pax_global_header00006660000000000000000000000064146273775160014534gustar00rootroot0000000000000052 comment=c38be0c0034cf573797395b56e53f4d24021c297 elastic-elasticsearch-ruby-c38be0c/000077500000000000000000000000001462737751600174405ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/.buildkite/000077500000000000000000000000001462737751600214725ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/.buildkite/Dockerfile000066400000000000000000000004401462737751600234620ustar00rootroot00000000000000ARG RUBY_VERSION=${RUBY_VERSION:-3.1} FROM ruby:$RUBY_VERSION ENV QUIET=true ENV CI=true # Install required tools RUN apt-get -q update && apt-get -y install zip curl WORKDIR /usr/src/app COPY . . RUN bundle install \ && bundle exec rake bundle:clean \ && rake bundle:install elastic-elasticsearch-ruby-c38be0c/.buildkite/certs/000077500000000000000000000000001462737751600226125ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/.buildkite/certs/ca.crt000077500000000000000000000022601462737751600237120ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDSjCCAjKgAwIBAgIVAJQLm8V2LcaCTHUcoIfO+KL63nG3MA0GCSqGSIb3DQEB CwUAMDQxMjAwBgNVBAMTKUVsYXN0aWMgQ2VydGlmaWNhdGUgVG9vbCBBdXRvZ2Vu ZXJhdGVkIENBMB4XDTIwMDIyNjA1NTA1N1oXDTIzMDIyNTA1NTA1N1owNDEyMDAG A1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5lcmF0ZWQgQ0Ew ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDYyajkPvGtUOE5M1OowQfB kWVrWjo1+LIxzgCeRHp0YztLtdVJ0sk2xoSrt2uZpxcPepdyOseLTjFJex1D2yCR AEniIqcFif4G72nDih2LlbhpUe/+/MTryj8ZTkFTzI+eMmbQi5FFMaH+kwufmdt/ 5/w8YazO18SxxJUlzMqzfNUrhM8vvvVdxgboU7PWhk28wZHCMHQovomHmzclhRpF N0FMktA98vHHeRjH19P7rNhifSd7hZzoH3H148HVAKoPgqnZ6vW2O2YfAWOP6ulq cyszr57p8fS9B2wSdlWW7nVHU1JuKcYD67CxbBS23BeGFgCj4tiNrmxO8S5Yf85v AgMBAAGjUzBRMB0GA1UdDgQWBBSWAlip9eoPmnG4p4OFZeOUBlAbNDAfBgNVHSME GDAWgBSWAlip9eoPmnG4p4OFZeOUBlAbNDAPBgNVHRMBAf8EBTADAQH/MA0GCSqG SIb3DQEBCwUAA4IBAQA19qqrMTWl7YyId+LR/QIHDrP4jfxmrEELrAL58q5Epc1k XxZLzOBSXoBfBrPdv+3XklWqXrZjKWfdkux0Xmjnl4qul+srrZDLJVZG3I7IrITh AmQUmL9MuPiMnAcxoGZp1xpijtW8Qmd2qnambbljWfkuVaa4hcVRfrAX6TciIQ21 bS5aeLGrPqR14h30YzDp0RMmTujEa1o6ExN0+RSTkE9m89Q6WdM69az8JW7YkWqm I+UCG3TcLd3TXmN1zNQkq4y2ObDK4Sxy/2p6yFPI1Fds5w/zLfBOvvPQY61vEqs8 SCCcQIe7f6NDpIRIBlty1C9IaEHj7edyHjF6rtYb -----END CERTIFICATE----- elastic-elasticsearch-ruby-c38be0c/.buildkite/certs/ca.key000066400000000000000000000032171462737751600237120ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEpgIBAAKCAQEA2Mmo5D7xrVDhOTNTqMEHwZFla1o6NfiyMc4AnkR6dGM7S7XV SdLJNsaEq7drmacXD3qXcjrHi04xSXsdQ9sgkQBJ4iKnBYn+Bu9pw4odi5W4aVHv /vzE68o/GU5BU8yPnjJm0IuRRTGh/pMLn5nbf+f8PGGsztfEscSVJczKs3zVK4TP L771XcYG6FOz1oZNvMGRwjB0KL6Jh5s3JYUaRTdBTJLQPfLxx3kYx9fT+6zYYn0n e4Wc6B9x9ePB1QCqD4Kp2er1tjtmHwFjj+rpanMrM6+e6fH0vQdsEnZVlu51R1NS binGA+uwsWwUttwXhhYAo+LYja5sTvEuWH/ObwIDAQABAoIBAQC8QDGnMnmPdWJ+ 13FYY3cmwel+FXXjFDk5QpgK15A2rUz6a8XxO1d7d1wR+U84uH4v9Na6XQyWjaoD EyPQnuJiyAtgkZLUHoY244PGR5NsePEQlBSCKmGeF5w/j1LvP/2e9EmP4wKdQYJY nLxFNcgEBCFnFbKIU5n8fKa/klybCrwlBokenyBro02tqH4LL7h1YMRRrl97fv1V e/y/0WcMN+KnMglfz6haimBRV2yamCCHHmBImC+wzOgT/quqlxPfI+a3ScHxuA65 3QyCavaqlPh+T3lXnN/Na4UWqFtzMmwgJX2x1zM5qiln46/JoDiXtagvV43L3rNs LhPRFeIRAoGBAPhEB7nNpEDNjIRUL6WpebWS9brKAVY7gYn7YQrKGhhCyftyaiBZ zYgxPaJdqYXf+DmkWlANGoYiwEs40QwkR/FZrvO4+Xh3n3dgtl59ZmieuoQvDsG+ RYIj+TfBaqhewhZNMMl7dxz7DeyQhyRCdsvl3VqJM0RuOsIrzrhCIEItAoGBAN+K lgWI7swDpOEaLmu+IWMkGImh1LswXoZqIgi/ywZ7htZjPzidOIeUsMi+lrYsKojG uU3sBxASsf9kYXDnuUuUbGT5M/N2ipXERt7klUAA/f5sg1IKlTrabaN/HGs/uNtf Efa8v/h2VyTurdPCJ17TNpbOMDwX1qGM62tyt2CLAoGBAIHCnP8iWq18QeuQTO8b a3/Z9hHRL22w4H4MI6aOB6GSlxuTq6CJD4IVqo9IwSg17fnCy2l3z9s4IqWuZqUf +XJOW8ELd2jdrT2qEOfGR1Z7UCVyqxXcq1vgDYx0zZh/HpalddB5dcJx/c8do2Ty UEE2PcHqYB9uNcvzNbLc7RtpAoGBALbuU0yePUTI6qGnajuTcQEPpeDjhRHWSFRZ ABcG1N8uMS66Mx9iUcNp462zgeP8iqY5caUZtMHreqxT+gWKK7F0+as7386pwElF QPXgO18QMMqHBIQb0vlBjJ1SRPBjSiSDTVEML1DljvTTOX7kEJHh6HdKrmBO5b54 cqMQUo53AoGBAPVWRPUXCqlBz914xKna0ZUh2aesRBg5BvOoq9ey9c52EIU5PXL5 0Isk8sWSsvhl3tjDPBH5WuL5piKgnCTqkVbEHmWu9s1T57Mw6NuxlPMLBWvyv4c6 tB9brOxv0ui3qGMuBsBoDKbkNnwXyOXLyFg7O+H4l016A3mLQzJM+NGV -----END RSA PRIVATE KEY----- elastic-elasticsearch-ruby-c38be0c/.buildkite/certs/testnode.crt000077500000000000000000000021731462737751600251570ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDIzCCAgugAwIBAgIVAMTO6uVx9dLox2t0lY4IcBKZXb5WMA0GCSqGSIb3DQEB CwUAMDQxMjAwBgNVBAMTKUVsYXN0aWMgQ2VydGlmaWNhdGUgVG9vbCBBdXRvZ2Vu ZXJhdGVkIENBMB4XDTIwMDIyNjA1NTA1OVoXDTIzMDIyNTA1NTA1OVowEzERMA8G A1UEAxMIaW5zdGFuY2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDK YLTOikVENiN/qYupOsoXd7VYYnryyfCC/dK4FC2aozkbqjFzBdvPGAasoc4yEiH5 CGeXMgJuOjk1maqetmdIsw00j4oHJviYsnGXzxxS5swhD7spcW4Uk4V4tAUzrbfT vW/2WW/yYCLe5phVb2chz0jL+WYb4bBmdfs/t6RtP9RqsplYAmVp3gZ6lt2YNtvE k9gz0TVk3DuO1TquIClfRYUjuywS6xDSvxJ8Jl91EfDWM8QU+9F+YAtiv74xl2U3 P0wwMqNvMxf9/3ak3lTQGsgO4L6cwbKpVLMMzxSVunZz/sgl19xy3qHHz1Qr2MjJ /2c2J7vahUL4NPRkjJClAgMBAAGjTTBLMB0GA1UdDgQWBBS2Wn8E2VZv4oenY+pR O8G3zfQXhzAfBgNVHSMEGDAWgBSWAlip9eoPmnG4p4OFZeOUBlAbNDAJBgNVHRME AjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAvwPvCiJJ6v9jYcyvYY8I3gP0oCwrylpRL n91UlgRSHUmuAObyOoVN5518gSV/bTU2SDrstcLkLFxHvnfpoGJoxsQEHuGxwDRI nhYNd62EKLerehNM/F9ILKmvTh8f6QPCzjUuExTXv+63l2Sr6dBS7FHsGs6UKUYO llM/y9wMZ1LCuZuBg9RhtgpFXRSgDM9Z7Begu0d/BPX9od/qAeZg9Arz4rwUiCN4 IJOMEBEPi5q1tgeS0Fb1Grpqd0Uz5tZKtEHNKzLG+zSMmkneL62Nk2HsmEFZKwzg u2pU42UaUE596G6o78s1aLn9ICcElPHTjiuZNSiyuu9IzvFDjGQw -----END CERTIFICATE----- elastic-elasticsearch-ruby-c38be0c/.buildkite/certs/testnode.key000077500000000000000000000032131462737751600251530ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAymC0zopFRDYjf6mLqTrKF3e1WGJ68snwgv3SuBQtmqM5G6ox cwXbzxgGrKHOMhIh+QhnlzICbjo5NZmqnrZnSLMNNI+KByb4mLJxl88cUubMIQ+7 KXFuFJOFeLQFM623071v9llv8mAi3uaYVW9nIc9Iy/lmG+GwZnX7P7ekbT/UarKZ WAJlad4GepbdmDbbxJPYM9E1ZNw7jtU6riApX0WFI7ssEusQ0r8SfCZfdRHw1jPE FPvRfmALYr++MZdlNz9MMDKjbzMX/f92pN5U0BrIDuC+nMGyqVSzDM8Ulbp2c/7I Jdfcct6hx89UK9jIyf9nNie72oVC+DT0ZIyQpQIDAQABAoIBADAh7f7NjgnaInlD ds8KB3SraPsbeQhzlPtiqRJU4j/MIFH/GYG03AGWQkget67a9y+GmzSvlTpoKKEh 6h2TXl9BDpv4o6ht0WRn1HJ5tM/Wyqf2WNpTew3zxCPgFPikkXsPrChYPzLTQJfp GkP/mfTFmxfAOlPZSp4j41zVLYs53eDkAegFPVfKSr1XNNJ3QODLPcIBfxBYsiC9 oU+jRW8xYuj31cEl5k5UqrChJ1rm3mt6cguqXKbISuoSvi13gXI6DccqhuLAU+Kr ib2XYrRP+pWocZo/pM9WUVoNGtFxfY88sAQtvG6gDKo2AURtFyq84Ow0h9mdixV/ gRIDPcECgYEA5nEqE3OKuG9WuUFGXvjtn4C0F6JjflYWh7AbX51S4F6LKrW6/XHL Rg4BtF+XReT7OQ6llsV8kZeUxsUckkgDLzSaA8lysNDV5KkhAWHfRqH//QKFbqZi JL9t3x63Qt81US8s2hQk3khPYTRM8ZB3xHiXvZYSGC/0x/DxfEO3QJECgYEA4NK5 sxtrat8sFz6SK9nWEKimPjDVzxJ0hxdX4tRq/JdOO5RncawVqt6TNP9gTuxfBvhW MhJYEsQj8iUoL1dxo9d1eP8HEANNV0iX5OBvJNmgBp+2OyRSyr+PA55+wAxYuAE7 QKaitOjW57fpArNRt2hQyiSzTuqUFRWTWJHCWNUCgYAEurPTXF6vdFGCUc2g61jt GhYYGhQSpq+lrz6Qksj9o9MVWE9zHh++21C7o+6V16I0RJGva3QoBMVf4vG4KtQt 5tV2WG8LI+4P2Ey+G4UajP6U8bVNVQrUmD0oBBhcvfn5JY+1Fg6/pRpD82/U0VMz 7AmpMWhDqNBMPiymkTk0kQKBgCuWb05cSI0ly4SOKwS5bRk5uVFhYnKNH255hh6C FGP4acB/WzbcqC7CjEPAJ0nl5d6SExQOHmk1AcsWjR3wlCWxxiK5PwNJwJrlhh1n reS1FKN0H36D4lFQpkeLWQOe4Sx7gKNeKzlr0w6Fx3Uwku0+Gju2tdTdAey8jB6l 08opAoGAEe1AuR/OFp2xw6V8TH9UHkkpGxy+OrXI6PX6tgk29PgB+uiMu4RwbjVz 1di1KKq2XecAilVbnyqY+edADxYGbSnci9x5wQRIebfMi3VXKtV8NQBv2as6qwtW JDcQUWotOHjpdvmfJWWkcBhbAKrgX8ukww00ZI/lC3/rmkGnBBg= -----END RSA PRIVATE KEY----- elastic-elasticsearch-ruby-c38be0c/.buildkite/certs/testnode_san.crt000066400000000000000000000023001462737751600260050ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDVjCCAj6gAwIBAgIULh42yRefYlRRl1hvt055LrUH0HwwDQYJKoZIhvcNAQEL BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l cmF0ZWQgQ0EwHhcNMjAwMjI4MDMzNzIwWhcNMjMwMjI3MDMzNzIwWjATMREwDwYD VQQDEwhpbnN0YW5jZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIUP t267NN21z+3ukajej8eojSXwP6zHxy7CUAp+sQ7bTq2XCKxkYX3CW9ThcS4cV9mL ayYdWEYnbEDGYPQDo7Wk3Ih5OEXTMZb/yNEx5D4S2lGMOS5bCDdYx6GvwCMG4jNx aMktosaxpprAJiHh2oLgQk0hQc/a9JfMo6kJKtuhjxsxjxLwcOHhuaUD7NS0Pjop CJkSYcrL+nnQPQjKe4uLhAbSyiX914h4QX0CJ0e4z1ccdDX2PFWTrwaIf//vQhCR wP2YKdfjR0JB4oDAlu85GsIs2cFLPysM5ufuNZO4fCr8uOwloKI8zZ2HhlIfBEcY Gcy4g9N/9epmxMXZlGcCAwEAAaOBgDB+MB0GA1UdDgQWBBRefYm8DHHDdkTPHhS1 HEUwTb2uiDAfBgNVHSMEGDAWgBSWAlip9eoPmnG4p4OFZeOUBlAbNDAxBgNVHREE KjAogglsb2NhbGhvc3SHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCA2VzMTAJBgNV HRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQC+pauqM2wJjQaHyHu+kIm59P4b/5Oj IH1cYCQfMB7Y2UMLxp0ew+f7o7zzE2DA52YYFDWy6J5DVWtSBPyeFGgX+RH+aA+9 Iv4cc9QpAs6aFjncorHrzNOrWLgCHIeRAxTR0CAkeP2dUZfDBuMpRyP6rAsYzyLH Rb3/BfYJSI5vxgt5Ke49Y/ljDKFJTyDmAVrHQ4JWrseYE1UZ2eDkBXeiRlYE/QtB YsrUSqdL6zvFZyUcilxDUUabNcA+GgeGZ2lAEA90F8vwi62QwRXo3Iv1Hz+6xc43 nFofDK9D8/qkrUD9iuhpx1974QwPhwWyjn9RZRpbZA4ngRL+szdRXR4N -----END CERTIFICATE----- elastic-elasticsearch-ruby-c38be0c/.buildkite/certs/testnode_san.key000066400000000000000000000032131462737751600260110ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAhQ+3brs03bXP7e6RqN6Px6iNJfA/rMfHLsJQCn6xDttOrZcI rGRhfcJb1OFxLhxX2YtrJh1YRidsQMZg9AOjtaTciHk4RdMxlv/I0THkPhLaUYw5 LlsIN1jHoa/AIwbiM3FoyS2ixrGmmsAmIeHaguBCTSFBz9r0l8yjqQkq26GPGzGP EvBw4eG5pQPs1LQ+OikImRJhysv6edA9CMp7i4uEBtLKJf3XiHhBfQInR7jPVxx0 NfY8VZOvBoh//+9CEJHA/Zgp1+NHQkHigMCW7zkawizZwUs/Kwzm5+41k7h8Kvy4 7CWgojzNnYeGUh8ERxgZzLiD03/16mbExdmUZwIDAQABAoIBAEwhjulLMVc9JEfV PP/qv0cUOBYh3LzF3T/yq4slq7Z9YgnOJYdFM8aZgqNNjc09KEJvE5JOLeiNu9Ff 768Nugg+2HM5MCo7SN9FYCfZLOcbMFCCM2FDcnMAV9A512vzD08xryuT8dNPZ6yZ DfhK2hQRrb2lrpr3gwSrcGRRu3THqvq7X1RIjpLV3teDMeP8rQPAlpj8fmP+kdVV 5y1ihiDIo87McihG9FMavJtBDXQkUEuVw6eIeir8L/zHHD/ZwhYjNHZGWbrB88sz CkJkfWh/FlA63tCVdJzkmnERALLTVy9mR0Sq6sUlnFhFNO2BRdWgYLrcp9McfTJC e8+WsSECgYEAuwQ3nAaFL0jqYu1AREyKT/f3WUenf2UsX7dwwV2/yFtQvkzW7ji4 uZLnfUnZBojtHf35dRo+hDgtvhZhgZNAuPPsbOl/EIMTcbChEqV/3CSTFlhLFM1d hfM9PoM+Bt/pyUNabjD1sWM0X7WeUhzcddshY3S4daBsNsLuOzweRRcCgYEAtiSS 4qiiGafYsY7gOHuAlOhs/00+1uWIFEHKgoHM9vzCxDN3LCmBdynHk8ZE2TAdhw+l 7xpu6LUxKQDfGmVZa9Epg0kQmVq9c54oQP57pJ3tR+68++insEkfnaZH8jblfq2s sSkFrY3pdS19edq60nuft64kswKRUUkamCXTXTECgYBdoSfiMpV9bekC7DsPtq5M iR3KEgi2zEViCmomNTRuL+GF1NyKWdWJ+xVwcYd5MRZdvKimyyPfeGzWTUg14i42 KtEEWgZmkukqMz8BIeCYq6sENeIpIQQgqv3PjU+Bi5r1S4Y7wsFPNRakkD4aaB6r 1rCppWcwZMeoxwEUoO2aswKBgBdDIIdWJi3EpAY5SyWrkEZ0UMdiZC4p7nE33ddB IJ5CtdU9BXFcc652ZYjX/58FaCABvZ2F8LhDu92SwOusGfmNIxIjWL1dO2jywA1c 8wmZKd7P/M7nbdMz45fMzs9+d1zwbWfK53C8+R4AC1BuwQF0zHc3BHTgVRLelUjt O8thAoGAdO2gHIqEsZzTgbvLbsh52eVbumjfNGnrnEv1fjb+o+/wAol8dymcmzbL bZCRzoyA0qwU9kdPFgX46H6so6o1tUM2GQtVFoT6kDnPv7EkLQK0C4cDh6OOHxDU NPvr/9fHhQd9EDWDvS1JnVMAdKDO6ELp3SoKGGmCXR2QplnqWAk= -----END RSA PRIVATE KEY----- elastic-elasticsearch-ruby-c38be0c/.buildkite/functions/000077500000000000000000000000001462737751600235025ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/.buildkite/functions/cleanup.sh000077500000000000000000000036401462737751600254730ustar00rootroot00000000000000#!/usr/bin/env bash # # Shared cleanup routines between different steps # # Please source .ci/functions/imports.sh as a whole not just this file # # Version 1.0.0 # - Initial version after refactor function cleanup_volume { if [[ "$(docker volume ls -q -f name=$1)" ]]; then echo -e "\033[34;1mINFO:\033[0m Removing volume $1\033[0m" (docker volume rm "$1") || true fi } function container_running { if [[ "$(docker ps -q -f name=$1)" ]]; then return 0; else return 1; fi } function cleanup_node { if container_running "$1"; then echo -e "\033[34;1mINFO:\033[0m Removing container $1\033[0m" (docker container rm --force --volumes "$1") || true fi if [[ -n "$1" ]]; then echo -e "\033[34;1mINFO:\033[0m Removing volume $1-${suffix}-data\033[0m" cleanup_volume "$1-${suffix}-data" fi } function cleanup_network { if [[ "$(docker network ls -q -f name=$1)" ]]; then echo -e "\033[34;1mINFO:\033[0m Removing network $1\033[0m" (docker network rm "$1") || true fi } function cleanup_trap { status=$? set +x if [[ "$DETACH" != "true" ]]; then echo -e "\033[34;1mINFO:\033[0m clean the network if not detached (start and exit)\033[0m" cleanup_all_in_network "$1" fi # status is 0 or SIGINT if [[ "$status" == "0" || "$status" == "130" ]]; then echo -e "\n\033[32;1mSUCCESS run-tests\033[0m" exit 0 else echo -e "\n\033[31;1mFAILURE during run-tests\033[0m" exit ${status} fi }; function cleanup_all_in_network { if [[ -z "$(docker network ls -q -f name="^$1\$")" ]]; then echo -e "\033[34;1mINFO:\033[0m $1 is already deleted\033[0m" return 0 fi containers=$(docker network inspect -f '{{ range $key, $value := .Containers }}{{ printf "%s\n" .Name}}{{ end }}' $1) while read -r container; do cleanup_node "$container" done <<< "$containers" cleanup_network $1 echo -e "\033[32;1mSUCCESS:\033[0m Cleaned up and exiting\033[0m" }; elastic-elasticsearch-ruby-c38be0c/.buildkite/functions/imports.sh000077500000000000000000000041501462737751600255360ustar00rootroot00000000000000#!/usr/bin/env bash # # Sets up all the common variables and imports relevant functions # # Version 1.0.1 # - Initial version after refactor # - Validate STACK_VERSION asap function require_stack_version() { if [[ -z $STACK_VERSION ]]; then echo -e "\033[31;1mERROR:\033[0m Required environment variable [STACK_VERSION] not set\033[0m" exit 1 fi } require_stack_version if [[ -z $es_node_name ]]; then # only set these once set -euo pipefail export TEST_SUITE=${TEST_SUITE-free} export RUNSCRIPTS=${RUNSCRIPTS-} export DETACH=${DETACH-false} export CLEANUP=${CLEANUP-false} export es_node_name=instance export elastic_password=changeme export elasticsearch_image=elasticsearch if [[ $STACK_VERSION == "8.0.0-SNAPSHOT" ]]; then export elasticsearch_scheme="https" if [[ $TEST_SUITE != "platinum" ]]; then export elasticsearch_scheme="http" fi export elasticsearch_url=${elasticsearch_scheme}://elastic:${elastic_password}@${es_node_name}:9200 else export elasticsearch_url=https://elastic:${elastic_password}@${es_node_name}:9200 if [[ $TEST_SUITE != "platinum" ]]; then export elasticsearch_url=http://${es_node_name}:9200 fi fi export external_elasticsearch_url=${elasticsearch_url/$es_node_name/localhost} export elasticsearch_container="${elasticsearch_image}:${STACK_VERSION}" export suffix=rest-test export moniker=$(echo "$elasticsearch_container" | tr -C "[:alnum:]" '-') export network_name=${moniker}${suffix} export ssl_cert="${script_path}/certs/testnode.crt" export ssl_key="${script_path}/certs/testnode.key" export ssl_ca="${script_path}/certs/ca.crt" fi export script_path=$(dirname $(realpath -s $0)) source $script_path/functions/cleanup.sh source $script_path/functions/wait-for-container.sh trap "cleanup_trap ${network_name}" EXIT if [[ "$CLEANUP" == "true" ]]; then cleanup_all_in_network $network_name exit 0 fi echo -e "\033[34;1mINFO:\033[0m Creating network $network_name if it does not exist already \033[0m" docker network inspect "$network_name" > /dev/null 2>&1 || docker network create "$network_name" elastic-elasticsearch-ruby-c38be0c/.buildkite/functions/wait-for-container.sh000077500000000000000000000024651462737751600275600ustar00rootroot00000000000000#!/usr/bin/env bash # # Exposes a routine scripts can call to wait for a container if that container set up a health command # # Please source .ci/functions/imports.sh as a whole not just this file # # Version 1.0.1 # - Initial version after refactor # - Make sure wait_for_contiainer is silent function wait_for_container { set +x until ! container_running "$1" || (container_running "$1" && [[ "$(docker inspect -f "{{.State.Health.Status}}" ${1})" != "starting" ]]); do echo "" docker inspect -f "{{range .State.Health.Log}}{{.Output}}{{end}}" ${1} echo -e "\033[34;1mINFO:\033[0m waiting for node $1 to be up\033[0m" sleep 2; done; # Always show logs if the container is running, this is very useful both on CI as well as while developing if container_running $1; then docker logs $1 fi if ! container_running $1 || [[ "$(docker inspect -f "{{.State.Health.Status}}" ${1})" != "healthy" ]]; then cleanup_all_in_network $2 echo echo -e "\033[31;1mERROR:\033[0m Failed to start $1 in detached mode beyond health checks\033[0m" echo -e "\033[31;1mERROR:\033[0m dumped the docker log before shutting the node down\033[0m" return 1 else echo echo -e "\033[32;1mSUCCESS:\033[0m Detached and healthy: ${1} on docker network: ${network_name}\033[0m" return 0 fi } elastic-elasticsearch-ruby-c38be0c/.buildkite/log-results.sh000077500000000000000000000021731462737751600243140ustar00rootroot00000000000000#!/usr/bin/env bash # # This script is intended to be run after the build in a Buildkite pipeline buildkite-agent annotate --style info "## :rspec: Tests summary :rspec: " buildkite-agent artifact download "elasticsearch-api/tmp/*" . # Test result summary: files="elasticsearch-api/tmp/*.html" for f in $files; do TEST_SUITE=`echo $f | grep -o "\(free\|platinum\)"` RUBY_VERSION=`echo $f | grep -Po "(\d+\.)+\d+"` EXAMPLES=`cat $f | grep -o "[0-9]\+ examples\?" | tail -1` FAILURES=`cat $f | grep -o "[0-9]\+ failures\?" | tail -1` PENDING=`cat $f | grep -o "[0-9]\+ pending" | tail -1` buildkite-agent annotate --append " :ruby: $RUBY_VERSION :test_tube: $TEST_SUITE :rspec: $EXAMPLES - :x: $FAILURES - :suspect: $PENDING " done files="elasticsearch-api/tmp/*.log" for f in $files; do FAILED_TESTS=`awk 'BEGIN { FS = " | "}; /\| failed \|/{ print $1 }' $f | uniq` if [[ -n "$FAILED_TESTS" ]]; then buildkite-agent annotate --append " #### Failures in $f " FAILURES_ARRAY=($(echo $FAILED_TESTS | tr ' ' "\n")) for f in "${FAILURES_ARRAY[@]}" do buildkite-agent annotate --append " - $f " done fi done elastic-elasticsearch-ruby-c38be0c/.buildkite/pipeline.yml000066400000000000000000000022721462737751600240250ustar00rootroot00000000000000steps: - label: ":elasticsearch: {{ matrix.stack_version }} :ruby: v{{ matrix.ruby }} :rspec: {{ matrix.suite }}" agents: provider: "gcp" env: RUBY_VERSION: "{{ matrix.ruby }}" TEST_SUITE: "{{ matrix.suite }}" STACK_VERSION: "{{ matrix.stack_version }}" matrix: setup: suite: - "free" - "platinum" ruby: - "3.3" - "3.2" - "3.1" - "3.0" stack_version: - 7.17-SNAPSHOT adjustments: # Skip platinum for all but Ruby 3.2: - with: suite: "platinum" ruby: "3.1" skip: true - with: suite: "platinum" ruby: "3.0" skip: true # Compatibility tests for 8.x: - with: stack_version: "8.14.0-SNAPSHOT" suite: "free" ruby: "3.3" - with: stack_version: "8.14.0-SNAPSHOT" suite: "platinum" ruby: "3.3" command: ./.buildkite/run-tests.sh artifact_paths: "elasticsearch-api/tmp/*" - wait: ~ continue_on_failure: true - label: "Log Results" command: ./.buildkite/log-results.sh elastic-elasticsearch-ruby-c38be0c/.buildkite/run-client.sh000066400000000000000000000045631462737751600241160ustar00rootroot00000000000000#!/usr/bin/env bash # # Once called Elasticsearch should be up and running # script_path=$(dirname $(realpath -s $0)) set -euo pipefail repo=`pwd` export RUBY_VERSION=${RUBY_VERSION:-3.1} echo "--- :ruby: Building Docker image" docker build \ --file $script_path/Dockerfile \ --tag elastic/elasticsearch-ruby \ --build-arg RUBY_VERSION=$RUBY_VERSION \ . mkdir -p elasticsearch-api/tmp repo=`pwd` echo "--- :ruby: Running $TEST_SUITE tests" if [[ $STACK_VERSION =~ (^8\.) ]]; then echo -e "\033[1m RUNNING COMPATIBILITY MODE \033[0m" docker run \ -u "$(id -u)" \ --network="${network_name}" \ --env "ELASTIC_CLIENT_APIVERSIONING=true" \ --env "ELASTIC_PASSWORD=${elastic_password}" \ --env "ELASTIC_USER=elastic" \ --env "QUIET=false" \ --env "STACK_VERSION=${STACK_VERSION}" \ --env "TEST_ES_SERVER=${elasticsearch_url}" \ --env "TEST_SUITE=${TEST_SUITE}" \ --volume $repo:/usr/src/app \ --volume=/tmp:/tmp \ --name elasticsearch-ruby \ --rm \ elastic/elasticsearch-ruby \ bundle exec rake elasticsearch:download_artifacts test:rest_api else if [[ $TEST_SUITE != "platinum" ]]; then docker run \ -u "$(id -u)" \ --network="${network_name}" \ --env "TEST_ES_SERVER=${elasticsearch_url}" \ --env "TEST_SUITE=${TEST_SUITE}" \ --env "STACK_VERSION=${STACK_VERSION}" \ --volume $repo:/usr/src/app \ --volume=/tmp:/tmp \ --name elasticsearch-ruby \ --rm \ elastic/elasticsearch-ruby \ bundle exec rake elasticsearch:download_artifacts test:rest_api else docker run \ -u "$(id -u)" \ --network="${network_name}" \ --env "TEST_ES_SERVER=${elasticsearch_url}" \ --env "ELASTIC_USER=elastic" \ --env "ELASTIC_PASSWORD=${elastic_password}" \ --env "TEST_SUITE=${TEST_SUITE}" \ --env "STACK_VERSION=${STACK_VERSION}" \ --volume $repo:/usr/src/app \ --name elasticsearch-ruby \ --rm \ elastic/elasticsearch-ruby \ bundle exec rake elasticsearch:download_artifacts test:security fi fi elastic-elasticsearch-ruby-c38be0c/.buildkite/run-elasticsearch.sh000077500000000000000000000131061462737751600254460ustar00rootroot00000000000000#!/usr/bin/env bash # # Launch one or more Elasticsearch nodes via the Docker image, # to form a cluster suitable for running the REST API tests. # # Export the STACK_VERSION variable, eg. '8.0.0-SNAPSHOT'. # Export the TEST_SUITE variable, eg. 'free' or 'platinum' defaults to 'free'. # Export the NUMBER_OF_NODES variable to start more than 1 node # Version 1.3.0 # - Initial version of the run-elasticsearch.sh script # - Deleting the volume should not dependent on the container still running # - Fixed `ES_JAVA_OPTS` config # - Moved to STACK_VERSION and TEST_VERSION # - Refactored into functions and imports # - Support NUMBER_OF_NODES # - Added 5 retries on docker pull for fixing transient network errors # - Added flags to make local CCR configurations work # - Added action.destructive_requires_name=false as the default will be true in v8 script_path=$(dirname $(realpath -s $0)) source $script_path/functions/imports.sh set -euo pipefail echo -e "\033[34;1mINFO:\033[0m Take down node if called twice with the same arguments (DETACH=true) or on seperate terminals \033[0m" cleanup_node $es_node_name master_node_name=${es_node_name} cluster_name=${moniker}${suffix} # Set vm.max_map_count kernel setting to 262144 sudo sysctl -w vm.max_map_count=262144 declare -a volumes environment=($(cat <<-END --env node.name=$es_node_name --env cluster.name=$cluster_name --env cluster.initial_master_nodes=$master_node_name --env discovery.seed_hosts=$master_node_name --env cluster.routing.allocation.disk.threshold_enabled=false --env bootstrap.memory_lock=true --env node.attr.testattr=test --env path.repo=/tmp --env repositories.url.allowed_urls=http://snapshot.test* --env action.destructive_requires_name=false --env ingest.geoip.downloader.enabled=false --env cluster.deprecation_indexing.enabled=false END )) if [[ $STACK_VERSION =~ (^8\.) ]]; then environment+=($(cat <<-EOF --env ELASTIC_PASSWORD=$elastic_password --env node.roles=data,data_cold,data_content,data_frozen,data_hot,data_warm,ingest,master,ml,remote_cluster_client,transform EOF )) else if [ "$TEST_SUITE" != "platinum" ]; then environment+=($(cat <<-EOF --env node.roles=data,data_cold,data_content,data_frozen,data_hot,data_warm,ingest,master,remote_cluster_client EOF )) fi fi if [[ "$TEST_SUITE" == "platinum" ]]; then environment+=($(cat <<-END --env ELASTIC_PASSWORD=$elastic_password --env xpack.license.self_generated.type=trial --env xpack.security.enabled=true --env xpack.security.http.ssl.enabled=true --env xpack.security.http.ssl.verification_mode=certificate --env xpack.security.http.ssl.key=certs/testnode.key --env xpack.security.http.ssl.certificate=certs/testnode.crt --env xpack.security.http.ssl.certificate_authorities=certs/ca.crt --env xpack.security.transport.ssl.enabled=true --env xpack.security.transport.ssl.verification_mode=certificate --env xpack.security.transport.ssl.key=certs/testnode.key --env xpack.security.transport.ssl.certificate=certs/testnode.crt --env xpack.security.transport.ssl.certificate_authorities=certs/ca.crt END )) volumes+=($(cat <<-END --volume $ssl_cert:/usr/share/elasticsearch/config/certs/testnode.crt --volume $ssl_key:/usr/share/elasticsearch/config/certs/testnode.key --volume $ssl_ca:/usr/share/elasticsearch/config/certs/ca.crt END )) else environment+=($(cat <<-END --env xpack.security.enabled=false END )) fi cert_validation_flags="" if [[ "$TEST_SUITE" == "platinum" ]]; then cert_validation_flags="--insecure --cacert /usr/share/elasticsearch/config/certs/ca.crt --resolve ${es_node_name}:443:127.0.0.1" fi # Pull the container, retry on failures up to 5 times with # short delays between each attempt. Fixes most transient network errors. docker_pull_attempts=0 until [ "$docker_pull_attempts" -ge 5 ] do docker pull docker.elastic.co/elasticsearch/"$elasticsearch_container" && break docker_pull_attempts=$((docker_pull_attempts+1)) echo "Failed to pull image, retrying in 10 seconds (retry $docker_pull_attempts/5)..." sleep 10 done NUMBER_OF_NODES=${NUMBER_OF_NODES-1} http_port=9200 for (( i=0; i<$NUMBER_OF_NODES; i++, http_port++ )); do node_name=${es_node_name}$i node_url=${external_elasticsearch_url/9200/${http_port}}$i if [[ "$i" == "0" ]]; then node_name=$es_node_name; fi environment+=($(cat <<-END --env node.name=$node_name END )) echo "$i: $http_port $node_url " volume_name=${node_name}-${suffix}-data volumes+=($(cat <<-END --volume $volume_name:/usr/share/elasticsearch/data${i} END )) # make sure we detach for all but the last node if DETACH=false (default) so all nodes are started local_detach="true" if [[ "$i" == "$((NUMBER_OF_NODES-1))" ]]; then local_detach=$DETACH; fi echo -e "\033[34;1mINFO:\033[0m Starting container $node_name \033[0m" set -x docker run \ -u "$(id -u)" \ --name "$node_name" \ --network "$network_name" \ --env "ES_JAVA_OPTS=-Xms1g -Xmx1g -da:org.elasticsearch.xpack.ccr.index.engine.FollowingEngineAssertions" \ "${environment[@]}" \ "${volumes[@]}" \ --publish "$http_port":9200 \ --ulimit nofile=65536:65536 \ --ulimit memlock=-1:-1 \ --detach="$local_detach" \ --health-cmd="curl $cert_validation_flags --fail $elasticsearch_url/_cluster/health || exit 1" \ --health-interval=2s \ --health-retries=20 \ --health-timeout=2s \ --rm \ docker.elastic.co/elasticsearch/"$elasticsearch_container"; set +x if wait_for_container "$es_node_name" "$network_name"; then echo -e "\033[32;1mSUCCESS:\033[0m Running on: $node_url\033[0m" fi done elastic-elasticsearch-ruby-c38be0c/.buildkite/run-tests.sh000077500000000000000000000006201462737751600237730ustar00rootroot00000000000000#!/usr/bin/env bash # # Script to run Elasticsearch container and Elasticsearch client integration tests on Buildkite # # Version 0.1 # script_path=$(dirname $(realpath -s $0)) source $script_path/functions/imports.sh set -euo pipefail echo "--- :elasticsearch: Starting Elasticsearch" DETACH=true bash $script_path/run-elasticsearch.sh echo "+++ :ruby: Run Client" bash $script_path/run-client.sh elastic-elasticsearch-ruby-c38be0c/.ci/000077500000000000000000000000001462737751600201115ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/.ci/.dockerignore000066400000000000000000000000271462737751600225640ustar00rootroot00000000000000tmp/* **/Gemfile.lock elastic-elasticsearch-ruby-c38be0c/.ci/Dockerfile000066400000000000000000000020261462737751600221030ustar00rootroot00000000000000ARG RUBY_TEST_VERSION=2.7 FROM ruby:${RUBY_TEST_VERSION} # Default UID/GID to 1000 # it can be overridden at build time ARG BUILDER_UID=1000 ARG BUILDER_GID=1000 ENV BUILDER_USER elastic ENV BUILDER_GROUP elastic ENV GEM_HOME="/usr/local/bundle" ENV PATH="$GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH" ENV QUIET=true ENV CI=true # Install required tools RUN apt-get -q update \ && apt-get -y install zip \ && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # Create user RUN groupadd --system -g ${BUILDER_GID} ${BUILDER_GROUP} \ && useradd --system --shell /bin/bash -u ${BUILDER_UID} -g ${BUILDER_GROUP} -d /var/lib/elastic -m elastic 1>/dev/null 2>/dev/null \ && mkdir -p /usr/src/app && touch /Gemfile.lock \ && chown -R ${BUILDER_USER}:${BUILDER_GROUP} /usr/src/app /Gemfile.lock COPY --chown=$BUILDER_USER:$BUILDER_GROUP . . WORKDIR /usr/src/app USER ${BUILDER_USER}:${BUILDER_GROUP} RUN gem update --quiet --silent RUN bundle install \ && bundle exec rake bundle:clean \ && rake bundle:install elastic-elasticsearch-ruby-c38be0c/.ci/certs/000077500000000000000000000000001462737751600212315ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/.ci/certs/ca.crt000077500000000000000000000022601462737751600223310ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDSjCCAjKgAwIBAgIVAJQLm8V2LcaCTHUcoIfO+KL63nG3MA0GCSqGSIb3DQEB CwUAMDQxMjAwBgNVBAMTKUVsYXN0aWMgQ2VydGlmaWNhdGUgVG9vbCBBdXRvZ2Vu ZXJhdGVkIENBMB4XDTIwMDIyNjA1NTA1N1oXDTIzMDIyNTA1NTA1N1owNDEyMDAG A1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5lcmF0ZWQgQ0Ew ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDYyajkPvGtUOE5M1OowQfB kWVrWjo1+LIxzgCeRHp0YztLtdVJ0sk2xoSrt2uZpxcPepdyOseLTjFJex1D2yCR AEniIqcFif4G72nDih2LlbhpUe/+/MTryj8ZTkFTzI+eMmbQi5FFMaH+kwufmdt/ 5/w8YazO18SxxJUlzMqzfNUrhM8vvvVdxgboU7PWhk28wZHCMHQovomHmzclhRpF N0FMktA98vHHeRjH19P7rNhifSd7hZzoH3H148HVAKoPgqnZ6vW2O2YfAWOP6ulq cyszr57p8fS9B2wSdlWW7nVHU1JuKcYD67CxbBS23BeGFgCj4tiNrmxO8S5Yf85v AgMBAAGjUzBRMB0GA1UdDgQWBBSWAlip9eoPmnG4p4OFZeOUBlAbNDAfBgNVHSME GDAWgBSWAlip9eoPmnG4p4OFZeOUBlAbNDAPBgNVHRMBAf8EBTADAQH/MA0GCSqG SIb3DQEBCwUAA4IBAQA19qqrMTWl7YyId+LR/QIHDrP4jfxmrEELrAL58q5Epc1k XxZLzOBSXoBfBrPdv+3XklWqXrZjKWfdkux0Xmjnl4qul+srrZDLJVZG3I7IrITh AmQUmL9MuPiMnAcxoGZp1xpijtW8Qmd2qnambbljWfkuVaa4hcVRfrAX6TciIQ21 bS5aeLGrPqR14h30YzDp0RMmTujEa1o6ExN0+RSTkE9m89Q6WdM69az8JW7YkWqm I+UCG3TcLd3TXmN1zNQkq4y2ObDK4Sxy/2p6yFPI1Fds5w/zLfBOvvPQY61vEqs8 SCCcQIe7f6NDpIRIBlty1C9IaEHj7edyHjF6rtYb -----END CERTIFICATE----- elastic-elasticsearch-ruby-c38be0c/.ci/certs/ca.key000066400000000000000000000032171462737751600223310ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEpgIBAAKCAQEA2Mmo5D7xrVDhOTNTqMEHwZFla1o6NfiyMc4AnkR6dGM7S7XV SdLJNsaEq7drmacXD3qXcjrHi04xSXsdQ9sgkQBJ4iKnBYn+Bu9pw4odi5W4aVHv /vzE68o/GU5BU8yPnjJm0IuRRTGh/pMLn5nbf+f8PGGsztfEscSVJczKs3zVK4TP L771XcYG6FOz1oZNvMGRwjB0KL6Jh5s3JYUaRTdBTJLQPfLxx3kYx9fT+6zYYn0n e4Wc6B9x9ePB1QCqD4Kp2er1tjtmHwFjj+rpanMrM6+e6fH0vQdsEnZVlu51R1NS binGA+uwsWwUttwXhhYAo+LYja5sTvEuWH/ObwIDAQABAoIBAQC8QDGnMnmPdWJ+ 13FYY3cmwel+FXXjFDk5QpgK15A2rUz6a8XxO1d7d1wR+U84uH4v9Na6XQyWjaoD EyPQnuJiyAtgkZLUHoY244PGR5NsePEQlBSCKmGeF5w/j1LvP/2e9EmP4wKdQYJY nLxFNcgEBCFnFbKIU5n8fKa/klybCrwlBokenyBro02tqH4LL7h1YMRRrl97fv1V e/y/0WcMN+KnMglfz6haimBRV2yamCCHHmBImC+wzOgT/quqlxPfI+a3ScHxuA65 3QyCavaqlPh+T3lXnN/Na4UWqFtzMmwgJX2x1zM5qiln46/JoDiXtagvV43L3rNs LhPRFeIRAoGBAPhEB7nNpEDNjIRUL6WpebWS9brKAVY7gYn7YQrKGhhCyftyaiBZ zYgxPaJdqYXf+DmkWlANGoYiwEs40QwkR/FZrvO4+Xh3n3dgtl59ZmieuoQvDsG+ RYIj+TfBaqhewhZNMMl7dxz7DeyQhyRCdsvl3VqJM0RuOsIrzrhCIEItAoGBAN+K lgWI7swDpOEaLmu+IWMkGImh1LswXoZqIgi/ywZ7htZjPzidOIeUsMi+lrYsKojG uU3sBxASsf9kYXDnuUuUbGT5M/N2ipXERt7klUAA/f5sg1IKlTrabaN/HGs/uNtf Efa8v/h2VyTurdPCJ17TNpbOMDwX1qGM62tyt2CLAoGBAIHCnP8iWq18QeuQTO8b a3/Z9hHRL22w4H4MI6aOB6GSlxuTq6CJD4IVqo9IwSg17fnCy2l3z9s4IqWuZqUf +XJOW8ELd2jdrT2qEOfGR1Z7UCVyqxXcq1vgDYx0zZh/HpalddB5dcJx/c8do2Ty UEE2PcHqYB9uNcvzNbLc7RtpAoGBALbuU0yePUTI6qGnajuTcQEPpeDjhRHWSFRZ ABcG1N8uMS66Mx9iUcNp462zgeP8iqY5caUZtMHreqxT+gWKK7F0+as7386pwElF QPXgO18QMMqHBIQb0vlBjJ1SRPBjSiSDTVEML1DljvTTOX7kEJHh6HdKrmBO5b54 cqMQUo53AoGBAPVWRPUXCqlBz914xKna0ZUh2aesRBg5BvOoq9ey9c52EIU5PXL5 0Isk8sWSsvhl3tjDPBH5WuL5piKgnCTqkVbEHmWu9s1T57Mw6NuxlPMLBWvyv4c6 tB9brOxv0ui3qGMuBsBoDKbkNnwXyOXLyFg7O+H4l016A3mLQzJM+NGV -----END RSA PRIVATE KEY----- elastic-elasticsearch-ruby-c38be0c/.ci/certs/testnode.crt000077500000000000000000000021731462737751600235760ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDIzCCAgugAwIBAgIVAMTO6uVx9dLox2t0lY4IcBKZXb5WMA0GCSqGSIb3DQEB CwUAMDQxMjAwBgNVBAMTKUVsYXN0aWMgQ2VydGlmaWNhdGUgVG9vbCBBdXRvZ2Vu ZXJhdGVkIENBMB4XDTIwMDIyNjA1NTA1OVoXDTIzMDIyNTA1NTA1OVowEzERMA8G A1UEAxMIaW5zdGFuY2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDK YLTOikVENiN/qYupOsoXd7VYYnryyfCC/dK4FC2aozkbqjFzBdvPGAasoc4yEiH5 CGeXMgJuOjk1maqetmdIsw00j4oHJviYsnGXzxxS5swhD7spcW4Uk4V4tAUzrbfT vW/2WW/yYCLe5phVb2chz0jL+WYb4bBmdfs/t6RtP9RqsplYAmVp3gZ6lt2YNtvE k9gz0TVk3DuO1TquIClfRYUjuywS6xDSvxJ8Jl91EfDWM8QU+9F+YAtiv74xl2U3 P0wwMqNvMxf9/3ak3lTQGsgO4L6cwbKpVLMMzxSVunZz/sgl19xy3qHHz1Qr2MjJ /2c2J7vahUL4NPRkjJClAgMBAAGjTTBLMB0GA1UdDgQWBBS2Wn8E2VZv4oenY+pR O8G3zfQXhzAfBgNVHSMEGDAWgBSWAlip9eoPmnG4p4OFZeOUBlAbNDAJBgNVHRME AjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAvwPvCiJJ6v9jYcyvYY8I3gP0oCwrylpRL n91UlgRSHUmuAObyOoVN5518gSV/bTU2SDrstcLkLFxHvnfpoGJoxsQEHuGxwDRI nhYNd62EKLerehNM/F9ILKmvTh8f6QPCzjUuExTXv+63l2Sr6dBS7FHsGs6UKUYO llM/y9wMZ1LCuZuBg9RhtgpFXRSgDM9Z7Begu0d/BPX9od/qAeZg9Arz4rwUiCN4 IJOMEBEPi5q1tgeS0Fb1Grpqd0Uz5tZKtEHNKzLG+zSMmkneL62Nk2HsmEFZKwzg u2pU42UaUE596G6o78s1aLn9ICcElPHTjiuZNSiyuu9IzvFDjGQw -----END CERTIFICATE----- elastic-elasticsearch-ruby-c38be0c/.ci/certs/testnode.key000077500000000000000000000032131462737751600235720ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAymC0zopFRDYjf6mLqTrKF3e1WGJ68snwgv3SuBQtmqM5G6ox cwXbzxgGrKHOMhIh+QhnlzICbjo5NZmqnrZnSLMNNI+KByb4mLJxl88cUubMIQ+7 KXFuFJOFeLQFM623071v9llv8mAi3uaYVW9nIc9Iy/lmG+GwZnX7P7ekbT/UarKZ WAJlad4GepbdmDbbxJPYM9E1ZNw7jtU6riApX0WFI7ssEusQ0r8SfCZfdRHw1jPE FPvRfmALYr++MZdlNz9MMDKjbzMX/f92pN5U0BrIDuC+nMGyqVSzDM8Ulbp2c/7I Jdfcct6hx89UK9jIyf9nNie72oVC+DT0ZIyQpQIDAQABAoIBADAh7f7NjgnaInlD ds8KB3SraPsbeQhzlPtiqRJU4j/MIFH/GYG03AGWQkget67a9y+GmzSvlTpoKKEh 6h2TXl9BDpv4o6ht0WRn1HJ5tM/Wyqf2WNpTew3zxCPgFPikkXsPrChYPzLTQJfp GkP/mfTFmxfAOlPZSp4j41zVLYs53eDkAegFPVfKSr1XNNJ3QODLPcIBfxBYsiC9 oU+jRW8xYuj31cEl5k5UqrChJ1rm3mt6cguqXKbISuoSvi13gXI6DccqhuLAU+Kr ib2XYrRP+pWocZo/pM9WUVoNGtFxfY88sAQtvG6gDKo2AURtFyq84Ow0h9mdixV/ gRIDPcECgYEA5nEqE3OKuG9WuUFGXvjtn4C0F6JjflYWh7AbX51S4F6LKrW6/XHL Rg4BtF+XReT7OQ6llsV8kZeUxsUckkgDLzSaA8lysNDV5KkhAWHfRqH//QKFbqZi JL9t3x63Qt81US8s2hQk3khPYTRM8ZB3xHiXvZYSGC/0x/DxfEO3QJECgYEA4NK5 sxtrat8sFz6SK9nWEKimPjDVzxJ0hxdX4tRq/JdOO5RncawVqt6TNP9gTuxfBvhW MhJYEsQj8iUoL1dxo9d1eP8HEANNV0iX5OBvJNmgBp+2OyRSyr+PA55+wAxYuAE7 QKaitOjW57fpArNRt2hQyiSzTuqUFRWTWJHCWNUCgYAEurPTXF6vdFGCUc2g61jt GhYYGhQSpq+lrz6Qksj9o9MVWE9zHh++21C7o+6V16I0RJGva3QoBMVf4vG4KtQt 5tV2WG8LI+4P2Ey+G4UajP6U8bVNVQrUmD0oBBhcvfn5JY+1Fg6/pRpD82/U0VMz 7AmpMWhDqNBMPiymkTk0kQKBgCuWb05cSI0ly4SOKwS5bRk5uVFhYnKNH255hh6C FGP4acB/WzbcqC7CjEPAJ0nl5d6SExQOHmk1AcsWjR3wlCWxxiK5PwNJwJrlhh1n reS1FKN0H36D4lFQpkeLWQOe4Sx7gKNeKzlr0w6Fx3Uwku0+Gju2tdTdAey8jB6l 08opAoGAEe1AuR/OFp2xw6V8TH9UHkkpGxy+OrXI6PX6tgk29PgB+uiMu4RwbjVz 1di1KKq2XecAilVbnyqY+edADxYGbSnci9x5wQRIebfMi3VXKtV8NQBv2as6qwtW JDcQUWotOHjpdvmfJWWkcBhbAKrgX8ukww00ZI/lC3/rmkGnBBg= -----END RSA PRIVATE KEY----- elastic-elasticsearch-ruby-c38be0c/.ci/certs/testnode_san.crt000066400000000000000000000023001462737751600244240ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDVjCCAj6gAwIBAgIULh42yRefYlRRl1hvt055LrUH0HwwDQYJKoZIhvcNAQEL BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l cmF0ZWQgQ0EwHhcNMjAwMjI4MDMzNzIwWhcNMjMwMjI3MDMzNzIwWjATMREwDwYD VQQDEwhpbnN0YW5jZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIUP t267NN21z+3ukajej8eojSXwP6zHxy7CUAp+sQ7bTq2XCKxkYX3CW9ThcS4cV9mL ayYdWEYnbEDGYPQDo7Wk3Ih5OEXTMZb/yNEx5D4S2lGMOS5bCDdYx6GvwCMG4jNx aMktosaxpprAJiHh2oLgQk0hQc/a9JfMo6kJKtuhjxsxjxLwcOHhuaUD7NS0Pjop CJkSYcrL+nnQPQjKe4uLhAbSyiX914h4QX0CJ0e4z1ccdDX2PFWTrwaIf//vQhCR wP2YKdfjR0JB4oDAlu85GsIs2cFLPysM5ufuNZO4fCr8uOwloKI8zZ2HhlIfBEcY Gcy4g9N/9epmxMXZlGcCAwEAAaOBgDB+MB0GA1UdDgQWBBRefYm8DHHDdkTPHhS1 HEUwTb2uiDAfBgNVHSMEGDAWgBSWAlip9eoPmnG4p4OFZeOUBlAbNDAxBgNVHREE KjAogglsb2NhbGhvc3SHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCA2VzMTAJBgNV HRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQC+pauqM2wJjQaHyHu+kIm59P4b/5Oj IH1cYCQfMB7Y2UMLxp0ew+f7o7zzE2DA52YYFDWy6J5DVWtSBPyeFGgX+RH+aA+9 Iv4cc9QpAs6aFjncorHrzNOrWLgCHIeRAxTR0CAkeP2dUZfDBuMpRyP6rAsYzyLH Rb3/BfYJSI5vxgt5Ke49Y/ljDKFJTyDmAVrHQ4JWrseYE1UZ2eDkBXeiRlYE/QtB YsrUSqdL6zvFZyUcilxDUUabNcA+GgeGZ2lAEA90F8vwi62QwRXo3Iv1Hz+6xc43 nFofDK9D8/qkrUD9iuhpx1974QwPhwWyjn9RZRpbZA4ngRL+szdRXR4N -----END CERTIFICATE----- elastic-elasticsearch-ruby-c38be0c/.ci/certs/testnode_san.key000066400000000000000000000032131462737751600244300ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAhQ+3brs03bXP7e6RqN6Px6iNJfA/rMfHLsJQCn6xDttOrZcI rGRhfcJb1OFxLhxX2YtrJh1YRidsQMZg9AOjtaTciHk4RdMxlv/I0THkPhLaUYw5 LlsIN1jHoa/AIwbiM3FoyS2ixrGmmsAmIeHaguBCTSFBz9r0l8yjqQkq26GPGzGP EvBw4eG5pQPs1LQ+OikImRJhysv6edA9CMp7i4uEBtLKJf3XiHhBfQInR7jPVxx0 NfY8VZOvBoh//+9CEJHA/Zgp1+NHQkHigMCW7zkawizZwUs/Kwzm5+41k7h8Kvy4 7CWgojzNnYeGUh8ERxgZzLiD03/16mbExdmUZwIDAQABAoIBAEwhjulLMVc9JEfV PP/qv0cUOBYh3LzF3T/yq4slq7Z9YgnOJYdFM8aZgqNNjc09KEJvE5JOLeiNu9Ff 768Nugg+2HM5MCo7SN9FYCfZLOcbMFCCM2FDcnMAV9A512vzD08xryuT8dNPZ6yZ DfhK2hQRrb2lrpr3gwSrcGRRu3THqvq7X1RIjpLV3teDMeP8rQPAlpj8fmP+kdVV 5y1ihiDIo87McihG9FMavJtBDXQkUEuVw6eIeir8L/zHHD/ZwhYjNHZGWbrB88sz CkJkfWh/FlA63tCVdJzkmnERALLTVy9mR0Sq6sUlnFhFNO2BRdWgYLrcp9McfTJC e8+WsSECgYEAuwQ3nAaFL0jqYu1AREyKT/f3WUenf2UsX7dwwV2/yFtQvkzW7ji4 uZLnfUnZBojtHf35dRo+hDgtvhZhgZNAuPPsbOl/EIMTcbChEqV/3CSTFlhLFM1d hfM9PoM+Bt/pyUNabjD1sWM0X7WeUhzcddshY3S4daBsNsLuOzweRRcCgYEAtiSS 4qiiGafYsY7gOHuAlOhs/00+1uWIFEHKgoHM9vzCxDN3LCmBdynHk8ZE2TAdhw+l 7xpu6LUxKQDfGmVZa9Epg0kQmVq9c54oQP57pJ3tR+68++insEkfnaZH8jblfq2s sSkFrY3pdS19edq60nuft64kswKRUUkamCXTXTECgYBdoSfiMpV9bekC7DsPtq5M iR3KEgi2zEViCmomNTRuL+GF1NyKWdWJ+xVwcYd5MRZdvKimyyPfeGzWTUg14i42 KtEEWgZmkukqMz8BIeCYq6sENeIpIQQgqv3PjU+Bi5r1S4Y7wsFPNRakkD4aaB6r 1rCppWcwZMeoxwEUoO2aswKBgBdDIIdWJi3EpAY5SyWrkEZ0UMdiZC4p7nE33ddB IJ5CtdU9BXFcc652ZYjX/58FaCABvZ2F8LhDu92SwOusGfmNIxIjWL1dO2jywA1c 8wmZKd7P/M7nbdMz45fMzs9+d1zwbWfK53C8+R4AC1BuwQF0zHc3BHTgVRLelUjt O8thAoGAdO2gHIqEsZzTgbvLbsh52eVbumjfNGnrnEv1fjb+o+/wAol8dymcmzbL bZCRzoyA0qwU9kdPFgX46H6so6o1tUM2GQtVFoT6kDnPv7EkLQK0C4cDh6OOHxDU NPvr/9fHhQd9EDWDvS1JnVMAdKDO6ELp3SoKGGmCXR2QplnqWAk= -----END RSA PRIVATE KEY----- elastic-elasticsearch-ruby-c38be0c/.ci/functions/000077500000000000000000000000001462737751600221215ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/.ci/functions/cleanup.sh000077500000000000000000000036401462737751600241120ustar00rootroot00000000000000#!/usr/bin/env bash # # Shared cleanup routines between different steps # # Please source .ci/functions/imports.sh as a whole not just this file # # Version 1.0.0 # - Initial version after refactor function cleanup_volume { if [[ "$(docker volume ls -q -f name=$1)" ]]; then echo -e "\033[34;1mINFO:\033[0m Removing volume $1\033[0m" (docker volume rm "$1") || true fi } function container_running { if [[ "$(docker ps -q -f name=$1)" ]]; then return 0; else return 1; fi } function cleanup_node { if container_running "$1"; then echo -e "\033[34;1mINFO:\033[0m Removing container $1\033[0m" (docker container rm --force --volumes "$1") || true fi if [[ -n "$1" ]]; then echo -e "\033[34;1mINFO:\033[0m Removing volume $1-${suffix}-data\033[0m" cleanup_volume "$1-${suffix}-data" fi } function cleanup_network { if [[ "$(docker network ls -q -f name=$1)" ]]; then echo -e "\033[34;1mINFO:\033[0m Removing network $1\033[0m" (docker network rm "$1") || true fi } function cleanup_trap { status=$? set +x if [[ "$DETACH" != "true" ]]; then echo -e "\033[34;1mINFO:\033[0m clean the network if not detached (start and exit)\033[0m" cleanup_all_in_network "$1" fi # status is 0 or SIGINT if [[ "$status" == "0" || "$status" == "130" ]]; then echo -e "\n\033[32;1mSUCCESS run-tests\033[0m" exit 0 else echo -e "\n\033[31;1mFAILURE during run-tests\033[0m" exit ${status} fi }; function cleanup_all_in_network { if [[ -z "$(docker network ls -q -f name="^$1\$")" ]]; then echo -e "\033[34;1mINFO:\033[0m $1 is already deleted\033[0m" return 0 fi containers=$(docker network inspect -f '{{ range $key, $value := .Containers }}{{ printf "%s\n" .Name}}{{ end }}' $1) while read -r container; do cleanup_node "$container" done <<< "$containers" cleanup_network $1 echo -e "\033[32;1mSUCCESS:\033[0m Cleaned up and exiting\033[0m" }; elastic-elasticsearch-ruby-c38be0c/.ci/functions/imports.sh000077500000000000000000000041501462737751600241550ustar00rootroot00000000000000#!/usr/bin/env bash # # Sets up all the common variables and imports relevant functions # # Version 1.0.1 # - Initial version after refactor # - Validate STACK_VERSION asap function require_stack_version() { if [[ -z $STACK_VERSION ]]; then echo -e "\033[31;1mERROR:\033[0m Required environment variable [STACK_VERSION] not set\033[0m" exit 1 fi } require_stack_version if [[ -z $es_node_name ]]; then # only set these once set -euo pipefail export TEST_SUITE=${TEST_SUITE-free} export RUNSCRIPTS=${RUNSCRIPTS-} export DETACH=${DETACH-false} export CLEANUP=${CLEANUP-false} export es_node_name=instance export elastic_password=changeme export elasticsearch_image=elasticsearch if [[ $STACK_VERSION == "8.0.0-SNAPSHOT" ]]; then export elasticsearch_scheme="https" if [[ $TEST_SUITE != "platinum" ]]; then export elasticsearch_scheme="http" fi export elasticsearch_url=${elasticsearch_scheme}://elastic:${elastic_password}@${es_node_name}:9200 else export elasticsearch_url=https://elastic:${elastic_password}@${es_node_name}:9200 if [[ $TEST_SUITE != "platinum" ]]; then export elasticsearch_url=http://${es_node_name}:9200 fi fi export external_elasticsearch_url=${elasticsearch_url/$es_node_name/localhost} export elasticsearch_container="${elasticsearch_image}:${STACK_VERSION}" export suffix=rest-test export moniker=$(echo "$elasticsearch_container" | tr -C "[:alnum:]" '-') export network_name=${moniker}${suffix} export ssl_cert="${script_path}/certs/testnode.crt" export ssl_key="${script_path}/certs/testnode.key" export ssl_ca="${script_path}/certs/ca.crt" fi export script_path=$(dirname $(realpath -s $0)) source $script_path/functions/cleanup.sh source $script_path/functions/wait-for-container.sh trap "cleanup_trap ${network_name}" EXIT if [[ "$CLEANUP" == "true" ]]; then cleanup_all_in_network $network_name exit 0 fi echo -e "\033[34;1mINFO:\033[0m Creating network $network_name if it does not exist already \033[0m" docker network inspect "$network_name" > /dev/null 2>&1 || docker network create "$network_name" elastic-elasticsearch-ruby-c38be0c/.ci/functions/wait-for-container.sh000077500000000000000000000024651462737751600261770ustar00rootroot00000000000000#!/usr/bin/env bash # # Exposes a routine scripts can call to wait for a container if that container set up a health command # # Please source .ci/functions/imports.sh as a whole not just this file # # Version 1.0.1 # - Initial version after refactor # - Make sure wait_for_contiainer is silent function wait_for_container { set +x until ! container_running "$1" || (container_running "$1" && [[ "$(docker inspect -f "{{.State.Health.Status}}" ${1})" != "starting" ]]); do echo "" docker inspect -f "{{range .State.Health.Log}}{{.Output}}{{end}}" ${1} echo -e "\033[34;1mINFO:\033[0m waiting for node $1 to be up\033[0m" sleep 2; done; # Always show logs if the container is running, this is very useful both on CI as well as while developing if container_running $1; then docker logs $1 fi if ! container_running $1 || [[ "$(docker inspect -f "{{.State.Health.Status}}" ${1})" != "healthy" ]]; then cleanup_all_in_network $2 echo echo -e "\033[31;1mERROR:\033[0m Failed to start $1 in detached mode beyond health checks\033[0m" echo -e "\033[31;1mERROR:\033[0m dumped the docker log before shutting the node down\033[0m" return 1 else echo echo -e "\033[32;1mSUCCESS:\033[0m Detached and healthy: ${1} on docker network: ${network_name}\033[0m" return 0 fi } elastic-elasticsearch-ruby-c38be0c/.ci/jobs/000077500000000000000000000000001462737751600210465ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/.ci/jobs/defaults.yml000066400000000000000000000031231462737751600233770ustar00rootroot00000000000000--- ##### GLOBAL METADATA - meta: cluster: clients-ci ##### JOB DEFAULTS - job: project-type: matrix logrotate: daysToKeep: 30 numToKeep: 100 properties: - github: url: https://github.com/elastic/elasticsearch-ruby/ - inject: properties-content: HOME=$JENKINS_HOME concurrent: true node: flyweight scm: - git: name: origin credentials-id: f6c7695a-671e-4f4f-a331-acdce44ff9ba reference-repo: /var/lib/jenkins/.git-references/elasticsearch-ruby.git branches: - ${branch_specifier} url: git@github.com:elastic/elasticsearch-ruby.git wipe-workspace: 'True' triggers: - github - timed: '@daily' axes: - axis: type: slave name: label values: - linux - axis: type: yaml filename: .ci/test-matrix.yml name: STACK_VERSION - axis: type: yaml filename: .ci/test-matrix.yml name: RUBY_TEST_VERSION - axis: type: yaml filename: .ci/test-matrix.yml name: TEST_SUITE yaml-strategy: exclude-key: exclude filename: .ci/test-matrix.yml wrappers: - ansicolor - timeout: type: absolute timeout: 120 fail: true - timestamps - workspace-cleanup builders: - shell: |- #!/usr/local/bin/runbld .ci/run-tests publishers: - email: recipients: build-lang-clients@elastic.co - junit: results: "*-junit.xml" allow-empty-results: true elastic-elasticsearch-ruby-c38be0c/.ci/jobs/elastic+elasticsearch-ruby+6.x.yml000066400000000000000000000006031462737751600274100ustar00rootroot00000000000000--- - job: name: elastic+elasticsearch-ruby+6.x display-name: 'elastic / elasticsearch-ruby # 6.x' description: Testing the elasticsearch-ruby 6.x branch. parameters: - string: name: branch_specifier default: refs/heads/6.x description: the Git branch specifier to build (<branchName>, <tagName>, <commitId>, etc.) elastic-elasticsearch-ruby-c38be0c/.ci/jobs/elastic+elasticsearch-ruby+7.16.yml000066400000000000000000000006071462737751600273740ustar00rootroot00000000000000--- - job: name: elastic+elasticsearch-ruby+7.16 display-name: 'elastic / elasticsearch-ruby # 7.16' description: Testing the elasticsearch-ruby 7.16 branch. parameters: - string: name: branch_specifier default: refs/heads/7.16 description: the Git branch specifier to build (<branchName>, <tagName>, <commitId>, etc.) elastic-elasticsearch-ruby-c38be0c/.ci/jobs/elastic+elasticsearch-ruby+main.yml000066400000000000000000000006071462737751600277250ustar00rootroot00000000000000--- - job: name: elastic+elasticsearch-ruby+main display-name: 'elastic / elasticsearch-ruby # main' description: Testing the elasticsearch-ruby main branch. parameters: - string: name: branch_specifier default: refs/heads/main description: the Git branch specifier to build (<branchName>, <tagName>, <commitId>, etc.) elastic-elasticsearch-ruby-c38be0c/.ci/jobs/elastic+elasticsearch-ruby+pull-request.yml000066400000000000000000000010501462737751600314340ustar00rootroot00000000000000--- - job: name: elastic+elasticsearch-ruby+pull-request display-name: 'elastic / elasticsearch-ruby # pull-request' description: Testing of elasticsearch-ruby pull requests. scm: - git: branches: - ${ghprbActualCommit} refspec: +refs/pull/*:refs/remotes/origin/pr/* triggers: - github-pull-request: org-list: - elastic allow-whitelist-orgs-as-admins: true github-hooks: true status-context: clients-ci cancel-builds-on-update: true publishers: [] elastic-elasticsearch-ruby-c38be0c/.ci/make.sh000077500000000000000000000120461462737751600213700ustar00rootroot00000000000000#!/usr/bin/env bash # ------------------------------------------------------- # # # Build entry script for elasticsearch-ruby # # Must be called: ./.ci/make.sh # # Version: 1.1.0 # # Targets: # --------------------------- # assemble : build client artefacts with version # bump : bump client internals to version # codegen : generate endpoints # docsgen : generate documentation # examplegen : generate the doc examples # clean : clean workspace # # ------------------------------------------------------- # # ------------------------------------------------------- # # Bootstrap # ------------------------------------------------------- # script_path=$(dirname "$(realpath -s "$0")") repo=$(realpath "$script_path/../") # shellcheck disable=SC1090 CMD=$1 TASK=$1 TASK_ARGS=() VERSION=$2 STACK_VERSION=$VERSION set -euo pipefail product="elastic/elasticsearch-ruby" output_folder=".ci/output" codegen_folder=".ci/output" OUTPUT_DIR="$repo/${output_folder}" REPO_BINDING="${OUTPUT_DIR}:/sln/${output_folder}" RUBY_TEST_VERSION=${RUBY_TEST_VERSION-2.7} WORKFLOW=${WORKFLOW-staging} mkdir -p "$OUTPUT_DIR" echo -e "\033[34;1mINFO:\033[0m PRODUCT ${product}\033[0m" echo -e "\033[34;1mINFO:\033[0m VERSION ${STACK_VERSION}\033[0m" echo -e "\033[34;1mINFO:\033[0m OUTPUT_DIR ${OUTPUT_DIR}\033[0m" echo -e "\033[34;1mINFO:\033[0m RUBY_TEST_VERSION ${RUBY_TEST_VERSION}\033[0m" case $CMD in clean) echo -e "\033[36;1mTARGET: clean workspace $output_folder\033[0m" rm -rf "$output_folder" echo -e "\033[32;1mdone.\033[0m" exit 0 ;; assemble) if [ -v $VERSION ]; then echo -e "\033[31;1mTARGET: assemble -> missing version parameter\033[0m" exit 1 fi echo -e "\033[36;1mTARGET: assemble artefact $VERSION\033[0m" TASK=assemble TASK_ARGS=("$VERSION" "$output_folder") ;; codegen) if [ -v $VERSION ]; then echo -e "\033[31;1mTARGET: codegen -> missing version parameter\033[0m" exit 1 fi echo -e "\033[36;1mTARGET: codegen API v$VERSION\033[0m" TASK=codegen # VERSION is BRANCH here for now TASK_ARGS=("$VERSION" "$codegen_folder") ;; docsgen) if [ -v $VERSION ]; then echo -e "\033[31;1mTARGET: docsgen -> missing version parameter\033[0m" exit 1 fi echo -e "\033[36;1mTARGET: generate docs for $VERSION\033[0m" TASK=codegen # VERSION is BRANCH here for now TASK_ARGS=("$VERSION" "$codegen_folder") ;; examplesgen) echo -e "\033[36;1mTARGET: generate examples\033[0m" TASK=codegen # VERSION is BRANCH here for now TASK_ARGS=("$VERSION" "$codegen_folder") ;; bump) if [ -v $VERSION ]; then echo -e "\033[31;1mTARGET: bump -> missing version parameter\033[0m" exit 1 fi echo -e "\033[36;1mTARGET: bump to version $VERSION\033[0m" TASK=bump # VERSION is BRANCH here for now TASK_ARGS=("$VERSION") ;; *) echo -e "\nUsage:" echo -e "\t Clean workspace:" echo -e "\t $0 clean\n" echo -e "\t Build gems:" echo -e "\t $0 assemble [version_qualifier]\n" echo -e "\t Bump version:" echo -e "\t $0 bump [version_qualifier]\n" exit 1 esac echo -e "\033[1m>>>>> Build [elastic/elasticsearch-ruby container] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\033[0m" # ------------------------------------------------------- # # Build Container # ------------------------------------------------------- # echo -e "\033[34;1mINFO: building $product container\033[0m" docker build --build-arg BUILDER_UID="$(id -u)" --file .ci/Dockerfile --tag ${product} . # ------------------------------------------------------- # # Run the Container # ------------------------------------------------------- # echo -e "\033[34;1mINFO: running $product container\033[0m" mkdir -p "$OUTPUT_DIR" # Convert ARGS to comma separated string for Rake: args_string="${TASK_ARGS[*]}" args_string="${args_string// /,}" docker run \ -u "$(id -u)" \ --env "RUBY_TEST_VERSION=${RUBY_TEST_VERSION}" \ --env "WORKFLOW=${WORKFLOW}" \ --name test-runner \ --volume "${REPO_BINDING}" \ --volume "${repo}:/usr/src/app" \ --rm \ "${product}" \ bundle exec rake unified_release:${TASK}["${args_string}"] # ------------------------------------------------------- # # Post Command tasks & checks # ------------------------------------------------------- # if [[ "$CMD" == "assemble" ]]; then if compgen -G ".ci/output" > /dev/null; then echo -e "\033[32;1mTARGET: successfully assembled client v$VERSION\033[0m" else echo -e "\033[31;1mTARGET: assemble failed, empty workspace!\033[0m" exit 1 fi fi if [[ "$CMD" == "codegen" ]]; then echo "TODO" fi if [[ "$CMD" == "docsgen" ]]; then echo "TODO" fi if [[ "$CMD" == "examplesgen" ]]; then echo "TODO" fi elastic-elasticsearch-ruby-c38be0c/.ci/run-elasticsearch.sh000077500000000000000000000127561462737751600240770ustar00rootroot00000000000000#!/usr/bin/env bash # # Launch one or more Elasticsearch nodes via the Docker image, # to form a cluster suitable for running the REST API tests. # # Export the STACK_VERSION variable, eg. '8.0.0-SNAPSHOT'. # Export the TEST_SUITE variable, eg. 'free' or 'platinum' defaults to 'free'. # Export the NUMBER_OF_NODES variable to start more than 1 node # Version 1.3.0 # - Initial version of the run-elasticsearch.sh script # - Deleting the volume should not dependent on the container still running # - Fixed `ES_JAVA_OPTS` config # - Moved to STACK_VERSION and TEST_VERSION # - Refactored into functions and imports # - Support NUMBER_OF_NODES # - Added 5 retries on docker pull for fixing transient network errors # - Added flags to make local CCR configurations work # - Added action.destructive_requires_name=false as the default will be true in v8 script_path=$(dirname $(realpath -s $0)) source $script_path/functions/imports.sh set -euo pipefail echo -e "\033[34;1mINFO:\033[0m Take down node if called twice with the same arguments (DETACH=true) or on seperate terminals \033[0m" cleanup_node $es_node_name master_node_name=${es_node_name} cluster_name=${moniker}${suffix} declare -a volumes environment=($(cat <<-END --env node.name=$es_node_name --env cluster.name=$cluster_name --env cluster.initial_master_nodes=$master_node_name --env discovery.seed_hosts=$master_node_name --env cluster.routing.allocation.disk.threshold_enabled=false --env bootstrap.memory_lock=true --env node.attr.testattr=test --env path.repo=/tmp --env repositories.url.allowed_urls=http://snapshot.test* --env action.destructive_requires_name=false --env ingest.geoip.downloader.enabled=false --env cluster.deprecation_indexing.enabled=false END )) if [[ $STACK_VERSION =~ (^8\.) ]]; then environment+=($(cat <<-EOF --env ELASTIC_PASSWORD=$elastic_password --env node.roles=data,data_cold,data_content,data_frozen,data_hot,data_warm,ingest,master,ml,remote_cluster_client,transform EOF )) else if [ "$TEST_SUITE" != "platinum" ]; then environment+=($(cat <<-EOF --env node.roles=data,data_cold,data_content,data_frozen,data_hot,data_warm,ingest,master,remote_cluster_client EOF )) fi fi if [[ "$TEST_SUITE" == "platinum" ]]; then environment+=($(cat <<-END --env ELASTIC_PASSWORD=$elastic_password --env xpack.license.self_generated.type=trial --env xpack.security.enabled=true --env xpack.security.http.ssl.enabled=true --env xpack.security.http.ssl.verification_mode=certificate --env xpack.security.http.ssl.key=certs/testnode.key --env xpack.security.http.ssl.certificate=certs/testnode.crt --env xpack.security.http.ssl.certificate_authorities=certs/ca.crt --env xpack.security.transport.ssl.enabled=true --env xpack.security.transport.ssl.verification_mode=certificate --env xpack.security.transport.ssl.key=certs/testnode.key --env xpack.security.transport.ssl.certificate=certs/testnode.crt --env xpack.security.transport.ssl.certificate_authorities=certs/ca.crt END )) volumes+=($(cat <<-END --volume $ssl_cert:/usr/share/elasticsearch/config/certs/testnode.crt --volume $ssl_key:/usr/share/elasticsearch/config/certs/testnode.key --volume $ssl_ca:/usr/share/elasticsearch/config/certs/ca.crt END )) else environment+=($(cat <<-END --env xpack.security.enabled=false END )) fi cert_validation_flags="" if [[ "$TEST_SUITE" == "platinum" ]]; then cert_validation_flags="--insecure --cacert /usr/share/elasticsearch/config/certs/ca.crt --resolve ${es_node_name}:443:127.0.0.1" fi # Pull the container, retry on failures up to 5 times with # short delays between each attempt. Fixes most transient network errors. docker_pull_attempts=0 until [ "$docker_pull_attempts" -ge 5 ] do docker pull docker.elastic.co/elasticsearch/"$elasticsearch_container" && break docker_pull_attempts=$((docker_pull_attempts+1)) echo "Failed to pull image, retrying in 10 seconds (retry $docker_pull_attempts/5)..." sleep 10 done NUMBER_OF_NODES=${NUMBER_OF_NODES-1} http_port=9200 for (( i=0; i<$NUMBER_OF_NODES; i++, http_port++ )); do node_name=${es_node_name}$i node_url=${external_elasticsearch_url/9200/${http_port}}$i if [[ "$i" == "0" ]]; then node_name=$es_node_name; fi environment+=($(cat <<-END --env node.name=$node_name END )) echo "$i: $http_port $node_url " volume_name=${node_name}-${suffix}-data volumes+=($(cat <<-END --volume $volume_name:/usr/share/elasticsearch/data${i} END )) # make sure we detach for all but the last node if DETACH=false (default) so all nodes are started local_detach="true" if [[ "$i" == "$((NUMBER_OF_NODES-1))" ]]; then local_detach=$DETACH; fi echo -e "\033[34;1mINFO:\033[0m Starting container $node_name \033[0m" set -x docker run \ -u "$(id -u)" \ --name "$node_name" \ --network "$network_name" \ --env "ES_JAVA_OPTS=-Xms1g -Xmx1g -da:org.elasticsearch.xpack.ccr.index.engine.FollowingEngineAssertions" \ "${environment[@]}" \ "${volumes[@]}" \ --publish "$http_port":9200 \ --ulimit nofile=65536:65536 \ --ulimit memlock=-1:-1 \ --detach="$local_detach" \ --health-cmd="curl $cert_validation_flags --fail $elasticsearch_url/_cluster/health || exit 1" \ --health-interval=2s \ --health-retries=20 \ --health-timeout=2s \ --rm \ docker.elastic.co/elasticsearch/"$elasticsearch_container"; set +x if wait_for_container "$es_node_name" "$network_name"; then echo -e "\033[32;1mSUCCESS:\033[0m Running on: $node_url\033[0m" fi done elastic-elasticsearch-ruby-c38be0c/.ci/run-repository.sh000077500000000000000000000065251462737751600235010ustar00rootroot00000000000000#!/usr/bin/env bash # # Called by entry point `run-test` use this script to add your repository specific test commands # # Once called Elasticsearch is up and running # # Its recommended to call `imports.sh` as defined here so that you get access to all variables defined there # # Any parameters that test-matrix.yml defines should be declared here with appropiate defaults script_path=$(dirname $(realpath -s $0)) source $script_path/functions/imports.sh set -euo pipefail echo -e "\033[34;1mINFO:\033[0m VERSION: ${STACK_VERSION}\033[0m" echo -e "\033[34;1mINFO:\033[0m TEST_SUITE: ${TEST_SUITE}\033[0m" echo -e "\033[34;1mINFO:\033[0m RUNSCRIPTS: ${RUNSCRIPTS}\033[0m" echo -e "\033[34;1mINFO:\033[0m URL: ${elasticsearch_url}\033[0m" echo -e "\033[34;1mINFO:\033[0m CONTAINER: ${elasticsearch_container}\033[0m" # # Ruby client setup: # export RUBY_TEST_VERSION=${RUBY_TEST_VERSION:-2.7.0} export STACK_VERSION=${STACK_VERSION:-8.0.0-SNAPSHOT} export SINGLE_TEST=${SINGLE_TEST:-} echo -e "\033[1m>>>>> Build [elastic/elasticsearch-ruby container] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\033[0m" # create client image docker build \ --file .ci/Dockerfile \ --tag elastic/elasticsearch-ruby \ --build-arg RUBY_TEST_VERSION=${RUBY_TEST_VERSION} \ . echo -e "\033[1m>>>>> Run [elastic/elasticsearch-ruby container] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\033[0m" repo=`pwd` # run the client tests if [[ $STACK_VERSION =~ (^8\.) ]]; then echo -e "\033[1m RUNNING COMPATIBILITY MODE \033[0m" docker run \ -u "$(id -u)" \ --network="${network_name}" \ --env "ELASTIC_CLIENT_APIVERSIONING=true" \ --env "ELASTIC_PASSWORD=${elastic_password}" \ --env "ELASTIC_USER=elastic" \ --env "QUIET=false" \ --env "STACK_VERSION=${STACK_VERSION}" \ --env "TEST_ES_SERVER=${elasticsearch_url}" \ --env "TEST_SUITE=${TEST_SUITE}" \ --volume $repo:/usr/src/app \ --volume=/tmp:/tmp \ --name elasticsearch-ruby \ --rm \ elastic/elasticsearch-ruby \ bundle exec rake elasticsearch:download_artifacts test:rest_api else if [[ $TEST_SUITE != "platinum" ]]; then docker run \ -u "$(id -u)" \ --network="${network_name}" \ --env "TEST_ES_SERVER=${elasticsearch_url}" \ --env "TEST_SUITE=${TEST_SUITE}" \ --env "STACK_VERSION=${STACK_VERSION}" \ --volume $repo:/usr/src/app \ --volume=/tmp:/tmp \ --name elasticsearch-ruby \ --rm \ elastic/elasticsearch-ruby \ bundle exec rake elasticsearch:download_artifacts test:rest_api else docker run \ -u "$(id -u)" \ --network="${network_name}" \ --env "TEST_ES_SERVER=${elasticsearch_url}" \ --env "ELASTIC_USER=elastic" \ --env "ELASTIC_PASSWORD=${elastic_password}" \ --env "TEST_SUITE=${TEST_SUITE}" \ --env "SINGLE_TEST=${SINGLE_TEST}" \ --env "STACK_VERSION=${STACK_VERSION}" \ --volume $repo:/usr/src/app \ --name elasticsearch-ruby \ --rm \ elastic/elasticsearch-ruby \ bundle exec rake elasticsearch:download_artifacts test:security fi fi elastic-elasticsearch-ruby-c38be0c/.ci/run-tests000077500000000000000000000015001462737751600217770ustar00rootroot00000000000000#!/usr/bin/env bash # # Version 1.1 # - Moved to .ci folder and seperated out `run-repository.sh` # - Add `$RUNSCRIPTS` env var for running Elasticsearch dependent products script_path=$(dirname $(realpath -s $0)) source $script_path/functions/imports.sh set -euo pipefail echo -e "\033[1m>>>>> Start [$STACK_VERSION container] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\033[0m" DETACH=true bash .ci/run-elasticsearch.sh if [[ -n "$RUNSCRIPTS" ]]; then for RUNSCRIPT in ${RUNSCRIPTS//,/ } ; do echo -e "\033[1m>>>>> Running run-$RUNSCRIPT.sh >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\033[0m" CONTAINER_NAME=${RUNSCRIPT} \ DETACH=true \ bash .ci/run-${RUNSCRIPT}.sh done fi echo -e "\033[1m>>>>> Repository specific tests >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\033[0m" bash .ci/run-repository.sh elastic-elasticsearch-ruby-c38be0c/.ci/test-matrix.yml000066400000000000000000000004741462737751600231220ustar00rootroot00000000000000--- STACK_VERSION: - 7.17-SNAPSHOT - 8.5-SNAPSHOT RUBY_TEST_VERSION: - 3.1 - 3.0 - 2.7 - 2.6 TEST_SUITE: - free - platinum exclude: - STACK_VERSION: 8.5-SNAPSHOT RUBY_TEST_VERSION: 3.0 - STACK_VERSION: 8.5-SNAPSHOT RUBY_TEST_VERSION: 2.7 - STACK_VERSION: 8.5-SNAPSHOT RUBY_TEST_VERSION: 2.6 elastic-elasticsearch-ruby-c38be0c/.ci/views/000077500000000000000000000000001462737751600212465ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/.ci/views/views.yml000066400000000000000000000006131462737751600231260ustar00rootroot00000000000000- view: name: 'Main' regex: '^.*$' view-type: list - view: name: 'Benchmark' regex: '^.*benchmark.*$' view-type: list - view: name: 'Ruby' regex: '^.*elasticsearch-ruby.*$' view-type: list - view: name: 'Javascript' regex: '^.*elasticsearch-js.*$' view-type: list - view: name: 'Python' regex: '^.*elasticsearch-py.*$' view-type: list elastic-elasticsearch-ruby-c38be0c/.github/000077500000000000000000000000001462737751600210005ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/.github/check_license_headers.rb000066400000000000000000000022351462737751600256010ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. LICENSE = File.read('./.github/license-header.txt') files = `git ls-files | grep -E '\.rb|Rakefile|\.rake|\.erb|Gemfile|gemspec'`.split("\n") errors = [] files.each do |file| unless File.read(file).include?(LICENSE) errors << file puts "#{file} doesn't contain the correct license header" end end if errors.empty? puts 'All checked files have the correct license header' else exit 1 end elastic-elasticsearch-ruby-c38be0c/.github/license-header.txt000066400000000000000000000014071462737751600244130ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. elastic-elasticsearch-ruby-c38be0c/.github/workflows/000077500000000000000000000000001462737751600230355ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/.github/workflows/7.17-8.x.yml000066400000000000000000000020271462737751600245700ustar00rootroot00000000000000name: 7.x with 8.x on: push: branches: - 7.17 pull_request: branches: - 7.17 jobs: test-ruby: env: TEST_ES_SERVER: http://localhost:9250 PORT: 9250 strategy: fail-fast: false matrix: ruby: [ '3.2' ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Increase system limits run: | sudo swapoff -a sudo sysctl -w vm.swappiness=1 sudo sysctl -w fs.file-max=262144 sudo sysctl -w vm.max_map_count=262144 - uses: elastic/elastic-github-actions/elasticsearch@master with: stack-version: 8.14.0-SNAPSHOT security-enabled: false - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - name: Build and test with Rake run: | sudo apt-get update sudo apt-get install libcurl4-openssl-dev ruby -v rake bundle:clean rake bundle:install - name: elasticsearch run: cd elasticsearch && bundle exec rake test:all elastic-elasticsearch-ruby-c38be0c/.github/workflows/7.17.yml000066400000000000000000000030331462737751600241530ustar00rootroot00000000000000name: 7.17 on: push: branches: - 7.17 pull_request: branches: - 7.17 jobs: test-ruby: env: TEST_ES_SERVER: http://localhost:9250 PORT: 9250 strategy: fail-fast: false matrix: ruby: [ '3.0', '3.1', '3.2', '3.3', 'jruby-9.3', 'jruby-9.4' ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Increase system limits run: | sudo swapoff -a sudo sysctl -w vm.swappiness=1 sudo sysctl -w fs.file-max=262144 sudo sysctl -w vm.max_map_count=262144 - uses: elastic/elastic-github-actions/elasticsearch@master with: stack-version: 7.17-SNAPSHOT - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - name: Build and test with Rake run: | sudo apt-get update sudo apt-get install libcurl4-openssl-dev ruby -v rake bundle:clean rake bundle:install - name: elasticsearch run: cd elasticsearch && bundle exec rake test:all - name: elasticsearch-transport faraday1 run: cd elasticsearch-transport && bundle install && bundle exec rake test:faraday1:all env: BUNDLE_GEMFILE: 'Gemfile-faraday1.gemfile' - name: elasticsearch-transport faraday2 run: cd elasticsearch-transport && bundle exec rake test:all - name: elasticsearch-api run: cd elasticsearch-api && bundle exec rake test:spec - name: elasticsearch-xpack run: cd elasticsearch-xpack && bundle exec rake test:unit test:spec elastic-elasticsearch-ruby-c38be0c/.github/workflows/docs-preview.yml000066400000000000000000000007421462737751600261720ustar00rootroot00000000000000--- name: docs-preview on: pull_request_target: types: [opened] permissions: pull-requests: write jobs: doc-preview-pr: runs-on: ubuntu-latest steps: - uses: elastic/docs/.github/actions/docs-preview@master with: github-token: ${{ secrets.GITHUB_TOKEN }} repo: ${{ github.event.repository.name }} preview-path: 'guide/en/elasticsearch/client/ruby-api/index.html' pr: ${{ github.event.pull_request.number }} elastic-elasticsearch-ruby-c38be0c/.github/workflows/license.yml000066400000000000000000000004401462737751600252000ustar00rootroot00000000000000name: License headers on: [pull_request] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: ruby/setup-ruby@v1 with: ruby-version: 3 - name: Check license headers run: | ruby ./.github/check_license_headers.rb elastic-elasticsearch-ruby-c38be0c/.gitignore000066400000000000000000000002421462737751600214260ustar00rootroot00000000000000.config .yardoc _yardoc coverage **/test/reports/ **/test/html_reports/ doc/ rdoc/ tmp Gemfile.lock .DS_Store *.log .idea/* profile/**/data/*.json .byebug_historyelastic-elasticsearch-ruby-c38be0c/CHANGELOG.md000066400000000000000000002157241462737751600212640ustar00rootroot00000000000000## 7.17.11 - Ruby 3.3 added to the test matrix. Tested versions of Ruby for 7.17.11: Ruby (MRI) 3.0, 3.1, 3.2, 3.3, JRuby 9.3, JRuby 9.4. - Adds `base64` dependency to `elasticsearch-transport`: base64 was added to the gemspec, since starting in Ruby 3.4.0, base64 will no longer be part of the default gems and will no longer be in the standard library, [#2400](https://github.com/elastic/elasticsearch-ruby/pull/2400) ## 7.17.10 Backports support for Faraday 2 from `elastic-transport`. ¡Gracias [santiagorodriguez96](https://github.com/santiagorodriguez96)! This version of the gem now supports Faraday v2. If you don't have a locked version of Faraday in your project, when you upgrade your gems, Faraday v2 will be installed. The main change on dependencies when using Faraday v2 is all adapters, except for the default `net_http` one, have been moved out of Faraday into separate gems. This means if you're not using the default adapter and you migrate to Faraday v2, you'll need to add the adapter gems to your Gemfile. These are the gems required for the different adapters with Faraday 2, instead of the libraries on which they were based: ```ruby # HTTPCLient gem 'faraday-httpclient' # NetHTTPPersistent gem 'faraday-net_http_persistent' # Patron gem 'faraday-patron' # Typhoeus gem 'faraday-typhoeus' ``` Things should work fine if you migrate to Faraday 2 as long as you include the adapter (unless you're using the default one `net-http`), but worst case scenario, you can always lock the version of Faraday in your project to 1.x: `gem 'faraday', '~> 1'` Be aware if migrating to Faraday v2 that it requires at least Ruby `2.6`, unlike Faraday v1 which requires `2.4`. *Troubleshooting* If you see a message like: `:adapter is not registered on Faraday::Adapter (Faraday::Error)` Then you probably need to include the adapter library in your gemfile and require it. Please [submit an issue](https://github.com/elastic/elasticsearch-ruby/issues) if you encounter any problems. ## 7.17.9 - Backports fix from `elastic-transport`: [#66](https://github.com/elastic/elastic-transport-ruby/issues/66) - Manticore transport unable to send custom headers with `perform_request` [Pull Request](https://github.com/elastic/elastic-transport-ruby/pull/69). ## 7.17.8 - Patch releases back to being detached from Elastic stack releases. - Tested compatibility with Elasticsearch v7.17 APIs. - Tested versions of Ruby for 7.17.8: Ruby (MRI) 2.7, 3.0, 3.1, 3.2, JRuby 9.3, JRuby 9.4. - Bugfix in elasticsearch-transport: Fixes enforcing UTF-8 in Response body, causing an error when the string is frozen, particularly when using webmock: [issue #63](https://github.com/elastic/elastic-transport-ruby/issues/63). ## 7.17.7 - Compatibility with Elasticsearch v7.17.7 APIs. - Tested versions of Ruby for 7.17.7: Ruby (MRI) 2.6, 2.7, 3.0 and 3.1, JRuby 9.3. ## 7.17.2, 7.17.3, 7.17.4, 7.17.5, 7.17.6 No release. ## 7.17.1 - Improves handling of YAML parsing, uses `safe_load` instead of `load` when doing the product verification (should only affect Ruby < 3.0). - Updates headers setup when using the Manticore adapter. This fixes an issue where the user-agent header was being foverridden even when it was being set on initialization via the transport options. [Pull Request](https://github.com/elastic/elasticsearch-ruby/pull/1685), [issue](https://github.com/elastic/elasticsearch-ruby/issues/1684). ## 7.17.0 - Drops Ruby 2.5 from the test matrix. Support for Ruby 2.5 was dropped March 2021. - Updates the product verification when the response is a `413` error. ## 7.16.3 ### API Bugfix for [#1475](https://github.com/elastic/elasticsearch-ruby/issues/1475), an issue where if you indexed a document with an id such as `an id`, it would get escaped to `an+id` instead of `an%20id` when using `index` or `create`. This would result in the document id being `an+id` instead of the intended value `an id`. ## 7.16.2 No release. ## 7.16.1 Patch release corresponding with Elastic Stack version 7.16.1 that addresses the Apache Log4j2 vulnerability, [more information](https://discuss.elastic.co/t/apache-log4j2-remote-code-execution-rce-vulnerability-cve-2021-44228-esa-2021-31/291476). ### Client The only changes in the client since 7.16.0 are a few minor updates for the [Compatibility mode with 8.0](https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/current/connecting.html#client-comp). We added the compatibility header in `7.13.0`, but now we have integration tests and compatibility tests for version `7.x` of the client with Elasticsearch `8.0`. ## 7.16.0 ### Client - Adds the `delay_on_retry` parameter, a value in milliseconds to wait between each failed connection, thanks [DinoPullerUqido](https://github.com/DinoPullerUqido)! [Pull Request](https://github.com/elastic/elasticsearch-ruby/pull/1521) and [backport](https://github.com/elastic/elasticsearch-ruby/pull/1523). - Adds *CA fingerprinting*. You can configure the client to only trust certificates that are signed by a specific CA certificate (CA certificate pinning) by providing a `ca_fingerprint` option. This will verify that the fingerprint of the CA certificate that has signed the certificate of the server matches the supplied value. The verification will be run once per connection. Code example: ```ruby ca_fingerprint = '64F2593F...' client = Elasticsearch::Client.new( host: 'https://elastic:changeme@localhost:9200', transport_options: { ssl: { verify: false } }, ca_fingerprint: ca_fingerprint ) ``` The verification will be run once per connection. - Fixes compression. When `compression` is set to `true`, the client will now gzip the request body properly and use the appropiate headers. Thanks [johnnyshields](https://github.com/johnnyshields)! [Pull Request](https://github.com/elastic/elasticsearch-ruby/pull/1478) and [backport](https://github.com/elastic/elasticsearch-ruby/pull/1526). - Warnings emitted by Elasticsearch are now logged via `log_warn` through the Loggable interface in the client, instead of using `Kernel.warn`. [Pull Request](https://github.com/elastic/elasticsearch-ruby/pull/1517). ### API #### Updates - Cleaned up some deprecated code. - `count` - The API is documented as using `GET`, but it supports both GET and POST on the Elasticsearch side. So it was updated to only use `POST` when there's a body present, or else use `GET`. Elasticsearch would still accept a body with `GET`, but to be more semantically correct in the clients we use `POST` when there's a body. - `delete_index_template` was updated to support the `ignore_404` parameter to ignore 404 errors when attempting to delete a non-existing template. - `ingest.put_pipeline` adds new parameter `if_version`: Required version for optimistic concurrency control for pipeline updates. - `ml.put_trained_model`: adds new parameter `defer_definition_decompression`: If set to `true` and a `compressed_definition` is provided, the request defers definition decompression and skips relevant validations. - `nodes.hot_threads` adds new parameter `sort`: The sort order for 'cpu' type (default: total) (options: cpu, total). - `open_point_in_time`: `keep_alive` is now a required parameter. - `search_mvt`: adds new parameter `track_total_hits`: Indicate if the number of documents that match the query should be tracked. A number can also be specified, to accurately track the total hit count up to the number. - `transform.preview_transform`: adds new parameter `transform_id`. Body is now optional and the API will use `GET` or `POST` depending on the presence of a body. ##### APIs promoted from experimental to stable since last version: - `fleet.global_checkpoints` - `get_script_context` - `get_script_language` - `indices.resolve_index` - `monitoring.bulk` - `rank_eval` - `searchable_snapshots.mount` - `searchable_snapshots.stats` - `security.clear_cached_service_tokens` - `security.create_service_token` - `security.delete_service_token` - `security.get_service_accounts` - `security.get_service_credentials` - `shutdown.delete_node` - `shutdown.get_node` - `shutdown.put_node` - `terms_enum` #### New APIs - `fleet.mseach` - `fleet.search` - `indices.modify_data_stream` - `ml.infer_trained_model_deployment` - `ml.start_trained_model_deployment` - `ml.stop_trained_model_deployment` - `migration.get_feature_upgrade_status` - `migration.post_feature_upgrade_status` - `security.enroll_kibana` - `security.enroll_node` - `transform.updgrade_transforms` ## 7.15.0 ### Client We've tested and added documentation on best practices for leveraging the client in a Function-as-a-Service (FaaS) environment to the [official docs](https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/current/connecting.html#client-faas). ### API - New experimental endpoints: `indices.disk_usage`. `indices.field_usage_stats`, `nodes.clear_repositories_metering_archive`, `get_repositories_metering_info`, [`search_mvt`](https://www.elastic.co/guide/en/elasticsearch/reference/master/search-vector-tile-api.html) - The `index` parameter is now required for `open_point_in_time`. - The `index_metric` parameter in `nodes.stats` adds the `shards` option. ### X-Pack - New parameters for `ml.put_job`: `ignore_unavailable`, `allow_no_indices`, `ignore_throttled`, `expand_wildcards`. - New endpoint: `security.query_api_keys`. [Documentation](https://www.elastic.co/guide/en/elasticsearch/reference/7.15/security-api-query-api-key.html) ## 7.14.1 ### Client - Fixes for Manticore Implementation: Addresses custom headers on initialization (https://github.com/elastic/elasticsearch-ruby/commit/3732dd4f6de75365460fa99c1cd89668b107ef1c) and fixes tracing (https://github.com/elastic/elasticsearch-ruby/commit/3c48ebd9a783988d1f71bfb9940459832ccd63e4). Related to #1426 and #1428. ## 7.14.0 ### Client Added check that client is connected to an Elasticsearch cluster. If the client isn't connected to a supported Elasticsearch cluster the `UnsupportedProductError` exception will be raised. This release changes the way in which the transport layer and the client interact. Previously, when using `elasticsearch-transport`, `Elasticsearch::Transport::Client` had a convenient wrapper, so it could be used as `Elasticsearch::Client`. Now, we are decoupling the transport layer from the Elasticsearch client. If you're using the `elasticsearch` gem, not much will change. It will instantiate a new `Elasticsearch::Transport::Client` when you instantiate `Elasticsearch::Client` and the endpoints from `elasticsearch-api` will be available. `Elasticsearch::Client` has an `attr_accessor` for the transport instance: ```ruby > client = Elasticsearch::Client.new > client.transport.class => Elasticsearch::Transport::Client > client.transport.transport.class => Elasticsearch::Transport::Transport::HTTP::Faraday ``` The interaction with `elasticsearch-api` remains unchanged. You can use the API endpoints just like before: ```ruby > client.info => {"name"=>"instance", "cluster_name"=>"elasticsearch", "cluster_uuid"=>"id", "version"=> {"number"=>"7.14.0", ... }, "tagline"=>"You Know, for Search"} ``` Or perform request directly from the client which will return an `Elasticsearch::Transport::Response` object: ```ruby > client.perform_request('GET', '/') # This is the same as doing client.transport.perform_request('GET', '/') => #"instance", "cluster_name"=>"elasticsearch", "cluster_uuid"=>"id", "version"=> {"number"=>"7.14.0-SNAPSHOT", ... }, "tagline"=>"You Know, for Search"}, @headers= {"content-type"=>"application/json; charset=UTF-8", "content-length"=>"571", ... }, @status=200> ``` If you have any problems, please report them in [this issue](https://github.com/elastic/elasticsearch-ruby/issues/1344). ### API Code is now generated from Elastic artifacts instead of checked out code of Elasticsearch. See [the Generator README](https://github.com/elastic/elasticsearch-ruby/blob/7.14/elasticsearch-api/utils/README.md#generate) for more info. - Endpoints `msearch`, `msearch_template` and `search_template` remove `query_and_fetch` and `dfs_query_and_fetch` options from the `search_type` parameter. - New parameter `include_repository` in `snapshot.get`: (boolean) Whether to include the repository name in the snapshot info. Defaults to true. ### X-Pack X-Pack is being deprecated. The first time using `xpack` on the client, a warning will be triggered. Please check [this issue](https://github.com/elastic/elasticsearch-ruby/issues/1274) for more information. - New endpoints: `index_lifecycle_management.migrate_to_data_tiers`, `machine_learning.reset_job`, `security.saml_authenticate`, `security.saml_complete_logout`, `security.saml_invalidate`, `security.saml_logout`, `security.saml_prepare_authentication`, `security.saml_service_provider_metadata`, `sql.delete_async`, `sql.get_async`, `sql.get_async_status`, `terms_enum`. - New experimental endpoints: `machine_learning.infer_trained_model_deployment`, `machine_learning.start_trained_model_deployment`, `machine_learning.stop_trained_model_deployment`. - Deprecation: `indices.freeze` and `indices.unfreeze`: Frozen indices are deprecated because they provide no benefit given improvements in heap memory utilization. They will be removed in a future release. ## 7.13.3 - API Support for Elasticsearch version 7.13.3 ## 7.13.2 - Mute release, yanked from RubyGems. ## 7.13.1 ### Client - Support for Elasticsearch version 7.13.1 - Fixes thread safety issue in `get_connection` - [Pull Request](https://github.com/elastic/elasticsearch-ruby/pull/1325). ## 7.13.0 ### Client - Support for Elasticsearch version 7.13.0 - Adds support for compatibility header for Elasticsearch. If the environment variable 'ELASTIC_CLIENT_APIVERSIONING' is set to `true` or `1`, the client will send the headers `Accept` and `Content-Type` with the following value: `application/vnd.elasticsearch+json;compatible-with=7`. - Better detection of Elasticsearch and Enterprise Search clients in the meta header used by cloud. ### API - The REST API tests now use an artifact downloaded from the Elastic servers instead of depending of cloning `elasticsearch` locally. Check the README for more information. - New parameter `include_unloaded_segments` in `cat.nodes`, `nodes.stats`: If set to true segment stats will include stats for segments that are not currently loaded into memory - New parameter `summary` in `ingest.get_pipeline`: Return pipelines without their definitions (default: false) - New parameter `index_details` in `snapshot.get`: Whether to include details of each index in the snapshot, if those details are available. Defaults to false. - New endpoint `features.reset_features`, `ingest/geo_ip_stats` - New experimental endpoints: `shutdown.delete_node`, `shutdown.get_node`, `shutdown.put_node`. ### X-Pack - Refactored test tasks, made it easier to run the tests by default. - New experimental endpoints: `fleet.global_checkpoints`, `searchable_snapshots.cache_stats`. - New beta endpoints: `security.clear_cached_service_tokens`, `security.create_service_token`, `security.delete_service_token`, `security.get_service_accounts`, `security.get_service_credentials` - New endpoints: `machine_learning.delete_trained_model_alias`, `machine_learning.preview_data_frame_analytics`, `machine_learning.put_trained_model_alias`. - APIs migrated from experimental or beta to stable: `machine_learning.delete_data_frame_analytics`, `machine_learning.delete_trained_model`, `machine_learning.estimate_model_memory`, `machine_learning.explain_data_frame_analytics`, `machine_learning.get_data_frame_analytics`, `machine_learning.get_data_frame_analytics_stats`, `machine_learning.get_trained_models`, `machine_learning.get_trained_models_stats`, `machine_learning.put_data_frame_analytics`, `machine_learning.put_trained_model`, `machine_learning.start_data_frame_analytics`, `machine_learning.stop_data_frame_analytics`, `machine_learning.update_data_frame_analytics` - New parameter `body` in `machine_learning.preview_datafeed`: The datafeed config and job config with which to execute the preview. ## 7.12.0 ### Client - Support for Elasticsearch version 7.12.0 - Ruby 3 is now tested, it was added to the entire test suite. - New official documentation pages for configuration: [Basic Configuration](https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/current/basic-config.html) and [Advanced Configuration](https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/current/advanced-config.html). - Integration tests runner refactored to keep skipped tests in a yaml file. ### API - New API namespace: `features` and endpoints `features.get_features` and `snapshot.get_features`. - `cat.plugins` adds parameter `include_bootstrap`: Include bootstrap plugins in the response. - Update in `indices.close` parameter `wait_for_active_shards`: Sets the number of active shards to wait for before the operation returns. Set to `index-setting` to wait according to the index setting `index.write.wait_for_active_shards`, or `all` to wait for all shards, or an integer. Defaults to `0`. - `actions.search` adds parameter `min_compatible_shard_node`: The minimum compatible version that all shards involved in search should have for this request to be successful. ### X-Pack - New API namespace: `text_structure` and endpoints `text_structure.find_structure`. - New API namespace: `logstash` and endpoints `logstash.delete_pipeline`, `logstash.get_pipeline`, `logstash.put_pipeline`. - New API: `eql.get_status`. - APIs migrated from experimental to stable: `autoscaling.delete_autoscaling_policy`, `autoscaling.get_autoscaling_capacity`, `autoscaling.get_autoscaling_policy`, `autoscaling.put_autoscaling_policy`. - `searchable_snapshots.mount` adds parameter `storage`: Selects the kind of local storage used to accelerate searches. Experimental, and defaults to `full_copy`. - `searchable_snapshots.stats` adds parameter `level`: Return stats aggregated at cluster, index or shard level (options: cluster, indices, shards). ## 7.11.2 ### Client * Bug fix in meta header, fixes fail when http adapter library hasn't been loaded yet: [Issue](https://github.com/elastic/elasticsearch-ruby/issues/1224). ## 7.11.1 ### Client * Bug fix in meta header, adds support for unknown Faraday adapters. [Pull Request](https://github.com/elastic/elasticsearch-ruby/pull/1204). ## 7.11.0 ### Client - Fixes a bug with headers in our default Faraday class. [Commit](https://github.com/elastic/elasticsearch-ruby/commit/9c4afc452467cc6344359b54b98bbe5af1469219). - Adds the `X-Elastic-Client-Meta` HTTP header which is used by Elastic Cloud and can be disabled with the `enable_meta_header` parameter set to `false`. ### API #### API Changes - `cat.tasks` - Parameter `node_id` changes name to `nodes`, a comma-separated list of node IDS or names. Parameter `parent_task` changes name to `parent_task_id`. - APIs that are no longer experimental: `cluster.delete_component_template`, `cluster.exists_component_template`, `cluster.get_component_template`, `cluster.put_component_template`, `indices.delete_index_template`, `indices.exists_index_template`, `indices.get_index_template`, `indices.put_index_template`, `indices.simulate_index_template`, `indices.simulate_template`. - Deprecation notice: The _upgrade API is no longer useful and will be removed. Instead, see `_reindex API`. Deprecated since version 8.0.0. Endpoints: `indices.get_upgrade`, `indices.upgrade` #### X-Pack - New endpoints:`async_search.status`, `autoscaling.get_autoscaling_capacity` (experimental), `indices.migrate_to_data_stream`, `indices.promote_data_stream`, `machine_learning.upgrade_job_snapshot`, `rollup.rollup`, `watcher.query_watches`. - APIs that are no longer experimental: `eql.delete`, `eql.get`, `eql.search`, - APIs promoted from experimental to beta: `machine_learning.delete_data_frame_analytics`, `ml.delete_trained_model`, `machine_learning.evaluate_data_frame`, `machine_learning.explain_data_frame_analytics`, `machine_learning.get_data_frame_analytics`, `machine_learning.get_datafeed_stats`, `machine_learning.get_trained_models`, `machine_learning.get_trained_models_stats`, `machine_learning.put_data_frame_analytics`, `machine_learning.put_trained_model`, `machine_learning.start_data_frame_analytics`, `machine_learning.stop_data_frame_analytics`, `machine_learning.update_data_frame_analytics` - `indices.delete_data_stream`, `indices.get_data_stream` add parameter `expand_wildcards`, wether wildcard expressions should get expanded to open or closed indices (default: open). Options: open, closed, hidden, none, all. - `machine_learning.get_data_frame_analytics`, `machine_learning.get_datafeeds`, `machine_learning.get_jobs`, `machine_learning.get_trained_models`, `transform.get_transform` add parameter `exclude_generated` - omits fields that are illegal to set on PUT. - `data_frame_transform_deprecated.get_transform` (_data_frame/transforms/ is deprecated, use _transform/ in the future) adds parameter `exclude_generated` - omits generated files. ## 7.10.1 - Use 443 for default cloud port, 9200 as the default port for http ## 7.10.0 ### Client - Support for Elasticsearch version `7.10.0`. - Fixes a bug when building the complete endpoint URL could end with duplicate slashes `//`. - Fixes a bug when building the complete endpoint URL with cloud id could end with duplicate ports [#1081](https://github.com/elastic/elasticsearch-ruby/issues/1081). ### API - Fix in RubyDoc comments, some parameters were being duplicated. - Deprecation notice: Synced flush (`indices.flush_synced`) is deprecated and will be removed in 8.0. Use flush instead. #### New API Endpoints - `snapshot.clone` #### API Changes - `bulk`, `index`, `update`: new parameter `require_alias` (boolean): When true, requires destination to be an alias (default: false) for `index` and `update`. For `bulk` it sets `require_alias` for all incoming documents. Defaults to unset (false). ### X-Pack Deprecation notice: `searchable_snapshots.repository_stats` is deprecated and is replaced by the Repositories Metering API. #### New API Endpoints - `close_point_in_time` - `open_point_in_time` - `security.clear_api_key_cache` - `security.grant_api_key` #### API Changes - `cat.ml_datafeeds`, `cat.ml_jobs`, `machine_learning.close_job`, `machine_learning.get_datafeed_stats`, `machine_learning.get_datafeeds`, `machine_learning.get_job_stats`, `machine_learning.get_jobs`, `machine_learning.get_overall_buckets`, `machine_learning.stop_datafeed`: new parameter `allow_no_match` (boolean): Whether to ignore if a wildcard expression matches no datafeeds. (This includes `_all` string or when no datafeeds have been specified) -`machine_learning.get_data_frame_analytics`: new parameter `verbose` (boolean), whether the stats response should be verbose - `machine_learning.get_trained_models`: new parameter `include` (string), a comma-separate list of fields to optionally include. Valid options are 'definition' and 'total_feature_importance'. Default is none. - `machine_learning.stop_datafeed`: endpoint now accepts a `body`: the URL params optionally sent in the body - `security.get_role`, `security/get_role_mapping`: The name parameter is now a comma-separated list of role-mapping names - `machine_learning.delete_trained_model`, `machine_learning.get_trained_models`, `machine_learning.get_trained_models_stats`, `machine_learning.put_trained_model`: Internal change, url changed from `_ml/inference` to `_ml/trained_models` ## 7.9.0 ### Client - Support for Elasticsearch version `7.9.0`. - Transport/Connection: Considers attributes values for equality - [Commit](https://github.com/elastic/elasticsearch-ruby/commit/06ffd03bf51f5f33a0d87e9914e66b39357d40af). - When an API endpoint accepts both `GET` and `POST`, the client will always use `POST` when a request body is present. ### API - Documentation for API endpoints will point out when an API is experimental, beta or unstable. #### New API Endpoints - New namespace: `dangling_indices` - `dangling_indices.delete_dangling_index` - `dangling_indices.import_dangling_index` - `dangling_indices.list_dangling_indices` - `indices.add_block` Experimental endpoints: - `indices.resolve_index` - `simulate_template` #### API Changes - `field_caps`: adds body parameter allowing to filter indices if `index_filter` is provided. - `eql.search`: new parameters `wait_for_completion`, `keep_on_completion` and `keep_alive`. - `info`: New parameter `accept_enterprise`: If an enterprise license is installed, return the type and mode as 'enterprise' (default: false). - `indices.put_mapping`: new parameter `write_index_only`. ### X-Pack #### New API Endpoints The Ruby client now supports all the X-Pack API endpoints. - New namespace `autoscaling`: `autoscaling.delete_autoscaling_policy`, `autoscaling.get_autoscaling_decision`, `autoscaling.get_autoscaling_policy`, `autoscaling.put_autoscaling_policy` - New namespace `enrich`: `enrich.delete_policy`, `enrich.execute_policy`, `enrich.get_policy`, `enrich.put_policy`, `enrich.stats` - New namespace `eql`: `eql.delete`, `eql.get`, `eql.search` - New namespace `cross_cluster_replication`: `cross_cluster_replication.delete_auto_follow_pattern`, `cross_cluster_replication.follow`, `cross_cluster_replication.follow_info`, `cross_cluster_replication.follow_stats`, `cross_cluster_replication.forget_follower`, `cross_cluster_replication.get_auto_follow_pattern`, `cross_cluster_replication.pause_auto_follow_pattern`, `cross_cluster_replication.pause_follow`, `cross_cluster_replication.put_auto_follow_pattern`, `cross_cluster_replication.resume_auto_follow_pattern`, `cross_cluster_replication.resume_follow`, `cross_cluster_replication.stats`, `cross_cluster_replication.unfollow` - New namespace `snapshot_lifecycle_management`: `snapshot_lifecycle_management.delete_lifecycle`, `snapshot_lifecycle_management.execute_lifecycle`, `snapshot_lifecycle_management.execute_retention`, `snapshot_lifecycle_management.get_lifecycle`, `snapshot_lifecycle_management.get_stats`, `snapshot_lifecycle_management.get_status`, `snapshot_lifecycle_management.put_lifecycle`, `snapshot_lifecycle_management.start`, `snapshot_lifecycle_management.stop` - `indices.create_data_stream` - `indices.data_streams_stats` - `indices.delete_data_stream` - `indices.get_data_stream` - `security.clear_cached_privileges` - `machine_learning.update_data_frame_analytics` #### API Changes - `machine_learning.delete_expired_data`: new parameters `job_id`, `requests_per_second` and `timeout` ## 7.8.1 ### Client - Support for Elasticsearch version `7.8.1`. - Bug fix: Fixed a bug on the API endpoints documentation for RubyDocs: there was an unnecessary empty new line in the documentation for parameters that have options. So the parameters before that empty newline were not being documented in RubyDocs. ### X-Pack #### API Changes - Update to `info` endpoint. New parameter `accept_enterprise` (boolean): If an enterprise license is installed, return the type and mode as 'enterprise' (default: false). ## 7.8.0 ### Client - Support for Elasticsearch version `7.8`. - Surface deprecation headers from Elasticsearch. When there's a `warning` response header in Elasticsearch's response, the client will emit a warning with `warn`. - Typhoeus is supported again, version 1.4+ and has been added back to the docs. - Adds documentation and example for integrating with Elastic APM. ### API #### New API Endpoints - `abort_benchmark` - `benchmark` - `cluster.delete_voting_config_exclusions` - `cluster.post_voting_config_exclusions` - `delete_by_rethrottle` - `nodes.shutdown` - `remote.info` Experimental endpoints: - `cluster.delete_component_template` - `cluster.exists_component_template` - `cluster.get_component_template` - `cluster.put_component_template` - `indices.delete_index_template` - `indices.exists_index_template` - `indices.get_index_template` - `indices.put_index_template` - `indices.simulate_index_template` #### API Changes - `cat/thread_pool`: `size` is deprecated. - `indices.get_data_streams`: `name` is now a string instead of list, the name or wildcard expression of the requested data streams. - `indices.put_index_template`: new parameter: `cause` (string), user defined reason for creating/updating the index template. - `indices.simulate_index_template`: Two new parameters: `create`, whether the index template we optionally defined in the body should only be dry-run added if new or can also replace an existing one. `cause` User defined reason for dry-run creating the new template for simulation purposes. - `snapshot.delete_repository`: New parameter `repository`, name of the snapshot repository, wildcard (`*`) patterns are now supported. - `task.cancel`: new parameter `wait_for_completion` (boolean) Should the request block until the cancellation of the task and its descendant tasks is completed. Defaults to false. ### X-Pack #### New API Endpoints New namespace: `indices` - `indices.freeze` - `indices.reload_search_analyzers` - `indices.unfreeze` New namespace: `searchable_snapshots` - `clear_cache` - `mount` - `repository_stats` - `stats` #### API Changes - `machine_learning.delete_expired_data` new param `body`: deleting expired data parameters. - `machine_learning.delete_data_frame_analytics` new param `timeout`: controls the time to wait until a job is deleted. Defaults to 1 minute. ## 7.7.0 This version drops support for Ruby 2.4 since it's reached it's end of life. ### Client - Support for Elasticsearch version `7.7` #### Custom Headers You can set custom HTTP headers on the client's initializer or pass them as a parameter to any API endpoint. [More info and code examples](https://github.com/elastic/elasticsearch-ruby/tree/7.x/elasticsearch-transport#custom-http-headers). ### API #### API Changes - Clean: Removes up some deprecated endpoints: `abort_benchmark`, `benchmark`, `delete_by_rethrottle`, `nodes.shutdown`, `remote.info`. - `expand_wildcards` Whether to expand wildcard expressions to concrete indices that are open, closed or both. Options: open, closed, hidden, none, all. `hidden` option is new. It was also added to the following endpoints: `cat.aliases`, `cat.indices`. - `delete_by_query`: Parameter `slices` can now be set to `auto`. - `reindex`: Parameter `slices` can now be set to `auto`. - `update_by_query`: Parameter `slices` can now be set to `auto`. - `snapshot.cleanup_repository`: Parameter `body` is removed. #### New API Endpoints - `cluster.delete_component_template` - `cluster.get_component_template` - `cluster.put_component_template` - `indices.create_data_stream` (experimental) - `indices.delete_data_stream` (experimental) - `indices.get_data_stream` (experimental) ### X-Pack #### API Changes - `machine_learing.get_trained_models`: New parameter `tags` - `machine_learning.put_datafeed`, `machine_learning.update_datafeed`: Added parameters `ignore_unavailable`, `allow_no_indices`, `ignore_throttled`, `expand_wildcards` - `reload_secure_settings`: New parameter `body`, an object containing the password for the keystore. #### New API Endpoints - `async_search.delete` - `async_search.get` - `async_search.submit` - `cat.ml_data_frame_analytics` - `cat.ml_datafeeds` - `cat.ml_jobs` - `cat.ml_trained_models` - `cat.transform` - `cat.transforms` - `machine_learning.estimate_model_memory` - `transform.delete_transform` - `transform.get_transform` - `transform.get_transform_stats` - `transform.preview_transform` - `transform.put_transform` - `transform.start_transform` - `transform.stop_transform` - `transform.update_transform` ## 7.6.0 ### Client - Support for Elasticsearch version `7.6`. - Last release supporting Ruby 2.4. Ruby 2.4 has reached it's end of life and no more security updates will be provided, users are suggested to update to a newer version of Ruby. #### API Key Support The client now supports API Key Authentication, check "Authentication" on the [transport README](https://github.com/elastic/elasticsearch-ruby/tree/7.x/elasticsearch-transport#authentication) for information on how to use it. #### X-Opaque-Id Support The client now supports identifying running tasks with X-Opaque-Id. Check [transport README](https://github.com/elastic/elasticsearch-ruby/tree/7.x/elasticsearch-transport#identifying-running-tasks-with-x-opaque-id) for information on how to use X-Opaque-Id. #### Faraday migrated to 1.0 We're now using version 1.0 of Faraday: - The client initializer was modified but this should not disrupt final users at all, check [this commit](https://github.com/elastic/elasticsearch-ruby/commit/0fdc6533f4621a549a4cb99e778bbd827461a2d0) for more information. - Migrated error checking to remove the deprecated `Faraday::Error` namespace. - **This change is not compatible with [Typhoeus](https://github.com/typhoeus/typhoeus)**. The latest release is 1.3.1, but it's [still using the deprecated `Faraday::Error` namespace](https://github.com/typhoeus/typhoeus/blob/v1.3.1/lib/typhoeus/adapters/faraday.rb#L100). This has been fixed on master, but the last release was November 6, 2018. Version 1.4.0 should be ok once it's released. - Note: Faraday 1.0 drops official support for JRuby. It installs fine on the tests we run with JRuby in this repo, but it's something we should pay attention to. Reference: [Upgrading - Faraday 1.0](https://github.com/lostisland/faraday/blob/master/UPGRADING.md) [Pull Request](https://github.com/elastic/elasticsearch-ruby/pull/808) ### API #### API Changes: - `cat.indices`: argument `bytes` options were: `b,k,m,g` and are now `b,k,kb,m,mb,g,gb,t,tb,p,pb`. - `delete_by_query`: New parameter `analyzer` - The analyzer to use for the query string. - `indices.put_template`: Removed parameters: `timeout`, `flat_settings`. - `msearch_template`: New Parameter `ccs_minimize_roundtrips` - Indicates whether network round-trips should be minimized as part of cross-cluster search requests execution. - `rank_eval`: New parameter `search_type` - Search operation type (options: `query_then_fetch,dfs_query_then_fetch`). - `search_template`: New parameter `ccs_minimize_roundtrips` - Indicates whether network round-trips should be minimized as part of cross-cluster search requests execution. #### New API endpoints: - `get_script_context` - `get_script_languages` #### Warnings: Synced flush is deprecated and will be removed in 8.0. ### X-Pack #### New API endpoints: - `ml/delete_trained_model` - `ml/explain_data_frame_analytics` - `ml/get_trained_models` - `ml/get_trained_models_stats` - `ml/put_trained_model` #### API changes: - `license/get`: Added parameter `accept_enterprise`. - `ml/delete_data_frame_analytics` Added parameter `force`. - `monitoring/bulk` - Removed parameter `system_version`. ## 7.5.0 - Support for Elasticsearch 7.5. - Update API spec generator: The code for Elasticsearch OSS and X-Pack APIs is being generated from the rest api spec. - Specs have been updated to address new/deprecated parameters. - Ruby versions tested: 2.3.8, 2.4.9, 2.5.7, 2.6.5 and 2.7.0 (new). ### API Endpoints that changed: - `_bulk`: body is now required as an argument. - `cat`: `local` and `master_timeout` parameters are gone. - `health`: New parameter `health`. - `indices`: Adds `time` and `include_unload_segments` parameters. - `nodes`: Adds `bytes`, `time` parameters. - `pending_tasks`: Adds `time` parameter. - `recovery`: Adds `active_only`, `detailed`, `index`, `time` parameters. - `segments`: Removes `index` parameter and it's now a url part. - `shards`: Adds `time` parameter. - `snapshots`: Adds `time` parameter. - `tasks`: Adds `time` parameter. - `templates`: The `name` parameter is now passed in as a part but not a parameter. - `thread_pool`: The `thread_pool_patterns` parameter is now passed in as a part but not as a parameter. - `cluster` - `put_settings`: body is required. - `state`: `index_templates` is gone. - `node_id` is now a url part. - `delete` - `parent` parameter is gone. - `delete_by_query`: `analyzer` parameters are gone, `max_docs` is a new parameter, `body` is now a required parameter. - `delete_by_query_rethrottle` new endpoint. - `delete_by_rethrottle` - uses `delete_by_query_rethrottle` and hasn't changed. - `exists`, `exists_source`, `explain`: `parent` parameter is gone. - `field_caps`: `fields` param is no longer required. - `get`: `parent` parameter is gone - `get_source`: `parent` parameter is gone - `index`: `body` parameter is required, `wait_for_shard` is a new parameter, `consistency`, `include_type_name`, `parent`, `percolate`, `replication`, `timestamp`, `ttl` parameters are gone - `indices` - `get`: `feature` paramatere was deprecated and is gone. - `delete_aliases`, `put_alias`: URL changed internally to 'aliases' instead of 'alias' but shouldn't affect the client's API. - `render_search_template`: `id` is now a part not a parameter - `search`: `fielddata_fields`, `include_type_name`, `fields`, `ignore_indices`, `lowercase_expanded_terms`, `query_cache`, `source` parameters are gone, `ccs_minimize_roundtrips`, `track_scores` are new parameters. - `tasks` - `list`: task_id is not supported anymore, it's in get now. - `termvectors`: `parent` parameter is gone. - `update`: `version` parameter is not supported anymore. ### X-PACK Some urls changed internally to remove `_xpack`, but it shouldn't affect the client's API. - `explore`: `index` is now required. - `info`: `human` parameter is gone. - `migration`: some endpoints are gone: `get_assistance`, `get_assistance_test` and `upgrade_test`. - `watcher`: `restart` endpoint is gone. ## 7.4.0 ### Client * Accept options passed to #perform_request to avoid infinite retry loop * Fix minor typo ### API * Update documentation of put_script method ### EXT:7.4.0 ### XPACK * Add ParamsRegistry in each direcotry and for Xpack top-level API * Add ParamsRegistry for Xpack data_frame API * Add ParamsRegistry for Xpack graph API * Add ParamsRegistry for Xpack license API * Add ParamsRegistry for Xpack MachineLearning API * Fix path for loading params_registry files * Add ParamsRegistry for Xpack Migration API * Add ParamsRegistry for Xpack Monitoring API * Add ParamsRegistry for Xpack Rollup API * Add ParamsRegistry for Xpack security API * Add ParamsRegistry for Xpack sql API * Add ParamsRegistry for Xpack watcher API * Update missed file with ParamsRegistry * Update versions in params registry files * Add update_data_frame_transform * Support Index Lifecycle Management(ILM) API ## 7.3.0 ### Client * Add note to readme about the default port value * Add note about exception to default port rule when connecting using Elastic Cloud ID * Cluster name is variable in cloud id ### XPACK * Support allow_no_match parameter in stop_data_frame_transform * Add allow_no_match to get_data_frame_transform API * Add missing headers * Support get_builtin_privileges API * Update tests for changed xpack paths * test:integration task in xpack gem shouldn't do anything in favor of test:rest_api ## 7.2.0 ### Client * Support User-Agent header client team specification * Improve code handling headers * Handle headers when using JRuby and Manticore * Rename method for clarity * Test selecting connections using multiple threads * Synchronize access to the connections collection and mutation of @current instance variable * Fix specs for selecting a connection * Further fixes to specs for testing selecting connections in parallel * Support providing a cloud id * Allow a port to be set with a Cloud id and use default if no port is provided * Remove unnecessary check for cloud_id when setting default port * Add documentation for creating client with cloud_id * Allow compression with Faraday and supported http adapters * Put development gem dependencies in gemspec * No reason to use ! for decompress method name * Check for the existence of headers before checking headers * Apply compression headers manually based on general :compression option * Use GZIP constant * Group tests into their transport adapters * Support compression when using Curb adapter * Support compression when using Manticore adapter with JRuby * Fix Curb unit test, expecting headers to be merged and not set * Update test descriptions for compression settings * Add documentation of 'compression' option on client * Improve client documentation for compression option * Centralize header handling into one method * Only add Accept-Encoding header if compression option is true ### API * Use rewritten test harness from XPACK for rest API tests * Include skipped tests and further updates * Delete all repositories and snapshots in a method * Further updates to the rest API test runner * Add erroneously removed constants and gems * Updates to rest api yaml rspec tasks * The get_source endpoint should raise an error if the resource is not found * Rename method to clear data in tests and consolidate tasks into one method * Update api for 7.2 ### EXT:7.2.0 ### XPACK * Add data_frame API * Update data frame files ## 7.1.0 ### Client * Update elasticsearch-transport README * Use default port when host and protocol are specified but no port * Verify that we have a response object before checking its status * Make code more succinct for supporting host with path and no port * Support options specified with String keys * Update elasticsearch-transport/lib/elasticsearch/transport/client.rb * Add tests showing IPv6 host specified when creating client ### API * Update links in elasticsearch-api README ### DSL * Update links in elasticsearch-dsl README * Allow Bool query and Bool filter methods to take objects as arguments * Edit tests on bool query / filter to match context ### EXT:7.1.0 * Update elasticsearch-ext README ### XPACK * Update elasticsearch-xpack README * Minor formatting fix * Remove puts line ## 7.0.0.pre * Added `elastic_ruby_console` executable ### Client * Fixed failing integration test * Updated the Manticore development dependency * Fixed a failing Manticore unit test * Removed "turn" and switched the tests to Minitest * Fixed integration tests for Patron * Allow passing request headers in `perform_request` * Added integration test for passing request headers in `perform_request` * Added, that request headers are printed in trace output, if set * Fix typos in elasticsearch-transport/README.md * Assert that connection count is at least previous count when reloaded * Adjust test for change in default number of shards on ES 7 * Abstract logging functionality into a Loggable Module (#556) * Convert client integration tests to rspec * Add flexible configuration in spec helper * Use helper methods in spec_helper * Remove minitest client integration tests in favor of rspec test * Convert tests to rspec and refactor client * minor changes to the client specs * Use pry-nav in development for JRuby * Keep arguments variable name for now * Skip round-robin test for now * Mark test as pending until there is a better way to detect rotating nodes * Remove client unit test in favor of rspec test * Comment-out round-robin test as it occasionally passes and pending is ineffective * Document the default host and port constant * Add documentation to spec_helper methods * Redacted password if host info is printed in error message * Adds tests for not including password in logged error message * The redacted string change will be in 6.1.1 * Add more tests for different ways to specify client host argument * Do not duplicate connections in connection pool after rebuild (#591) * Ensure that the spec rake task is run as part of integration tests * Use constant to define Elasticsearch hosts and avoid yellow status when number of nodes is 1 * Update handling of publish_address in _nodes/http response * Add another test for hostname/ipv6:port format ### API * Added the `wait_for_active_shards` parameter to the "Indices Open" API * Added the "Indices Split" API * Added the `wait_for_no_initializing_shards` argument to the "Cluster Health" API * Added the "Cluster Remote Info" API * Remove the dependency on "turn" * Clear cluster transient settings in test setups * Use `YAML.load_documents` in the REST tests runner * Removed pinning dependency for Minitest * Replaced the testing framework from Test::Unit to Minites and improved test output * Added, that trace logs are printed when the `TRACE` environment variable is set * Removed the "turn" dependency from generated test_helper.rb * Update the "Delete By Query" API to support :slices * Speed up `Elasticsearch::API::Utils.__listify` * Speed up `Elasticsearch::API::Utils.__pathify` * Use "String#strip" and "String.empty?" in `Utils.__pathify` * Updated the inline documentation for using scripts in the "Update" API * Updated the "Scroll" API inline example with passing the scroll ID in the body * Marked the `percolate` method as deprecated and added an example for current percolator * Fixed, that `Utils.__report_unsupported_parameters` and `Utils.__report_unsupported_method` use `Kernel.warn` so they can be suppressed * Fixed the "greedy" regex in the `Utils.__rescue_from_not_found` method * Fixed the incorrect `create` method * Allow passing headers in `perform_request` * Set application/x-ndjson content type on Bulk and Msearch requests * Update the Reindex API to support :slices * Fixed and improved the YAML tests runner * Added the `include_type_name` parameter to APIs * Fixed the helper for unit tests * Removed the requirement for passing the `type` parameter to APIs * Removed dead code from the YAML tests runner * Fixed the `api:code:generate` Thor task * Add copy_settings as valid param to split API * Port api/actions tests to rspec (#543) * Update tests to not require type * Account for escape_utils not being available for JRuby * Add nodes/reload_secure_settings endpoint support (#546) * Add new params for search and msearch API * Retrieve stashed variable if referenced in test * Convert cat API tests to rspec * Convert cluster API tests to rspec * Convert indices tests to rspec * Fix documentation of #indices.analyze * Avoid instantiating an array of valid params for each request, each time it is called (#550) * Add headers to custom client documentation (#527) * Fix typos in README * Minor update to scroll documentation example * Convert snapshot, ingest, tasks, nodes api tests to rspec * Update source_includes and source_excludes params names for mget * Update source_includes and source_excludes params names for get, search, bulk, explain * Update source_includes and source_excludes params names for get_source * Mark _search endpoint as deprecated * Link to 6.0 documentation explicitly for _suggest deprecation * Update documentation for msearch * Update documentation for scroll_id to be in body of scroll endpoint * Remove reference to deprecated format option for _analyze endpoint * Correct endpoints used for get and put search template * Fix minor typo * Note that a non-empty body argument is required for the bulk api * Add note about empty body in yard documentation * Support if_primary_term param on index API * Delete test2 template in between tests in case a test is not cleanup up properly * Support ignore_throttled option on search API * Updates for types removal changes * Add missing update param * Add missing params to methods * Support if_primary_term param for delete * Delete an index and index template not cleaned up after in rest api tests * Update supported params for cat API endpoints * Update supported params for cluster API endpoints * Update supported params for indices API endpoints * Update supported params for ingest API endpoints * Update supported params for nodes API endpoints * Update supported params for snapshot API endpoints * Update missed node API endpoints * Update missed tasks API endpoints * Update top-level api endpoints * Adjust specs and code after test failures * Fix accidental overwrite of index code * Add missing param in cat/thread_pool * The type argument is not required in the index method * Delete 'nomatch' template to account for lack of test cleanup * Ensure that the :index param is supported for cat.segments * Ensure that the :name param is passed to the templates API ### DSL * Add inner_hits option support for has_parent query * Add inner_hits option support for has_child query * Add inner_hits option support for has_parent filter * Add inner_hits option support for has_child filter * adds query support for nested queries in filter context (#531) * Convert aggregations/pipeline tests to rspec (#564) * Convert aggregations tests to rspec (#566) * Convert filters tests to rspec (#567) * Fix bug in applying no_match_filter to indices filter * Update test for current elasticsearch version * Fix integration tests for join field syntax * Update agg scripted metric test for deprecation in ES issue #29328 * Fix script in update for #29328 * minor: fix spacing * Convert queries tests to rspec (#569) * Add inner_hits test after cherry-picking rspec conversion * Remove tests already converted to rspec * spec directory structure should mirror code directory structure * Support query_string type option * Ensure that filters are registered when called on bool queries (#609) * Don't specify a type when creating mappings in tests ### XPACK * Embedded the source code for the `elasticsearch-xpack` Rubygem * Fixed the `setup` for YAML integration tests * Added missing X-Pack APIs * Improved the YAML integration test runner * Updated the Rakefile for running integration tests * Added, that password for Elasticsearch is generated * Fixed the Watcher example * Updated the README * Added gitignore for the `elasticsearch-xpack` Rubygem * Add ruby-prof as a development dependency * Handle multiple roles passed to get_role_mapping * Minor updates to xpack api methods (#586) * Support freeze and unfreeze APIs * Rewrite xpack rest api yaml test handler (#585) * Updates to take into account SSL settings * Fix mistake in testing version range so test can be skipped * Support set_upgrade_mode machine learning API * Support typed_keys and rest_total_hits_as_int params for rollup_search * Improve string output for xpack rest api tests * Fix logic in version checking * Support if_seq_no and if_primary_term in put_watch * Don't test execute_watch/60_http_input because of possible Docker issue * Support api key methods * Fix minor typo in test description * Fix issue with replacing argument value with an Integer value * Support transform_and_set in yaml tests * Skip two more tests * Run security tests against elasticsearch 7.0.0-rc2 * Account for error when forecast_id is not provided and legacy path is used * Blacklist specific tests, not the whole file * Fix version check for skipping test _Note: Up-to-date changelogs for each version can be found in their respective branches (e.g. [1.x/CHANGELOG.md](https://github.com/elastic/elasticsearch-ruby/blob/1.x/CHANGELOG.md))_ ## 6.0.0 Elasticsearch 6.0 compatibility. ### API * Added missing arguments to the "Exists" API * Added missing parameters to the "Indices Clear Cache" API * Added missing parameters to the "Indices Delete" API * Added missing parameters to the "Multi Search" API * Added missing parameters to the "Search" API * Added missing parameters to the "Search" API * Added requirement for the `id` argument for the "Create" API * Added support for additional parameters to the "Cluster State" API * Added support for additional parameters to the "Rollover" API * Added the "Remote Info" API * Added the "verbose" parameter to the "Get Snapshot" API * Aded the "Get Task" API * Changed, that the YAML test content is not printed unless `DEBUG` is set * Fixed a failing unit test for the "Create Document" API * Fixed handling of parameters in the "Rollover" API * Fixed incorrect handling of `catch` clauses in the YAML tests runner * Fixed incorrect handling of node ID in the "Nodes Stats" API * Fixed incorrect URL parameter in "Indices Flush" unit test * Fixed the failing unit tests for "Scroll" APIs * Fixes for the "Scroll" API * Updated and improved the YAML test runner ### Client * Added default value 'application/json' for the 'Content-Type' header * Added escaping of username and password in URL * Added proper handling of headers in client options to the Manticore adapter * Don't block waiting for body on HEAD requests * Fixed double logging of failed responses * Fixed incorrect test behaviour when the `QUIET` environment variable is set * Fixed the bug with `nil` value of `retry_on_status` * Fixed the incorrect paths and Typhoeus configuration in the benchmark tests * Fixed the integration tests for client * Fixed typo in default port handling during `__build_connections` * Swallow logging of exceptions when the `ignore` is specified ## 5.0.5 ### Client * Added escaping of username and password in URL * Don't block waiting for body on HEAD requests ### API * Aded the "Get Task" API * Fixed handling of parameters in the "Rollover" API * Added requirement for the `id` argument for the "Create" API * Added support for additional parameters to the "Rollover" API * Added support for additional parameters to the "Cluster State" API * Fixed incorrect handling of `catch` clauses in the YAML tests runner * Fixed a failing unit test for the "Create Document" API * Removed unsupported parameters from the "Indices Flush" API * Added the "Remote Info" API * Fixed incorrect URL parameter in "Indices Flush" unit test * Fixed incorrect handling of node ID in the "Nodes Stats" API * Fix the path for indices exists_type? method & update docs * Added terminate_after parameter to Count action * Marked the `percolate` method as deprecated and added an example for current percolator * Fixed, that `Utils.__report_unsupported_parameters` and `Utils.__report_unsupported_method` use `Kernel.warn` so they can be suppressed * Update the Reindex API to support :slices ### DSL * Added the `match_phrase` and `match_phrase_prefix` queries * Removed the `type` field from the "Match" query * Added an integration test for the "match phrase prefix" query ## 5.0.4 ### Client * Fixed incorrect test behaviour when the `QUIET` environment variable is set * Fixed double logging of failed responses * Swallow logging of exceptions when the `ignore` is specified * Fixed the bug with `nil` value of `retry_on_status` ### API * Added the "Field Capabilities" API * Changed, that the YAML test content is not printed unless `DEBUG` is set * Fixed the failing unit tests for "Scroll" APIs * Added missing parameters to the "Search" API * Added missing parameters to the "Multi Search" API * Added missing parameters to the "Indices Clear Cache" API * Added missing arguments to the "Exists" API * Fixes for the "Scroll" API * Improved the YAML test runner ## 5.0.3 ### Client * Added proper handling of headers in client options to the Manticore adapter ## 5.0.2 ### Client * Added default value 'application/json' for the 'Content-Type' header ## 5.0.0 ### API * Updated the parameters for Elasticsearch 5.x APIs * Added Elasticsearch 5.x APIs ## EXT:0.0.27 * Allow passing the Elasticsearch version to the Test::Cluster extension * Improved the profiling extension * Added that the timeout in `__determine_version` is configurable and increased the default value * Improved the integration test for the `Test::Cluster` extension * Improved the test infrastructure * Added the Elasticsearch start command for the 6.x version to the test/cluster extension * Added the "oj" and "patron" Rubygem to the list of runtime dependencies ## DSL:0.1.5 * Added support for the ["Exists" Query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-exists-query.html) * Added missing `like` and `unlike` options to the ["More Like This" Query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html) * Added missing `time_zone` option to the ["Query String" Query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html) * Added missing `inner_hits` option to the [Nested Query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html) * Allow calling the `filter` method for the [Bool Query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html) multiple times * Added missing `minimum_should_match`, `prefix_length`, `max_expansions`, `fuzzy_rewrite`, `analyzer`, `lenient`, `zero_terms_query` and `cutoff_frequency` options to the [Match Query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html) * Added missing `minimum_should_match` and `boost` options to the [Bool Query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html) * Refactored the [Aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html) collection into its own `AggregationsCollection` class ## EXT:0.0.23 * Fixed removing the data directory for Elasticsearch 5 and 6 in the test cluster * Added, that Elasticsearch process is properly killed when determining version * Updated the test cluster class to be compatible Elasticsearch 6.x * Added `the max_local_storage_nodes` setting to the start command arguments for Elasticsearch 5.x * Improved the documentation and error messsages for the test cluster * Updated the "Reindex" extension for Elasticsearch 5.x ## 1.1.3 ### Client * Fixed MRI 2.4 compatibility for 1.x * Fixed failing integration test for keeping existing collections ## 1.1.0 ### API * Added deprecation notices to API methods and arguments not supported on Elasticsearch 1.x ## 2.0.2 ### Client * * Fixed the bug with `nil` value of `retry_on_status` ### API * * Added, that `_all` is used as default index in "Search Exists" API * * Added, that `index` and `type` parameters are respected in the "Search Exists" API ## EXT:2.0.2 * * Updated the `Test::Cluster` extension ## 2.0.0 * Added deprecation notices to API methods and parameters not supported on Elasticsearch 2.x ## DSL:0.1.4 * Added correct implementation of `Sort#empty?` * Added the `filter` method to the Bool query * Added the pipeline aggregations * Allowed access to calling context from search block ## EXT:0.0.22 * Refactored and significantly improved the "Reindex" extension * Refactored and improved the `Extensions::Test::Cluster` extension ## 1.0.18 * Fixed the incorrect Rake dependency on Ruby 1.8 and updated the Rake dependency to 11.1 * Simplified the main README and added the information about the DSL and Watcher libraries ### API * Added `ignore: 404` to integration test setup blocks * Added options to the "Indices Get" and "Indices Flush Synced" APIs * Added the "Cat Tasks", "Cluster Stats", "Explain allocation", "Ingest", "Reindex" and "Update By Query" APIs * Added the `:terminate_after` parameter to the "Search" API * Added the `:timeout` option to the Nodes "Hot Threads", "Info" and "Stats" APIs * Added the `:timeout` parameter to the Nodes "Hot Threads", "Info" and "Stats" APIs * Added the `:verbose` option to the "Indices Segments" API and fixed formatting * Added the `explain` option to the "Analyze" API * Added the `filter` parameter for the "Indices Analyze" API * Added the `group_by` option to the "Tasks List" API * Added the `include_defaults` option to the "Get Cluster Settings" API * Added the `include_defaults` parameter to the "Indices" APIs * Added the `preserve_existing` option to the "Indices Put Settings" API * Added the `request_cache` parameter to the "Search" API * Added the `retry_failed` option to the "Cluster Reroute" API * Added the `size` parameter to the "Cat Thread Pool" API * Added the `update_all_types` parameter to "Indices Create" and "Indices Put Mapping" APIs * Added the parameters for ingest nodes into the "Bulk" and "Index" APIs * Fixes and improvements of handling the API method parameters * Changed, that the "Ping" API returns false also on connection errors (server "not reachable") * Added a `Utils.__report_unsupported_method` and `Utils.__report_unsupported_parameters` methods ### Client * Fixed, that the clients tries to deserialize an empty body * Fixed, that dead connections have not been removed during reloading, leading to leaks ## EXT:0.0.21 * Improved the documentation for the "Backup" extension and added it to the main README * Added the information about the "Reindex" extension to the README * Added a reindex extension * Improved the `Elasticsearch::Extensions::Test::Cluster` extension ## 1.0.17 ### Client * Fixed, that existing connections are not re-initialized during reloading ("sniffing") ## 1.0.16 * Added notes about ES 2.x compatibility * Fixes and updates to the Travis CI configuration * Updated the `elasticsearch:build` Rake task ### API * Added the ability to set a custom JSON serializer * Added, that`fields` and `fielddata_fields` in the Search API are not escaped * Fixed the incorrect handling of `:data` keys in the Utils#__bulkify method * Added fixes to suppress warnings in the verbose mode * Added support for new Cat API calls ### Client * Added, that username and password is automatically escaped in the URL * Changed, that the password is replaced with `*` characters in the log * Bumped the "manticore" gem dependency to 0.5 * Improved the thread-safety of reloading connections * Improved the Manticore HTTP client * Fixed, that connections are reloaded _before_ getting a connection * Added a better interface for configuring global HTTP settings such as protocol or authentication ## DSL:0.1.3 * Changed, that `global` aggregation takes a block * Updated the README example to work with Elasticsearch 2.x * Improved the documentation and integration tests for inner (nested) aggregaation * Added the option method `field` and `script` to the "stats" aggregation ## EXT:0.0.20 * Fixed the implementation of keeping the test cluster data and state around between restarts ## 1.0.15 * Updated the Travis CI configuration ### API * Added `bytes` as a valid parameter to "Shards" and "Segments" Cat API * Added support for the `local` argument in the "Get Warmer" API * Added support for `fields` argument in the "Get Field Mapping" API * Fixed an error in the YAML runner handling of ENV['TEST_CLUSTER_PARAMS'] * Validate and extract params from indices.get_warmer arguments ### Client * Added the option to configure the Faraday adapter using a block and the relevant documentation * Added information about configuring the client for the Amazon Elasticsearch Service * Added the `retry_on_status` option to retry on specific HTTP response statuses * Changed, that transports can close connections during `__rebuild_connections` * Added, that the Manticore adapter closes connections during reload ("sniffing") ## 1.0.14 * Clarified version support of Elasticsearch * Improved the `elasticsearch:build` Rake task to work with branch names ### API * Added support for the `:ignore` option to the "Snapshot and Restore" API * Added support for the `:ignore` option to the Status API * Added the "Cat Nodeattrs" API * Added the "fields" parameter to the Bulk API * Added the "Render Search Template" API * Added the "Shard Stores" API * Added, that document ID is URL-escaped when percolating an existing document * Allow passing TEST_CLUSTER_PARAMS to the test cluster * Define the path to core REST tests dynamically based on Elasticsearch version * Fixed example in "Get Warmer" API * Fixed incorrect documentation and link in the "Clear Cache" API * Fixed integration tests for the "Snapshot and Restore" API * Fixed the incorrect path in "Field Stats" API and added support for the `body` argument * Fixed, that `type` is not added both to path and URL parameters in the Bulk API * Updated the examples in README and documentation (facets -> aggregations) ### Client * Added an argument to control clearing out the testing cluster * Fixed, that reloading connections works with SSL, authentication and proxy/Shield * Highlight the need to set `retry_on_failure` option with multiple hosts in documentation ## DSL:0.1.2 * Added fuzziness option to the "Match" query * Added the `format` option to range filter and query * Added, that `*args` are passed to the Options initializer ## EXT:0.0.19 * Added `es.path.repo` to the testing cluster * Added `path_logs` option to test cluster * Added the `testattr` attribute to the testing cluster * Changed the default network host for the testing cluster to "localhost", to enable new "multicast" ## 1.0.13 ### Client * Added, that connection reloading supports Elasticsearch 2.0 output * Improved thread safety in parts of connection handling code ## DSL:1.0.1 * Added additional option methods to the "Multi Match" query ## 1.0.12 ### API * Fixed a regression when rescuing NotFound errors ## 1.0.11 * Fixed incorrect Hash syntax for Ruby 1.8 in client.rb ## 1.0.10 ### Client * Cleaned up handling the `reload_connections` option for transport * Be more defensive when logging exception * Added, that the Manticore transport respects the `transport_options` argument * Added a top level `request_timeout` argument ### API * Added the "Indices Seal" API * Added unified/centralized `NotFound` error handling ### Watcher * Added the integration with Elasticsearch Watcher plugin ## 1.0.9 * Improved the `elasticsearch::build` task in the main Rakefile * Merged the 'elasticsearch-dsl' gem into the main repository ### Client * Changed the argument compatibility check in `__extract_hosts()` from `respond_to?` to `is_a?` * Document the DEFAULT_MAX_RETRIES value for `retry_on_failure` * Leave only Typhoeus as the primary example of automatically detected & used HTTP library in README * Make sure the `connections` object is an instance of Collection * Prevent mutating the parameter passed to __extract_hosts() method * Removed the `ipv4` resolve mode setting in the Curb adapter * Update Manticore to utilize new SSL settings * Updated the Curb integration test to not fail on older Elasticsearch versions ### API * Added `_source_transform` to the list of permitted parameters * Added extra valid arguments to "Count" and "Validate Query" APIs * Improved and extended the YAML integration test suite runner * Added extra valida parameters to various APIs * Added the "Cat Plugins", "Field Stats" and "Search Exists" APIs * Changed, that `:body` parameter is preferred in the "Scroll" and "Clear Scroll" APIs * Changed, that predicate method variants are used in RDoc code examples * Fixed spelling mistakes in the documentation ### DSL * Added the `elasticsearch-dsl` gem ## 1.0.8 * Fixed incorrect dependency specification in the "elasticsearch" wrapper gem ## EXT:0.0.18 * Removed the deprecated options for launching the test cluster * Added removing the data folder for `cluster_name` to make sure the testing cluster starts green * Make sure the `cluster_name` argument is not empty/dangerous in test cluster launcher * Changed, that test cluster is stopped with `INT` rather than `KILL` signal ## 1.0.7 ### Client * Fixed, that the Curb transport passes the `selector_class` option * Added handling the `::Curl::Err::TimeoutError` exception for Curb transport * Reworded information about authentication and added example for using SSL certificates * Added information about the `ELASTICSEARCH_URL` environment variable to the README * Allow passing multiple URLs separated by a comma to the client * Fixed an error where passing `host: { ... }` resulted in error in Client#__extract_hosts ### API * Fixed incorrect escaping of multiple indices in the "Put Alias" API * Changed the "Scroll" and "Clear Scroll" APIs to send `scroll_id` in the body * Updated and fixed the `termvectors` API * Added the `query_cache` URL parameter to the Search API * Changed frequently used strings into constants * Removed the "activesupport" development dependency to prevent test error on Ruby 1.8 * Added the "Cat Segments" API * Updated the code and documentation for the "Cluster State" API * Fixed incorrect examples for the "Percolate" API * Added a `Elasticsearch::API.settings` method for accessing module settings * Added a `Elasticsearch::API.settings[:skip_parameter_validation]` setting support into `__validate_and_extract_params` * Added `master_timeout` parameters to the "Template Exists" and "Get Template" APIs * Fixed incorrect encoding of Array parameters * Added support for the `metric` parameter in the "Nodes Info" API * Added the skip features to the YAML test runner (stash_in_path,requires_replica) * Fixed the Ruby 1.8-incompatible syntax in the "Nodes Info" API * Added question mark versions for predicate methods * Added, that `indices.delete` accepts the `:ignore` parameter ### Various * Changed the way elasticsearch/elasticsearch repository is embedded * Added the `setup` Rake task * Added chapter about development to the READMEs * Added the "test-unit" gem for Ruby 2.2 * Fixed the `elasticsearch:build` Rake task ## EXT:0.0.17 ### Extensions * Improved the aesthetics and robustness of the `Test::Cluster#__print_cluster_info` method * Removed the dependency on the "Backup" gem (using mocks in tests) ## EXT:0.0.16 ### Extensions * Disabled `allocation.disk.threshold_enabled` in the testing cluster to prevent tests failing due to low disk space * Increased the default logging level for the testing cluster to `DEBUG` * Added basic integration with the Backup gem * Changed, that `wait_for_green` timeout is configurable with an environment variable ## 1.0.6 ### Client * Added Manticore transport for JRuby platforms * Fixed, that `ServerError` inherits from `Transport::Error` * Fix problems with gems on JRuby * Added the `send_get_body_as` setting ### API * Added the "Verify Snapshot" API * Added the "Upgrade Index" API * Added support for the `realtime` parameter to the Term Vectors APIs * Fixed `delete_by_query` example in documentation * Added the support for `metric` URL parameter to the "Reroute" API * Added the "Get Indices Info" API * Added support for versioning for the "Put Script" and "Delete Script" APIs ### Extensions * Added, that `wait_for_green` timeout for test cluster is configurable with environment variable ### Various * Added Ruby 2.0.0 and updated 2.1 build specification in the Travis configuration ## 1.0.5 ### Client * Added support for automatically connecting to cluster set in the ELASTICSEARCH_URL environment variable * Improved documentation ### API * Added the `flat_settings` and `local` parameters to the "Get Template" API ## 1.0.4 ### Client * Updated the parameters list for APIs (percolate, put index) * Updated the "Indices Stats" API * Improved the `__extract_parts` utility method ### API * Fixed incorrect instructions for automatically using Typhoeus as the Faraday adapter * Fixed, that the Faraday adapter didn't return a correct object * Added, that the response body is automatically force-encoded to UTF-8 ## 1.0.3 [SKIP] ## 1.0.2 * Improved the `elasticsearch:build` Rake task ### API * Added more examples into the documentation * Added missing parameters to the "Search" API * Added the `force` option to the "Optimize" API * Added support for `version` and `version_type` parameters in the "Get Document" API * Added the "Cat Fielddata", "Recovery", "Search Shards", "Search Template", "Snapshot Status" APIs * Added the `human` parameter to COMMON_QUERY_PARAMS * Updated the "Index Stats" API to the current implementation ### Transport * Added, that error requests are properly logged and traced * Fixed an error where exception was raised too late for error responses ### Extensions * Enabled the "Benchmark" API on the testing cluster * Enabled dynamic scripting by default in the test cluster ----- ## 1.0.1 * Updated 0.90/1.0 compatibility notice * Many improvements for the continuous integration (Travis, Jenkins) * Improved documentation ### API * Added the "explain" parameter for `cluster.reroute` ### Transport * Added auto-detection for Faraday adapter from loaded Rubygems ### Extensions * Improved the documentation for `Elasticsearch::Extensions::Test::Cluster` elastic-elasticsearch-ruby-c38be0c/CONTRIBUTING.md000066400000000000000000000022451462737751600216740ustar00rootroot00000000000000The process for contributing to any of the [Elasticsearch](https://github.com/elasticsearch) repositories is similar: 1. It is best to do your work in a separate Git branch. This makes it easier to synchronise your changes with [`rebase`](http://mislav.uniqpath.com/2013/02/merge-vs-rebase/). 2. Make sure your changes don't break any existing tests, and that you add tests for both bugfixes and new functionality. Examine the coverage report generated by running `COVERAGE=true rake test:all`. 3. **Sign the contributor license agreement.** Please make sure you have signed the [Contributor License Agreement](https://www.elastic.co/contributor-agreement/). We are not asking you to assign copyright to us, but to give us the right to distribute your code without restriction. We ask this of all contributors in order to assure our users of the origin and continuing existence of the code. You only need to sign the CLA once. 4. Submit a pull request. Push your local changes to your forked copy of the repository and submit a pull request. In the pull request, describe what your changes do and mention the number of the issue where discussion has taken place, eg “Closes #123″. elastic-elasticsearch-ruby-c38be0c/Gemfile000066400000000000000000000027701462737751600207410ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. source 'https://rubygems.org' gem 'elasticsearch-api', path: File.expand_path('../elasticsearch-api', __FILE__), require: false gem 'elasticsearch-transport', path: File.expand_path('../elasticsearch-transport', __FILE__), require: false gem 'elasticsearch-extensions', path: File.expand_path('../elasticsearch-extensions', __FILE__), require: false gem 'elasticsearch', path: File.expand_path('../elasticsearch', __FILE__), require: false gem 'ansi' gem 'cane' gem 'mocha' gem 'pry' gem 'rake' gem 'require-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius) gem 'ruby-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius) gem 'shoulda-context' gem 'simplecov' gem 'test-unit', '~> 2' gem 'yard' elastic-elasticsearch-ruby-c38be0c/LICENSE000066400000000000000000000261361462737751600204550ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. elastic-elasticsearch-ruby-c38be0c/README.md000066400000000000000000000136141462737751600207240ustar00rootroot00000000000000# Elasticsearch This repository contains Ruby integrations for [Elasticsearch](https://www.elastic.co/products/elasticsearch). [![7.17](https://github.com/elastic/elasticsearch-ruby/actions/workflows/7.17.yml/badge.svg?branch=7.17)](https://github.com/elastic/elasticsearch-ruby/actions/workflows/7.17.yml) [![main](https://github.com/elastic/elasticsearch-ruby/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/elastic/elasticsearch-ruby/actions/workflows/main.yml) [![Code Climate](https://codeclimate.com/github/elastic/elasticsearch-ruby/badges/gpa.svg)](https://codeclimate.com/github/elastic/elasticsearch-ruby) The [`elasticsearch`](https://github.com/elasticsearch/elasticsearch-ruby/tree/master/elasticsearch) library is a wrapper for two separate libraries: * [`elasticsearch-transport`](https://github.com/elasticsearch/elasticsearch-ruby/tree/master/elasticsearch-transport), which provides a low-level Ruby client for connecting to an Elasticsearch cluster * [`elasticsearch-api`](https://github.com/elasticsearch/elasticsearch-ruby/tree/master/elasticsearch-api), which provides a Ruby API for the Elasticsearch RESTful API ```ruby require 'elasticsearch' client = Elasticsearch::Client.new log: true # if you specify Elasticsearch host # client = Elasticsearch::Client.new url: 'http://localhost:9200', log: true client.transport.reload_connections! client.cluster.health client.search q: 'test' # etc. ``` Both of these libraries are extensively documented. **Please read the [`elasticsearch-transport`](http://rubydoc.info/gems/elasticsearch-transport) and the [`elasticsearch-api`](http://rubydoc.info/gems/elasticsearch-api) documentation carefully.** See also [`doc/examples`](https://github.com/elastic/elasticsearch-ruby/blob/master/docs/examples/README.md) for some practical examples. **For optimal performance, you should use a HTTP library which supports persistent ("keep-alive") connections, e.g. [Patron](https://github.com/toland/patron) or [Typhoeus](https://github.com/typhoeus/typhoeus).** These libraries are not dependencies of the Elasticsearch gems. Ensure you define a dependency for a HTTP library in your own application. This repository contains these additional Ruby libraries: * [`elasticsearch-extensions`](https://github.com/elastic/elasticsearch-ruby/tree/master/elasticsearch-extensions), which provides a set of extensions to the base library, * [`elasticsearch-dsl`](https://github.com/elastic/elasticsearch-ruby/tree/master/elasticsearch-dsl), which provides a Ruby API for the [Elasticsearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html), * [`elasticsearch-xpack`](https://github.com/elastic/elasticsearch-ruby/tree/master/elasticsearch-xpack), which provides a Ruby API for X-Pack APIs. This API is going to be merged into `elasticsearch-api` on v8.0. Please see their respective READMEs for information and documentation. For integration with Ruby models and Rails applications, see the **[elasticsearch-rails](https://github.com/elasticsearch/elasticsearch-rails)** project. ## Compatibility We follow Ruby’s own maintenance policy and officially support all currently maintained versions per [Ruby Maintenance Branches](https://www.ruby-lang.org/en/downloads/branches/). Language clients are forward compatible; meaning that clients support communicating with greater or equal minor versions of Elasticsearch. Elasticsearch language clients are only backwards compatible with default distributions and without guarantees made. ## Installation Install the `elasticsearch` package from [Rubygems](https://rubygems.org/gems/elasticsearch): gem install elasticsearch To use an unreleased version, either add it to your `Gemfile` for [Bundler](http://gembundler.com): gem 'elasticsearch', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git' or install it from a source code checkout: git clone https://github.com/elasticsearch/elasticsearch-ruby.git cd elasticsearch-ruby/elasticsearch bundle install rake install ## Development To work on the code, clone and bootstrap the project first: ``` git clone https://github.com/elasticsearch/elasticsearch-ruby.git cd elasticsearch-ruby/ bundle exec rake setup bundle exec rake bundle ``` This will clone the Elasticsearch repository into the project, and run `bundle install` in all subprojects. There are a few tasks to work with Elasticsearch. Use `rake -T` and look for the tasks in the `elasticsearch` namespace. You can build elasticsearch with `rake elasticsearch:build` after having ran setup. To run tests, you need to start a testing cluster on port 9250, or provide a different one in the `TEST_CLUSTER_PORT` environment variable. There's a Rake task to start a testing cluster in a Docker container: `rake docker:start[version]` - E.g.: `rake docker:start[7.x-SNAPSHOT]`. To start the container with X-Pack, pass it in as a parameter: `rake docker:start[7.x-SNAPSHOT,xpack]`. To run tests against unreleased Elasticsearch versions, you can use the `rake elasticsearch:build` Rake task to build Elasticsearch from the cloned source (use `rake elasticsearch:update` to update the repository): **Note:** If you have gems from the `elasticsearch` family installed system-wide, and want to use development ones, prepend the command with `bundle exec`. ``` rake elasticsearch:build ``` This is going to create the build in `./tmp/builds/`. You can pass a branch name (tag, commit, ...) as the Rake task variable: ``` rake elasticsearch:build[origin/1.x] ``` To run all the tests in all the subprojects, use the Rake task: ``` time rake test:client ``` By default, tests will atempt to use `http://localhost:9200` as a test server. If you're using a different host/port, set the `TEST_ES_SERVER` environment variable, e.g.: ``` $ TEST_ES_SERVER='http://localhost:9250' be rake test:client ``` ## License This software is licensed under the [Apache 2 license](./LICENSE). elastic-elasticsearch-ruby-c38be0c/Rakefile000066400000000000000000000111041462737751600211020ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # Admin client is used by tests and other rake tasks to communicate with a running cluster. def admin_client $admin_client ||= begin transport_options = {} test_suite = ENV['TEST_SUITE'].freeze if (hosts = ENV['TEST_ES_SERVER'] || ENV['ELASTICSEARCH_HOSTS']) split_hosts = hosts.split(',').map do |host| /(http\:\/\/)?\S+/.match(host) end uri = URI.parse(split_hosts.first[0]) end if test_suite == 'platinum' transport_options.merge!( ssl: { verify: false, ca_path: CERT_DIR } ) password = ENV['ELASTIC_PASSWORD'] || 'changeme' user = ENV['ELASTIC_USER'] || 'elastic' url = "https://#{user}:#{password}@#{uri.host}:#{uri.port}" elsif ENV['STACK_VERSION'] == '8.0.0-SNAPSHOT' password = ENV['ELASTIC_PASSWORD'] user = ENV['ELASTIC_USER'] || 'elastic' url = "http://#{user}:#{password}@#{uri.host}:#{uri.port}" else url = "http://#{uri&.host || 'localhost'}:#{uri&.port || 9200}" end puts "Elasticsearch Client url: #{url}" Elasticsearch::Client.new(host: url, transport_options: transport_options) end end import 'rake_tasks/elasticsearch_tasks.rake' import 'rake_tasks/test_tasks.rake' import 'rake_tasks/docker_tasks.rake' import 'rake_tasks/update_version.rake' import 'profile/benchmarking/benchmarking_tasks.rake' require 'pathname' CURRENT_PATH = Pathname(File.expand_path(__dir__)) SUBPROJECTS = [ 'elasticsearch', 'elasticsearch-transport', 'elasticsearch-api', 'elasticsearch-xpack' ].freeze RELEASE_TOGETHER = [ 'elasticsearch', 'elasticsearch-transport', 'elasticsearch-api', 'elasticsearch-xpack' ].freeze CERT_DIR = ENV['CERT_DIR'] || '.ci/certs' # Import build task after setting constants: import 'rake_tasks/unified_release_tasks.rake' # TODO: Figure out "bundle exec or not" # subprojects.each { |project| $LOAD_PATH.unshift CURRENT_PATH.join(project, "lib").to_s } task :default do system 'rake --tasks' end desc "Display information about subprojects" task :subprojects do puts '-' * 80 SUBPROJECTS.each do |project| commit = `git log --pretty=format:'%h %ar: %s' -1 #{project}` version = Gem::Specification::load(CURRENT_PATH.join(project, "#{project}.gemspec").to_s).version.to_s puts "#{version}".ljust(10) + "| \e[1m#{project.ljust(SUBPROJECTS.map {|s| s.length}.max)}\e[0m | #{commit[ 0..80]}..." end end desc "Alias for `bundle:install`" task :bundle => 'bundle:install' namespace :bundle do desc "Run `bundle install` in all subprojects" task :install do SUBPROJECTS.each do |project| puts '-' * 80 sh "cd #{CURRENT_PATH.join(project)} && unset BUNDLE_GEMFILE && bundle install --quiet" puts end end desc "Remove Gemfile.lock in all subprojects" task :clean do SUBPROJECTS.each do |project| sh "rm -f #{CURRENT_PATH.join(project)}/Gemfile.lock" end end end desc "Generate documentation for all subprojects" task :doc do SUBPROJECTS.each do |project| sh "cd #{CURRENT_PATH.join(project)} && rake doc" puts '-'*80 end end desc "Release all subprojects to Rubygems" task :release do RELEASE_TOGETHER.each do |project| next if project == 'elasticsearch-extensions' sh "cd #{CURRENT_PATH.join(project)} && bundle exec rake release" puts '-' * 80 end end elastic-elasticsearch-ruby-c38be0c/api-spec-testing/000077500000000000000000000000001462737751600226145ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/api-spec-testing/README.md000066400000000000000000000111371462737751600240760ustar00rootroot00000000000000# Rest API YAML Test Runner The specs in `elasticsearch-api` and `elasticsearch-xpack` automatically run the tests from [Elasticsearch's REST API Spec tests](https://github.com/elastic/elasticsearch/tree/master/rest-api-spec/src/main/resources/rest-api-spec/test#test-suite). The test runner is defined in each of these project's `spec` folder, starting with the `rest_api_yaml_spec.rb` file. ## REST API YAML Spec The file that traverses the yaml files and loads a **TestFile** object per each of them: `elasticsearch-(api|xpack)/spec/elasticsearch/api/rest_api_yaml_spec.rb` You can use the SINGLE_TEST env variable to run just one test or one test directory. E.g.: ``` $ cd elasticsearch-api && SINGLE_TEST=indices.resolve_index/10_basic_resolve_index.yml TEST_ES_SERVER='http://localhost:9200' be rake test:rest_api ``` And: ``` $ cd elasticsearch-api && SINGLE_TEST=indices.resolve_index TEST_ES_SERVER='http://localhost:9200' be rake test:rest_api ``` ## Skipped tests We sometimes skip tests, generally due to limitations on how we run the CI server or for stuff that hasn't been completely implemented on the client yet. Skipped tests are located in `elasticsearch-(api|xpack)/spec/skipped_tests.yml`. You can run just the tests which are currently being skipped by running: ``` $ cd elasticsearch-api && RUN_SKIPPED_TESTS=true TEST_ES_SERVER='http://localhost:9200' be rake test:rest_api ``` Or ``` $ cd elasticsearch-xpack && RUN_SKIPPED_TESTS=true ELASTIC_PASSWORD=changeme TEST_SUITE=platinum TEST_ES_SERVER='http://localhost:9200' be rake test:rest_api ``` ## TestFile Class representing a single test file. Contains setup, teardown and tests. `../api-spec-testing/test_file.rb` ## Test Every single test in the test file is represented in the Test object. `../api-spec-testing/test_file/test.rb` ## TaskGroup Tests are ordered in task groups, an array of TaskGroup objects. `../api-spec-testing/test_file/task_group.rb` Task Groups are a representation of a block of actions consisting of 'do' actions and their verifications. e.g.: ```yaml - do: index: index: test-index id: 1 body: { foo: bar } - match: { _index: test-index } - match: { _id: "1"} - match: { _version: 1} ``` **Before** each test, the spec runner runs `clear_data` on the test_file. This clears indices, index templates, snapshots and repositories. For xpack it also clears roles, users, privileges, datafeeds, ml_jobs and more. **After** each test, it runs the test file teardown and `clear_data` again. For each TaskGroup, it sees what's in the task group definition and runs an expectation test. ## Action This file is where the action is executed, where we call the client with the method from the test and save the response which is then used in the task group. ## Rest YAML tests Helper `elasticsearch-(api|xpack)/spec/rest_yaml_tests_helper.rb` - `ADMIN_CLIENT` is defined here. - `SINGLE_TEST` is defined here. - Skipped tests are listed here ## Spec Helper - `DEFAULT_CLIENT` is defined here ## Enable Logging To enable logging, set the environment `QUIET` to false before running the tests. In CI, this is located in the [Dockerfile](https://github.com/elastic/elasticsearch-ruby/blob/master/.ci/Dockerfile). The environment variable is evaluated in the Rest YAML tests Helper file. # Features ## RSpec Matchers The tests use custom [RSpec Matchers](https://www.rubydoc.info/gems/rspec-expectations/RSpec/Matchers) defined in `api-spec-testing/rspec_matchers.rb`. From the [Rest API test docs](https://github.com/elastic/elasticsearch/tree/master/rest-api-spec/src/main/resources/rest-api-spec/test#do): ## `catch` > If the arguments to `do` include `catch`, then we are expecting an error, which should be caught and tested. In `rest_api_yaml_spec`, there's a check for `catch_exception?` per task_group. This checks if the `do` definitions have any `catch` definitions. If there is a `catch`, it'll send the request and use the `match_error` RSpec custom matcher to validate the expected error. ## `warnings` >If the arguments to `do` include `warnings` then we are expecting a Warning header to come back from the request. If the arguments don’t include a warnings argument then we don’t expect the response to include a Warning header. The warnings must match exactly. Using it looks like this: ``` - do: warnings: - '[index] is deprecated' - quotes are not required because yaml - but this argument is always a list, never a single string - no matter how many warnings you expect get: index: test type: test id: 1 ``` elastic-elasticsearch-ruby-c38be0c/api-spec-testing/logging.rb000066400000000000000000000016611462737751600245730ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'logger' module Elasticsearch module RestAPIYAMLTests module Logging def logger @logger ||= Logger.new($stdout) end end end end elastic-elasticsearch-ruby-c38be0c/api-spec-testing/rspec_matchers.rb000066400000000000000000000241171462737751600261500ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # Match the `length` of a field. RSpec::Matchers.define :match_response_field_length do |expected_pairs, test| match do |response| expected_pairs.all? do |expected_key, expected_value| # ssl test returns results at '$body' key. See ssl/10_basic.yml expected_pairs = expected_pairs['$body'] if expected_pairs['$body'] split_key = TestFile::Test.split_and_parse_key(expected_key).collect do |k| test.get_cached_value(k) end actual_value = split_key.inject(response) do |_response, key| # If the key is an index, indicating element of a list if _response.empty? && key == '$body' _response else _response[key] || _response[key.to_s] end end actual_value.size == expected_value end end end # Validate that a field is `true`. RSpec::Matchers.define :match_true_field do |field, test| match do |response| # Handle is_true: '' return !!response if field == '' split_key = TestFile::Test.split_and_parse_key(field).collect do |k| test.get_cached_value(k) end !!TestFile::Test.find_value_in_document(split_key, response) end end # Validate that a field is `false`. RSpec::Matchers.define :match_false_field do |field, test| match do |response| # Handle is_false: '' return !response if field == '' split_key = TestFile::Test.split_and_parse_key(field).collect do |k| test.get_cached_value(k) end value_in_doc = TestFile::Test.find_value_in_document(split_key, response) value_in_doc == 0 || !value_in_doc end end # Validate that a field is `gte` than a given value. RSpec::Matchers.define :match_gte_field do |expected_pairs, test| match do |response| expected_pairs.all? do |expected_key, expected_value| split_key = TestFile::Test.split_and_parse_key(expected_key).collect do |k| test.get_cached_value(k) end actual_value = split_key.inject(response) do |_response, key| # If the key is an index, indicating element of a list if _response.empty? && key == '$body' _response else _response[key] || _response[key] end end actual_value >= test.get_cached_value(expected_value) end end end # Validate that a field is `gt` than a given value. RSpec::Matchers.define :match_gt_field do |expected_pairs, test| match do |response| expected_pairs.all? do |expected_key, expected_value| split_key = TestFile::Test.split_and_parse_key(expected_key).collect do |k| test.get_cached_value(k) end actual_value = split_key.inject(response) do |_response, key| # If the key is an index, indicating element of a list if _response.empty? && key == '$body' _response else _response[key] || _response[key.to_s] end end actual_value > test.get_cached_value(expected_value) end end end # Validate that a field is `lte` than a given value. RSpec::Matchers.define :match_lte_field do |expected_pairs, test| match do |response| expected_pairs.all? do |expected_key, expected_value| split_key = TestFile::Test.split_and_parse_key(expected_key).collect do |k| test.get_cached_value(k) end actual_value = split_key.inject(response) do |_response, key| # If the key is an index, indicating element of a list if _response.empty? && key == '$body' _response else _response[key] || _response[key.to_s] end end actual_value <= test.get_cached_value(expected_value) end end end # Validate that a field is `lt` than a given value. RSpec::Matchers.define :match_lt_field do |expected_pairs, test| match do |response| expected_pairs.all? do |expected_key, expected_value| split_key = TestFile::Test.split_and_parse_key(expected_key).collect do |k| test.get_cached_value(k) end actual_value = split_key.inject(response) do |_response, key| # If the key is an index, indicating element of a list if _response.empty? && key == '$body' _response else _response[key] || _response[key.to_s] end end actual_value < test.get_cached_value(expected_value) end end end # Match an arbitrary field of a response to a given value. RSpec::Matchers.define :match_response do |pairs, test| match do |response| pairs = sanitize_pairs(pairs) compare_pairs(pairs, response, test).empty? end failure_message do |response| "the expected response pair/value(s) #{@mismatched_pairs}" + " does not match the pair/value(s) in the response #{response}" end def sanitize_pairs(expected_pairs) # sql test returns results at '$body' key. See sql/translate.yml @pairs ||= expected_pairs['$body'] ? expected_pairs['$body'] : expected_pairs end def compare_pairs(expected_pairs, response, test) @mismatched_pairs = {} if expected_pairs.is_a?(String) @mismatched_pairs = expected_pairs unless compare_string_response(expected_pairs, response) else compare_hash(expected_pairs, response, test) end @mismatched_pairs end def compare_hash(expected_pairs, actual_hash, test) expected_pairs.each do |expected_key, expected_value| # Find the value to compare in the response split_key = TestFile::Test.split_and_parse_key(expected_key).collect do |k| # Sometimes the expected *key* is a cached value from a previous request. test.get_cached_value(k) end # We now accept 'nested.keys' so let's try the previous implementation and if that doesn't # work, try with the nested key, otherwise, raise exception. begin actual_value = TestFile::Test.find_value_in_document(split_key, actual_hash) rescue TypeError => e actual_value = TestFile::Test.find_value_in_document(expected_key, actual_hash) rescue StandardError => e raise e end # When the expected_key is '' actual_value = actual_hash if split_key.empty? # Sometimes the key includes dots. See watcher/put_watch/60_put_watch_with_action_condition.yml actual_value = TestFile::Test.find_value_in_document(expected_key, actual_hash) if actual_value.nil? # Sometimes the expected *value* is a cached value from a previous request. # See test api_key/10_basic.yml expected_value = test.get_cached_value(expected_value) case expected_value when Hash compare_hash(expected_value, actual_value, test) when Array unless compare_array(expected_value, actual_value, test, actual_hash) @mismatched_pairs.merge!(expected_key => expected_value) end when String unless compare_string(expected_value, actual_value, test, actual_hash) @mismatched_pairs.merge!(expected_key => expected_value) end else unless expected_value == actual_value @mismatched_pairs.merge!(expected_key => expected_value) end end end end def compare_string(expected, actual_value, test, response) # When you must match a regex. For example: # match: {task: '/.+:\d+/'} if expected[0] == '/' && expected[-1] == '/' parsed = expected expected.scan(/\$\{([a-z_0-9]+)\}/) do |match| parsed = parsed.gsub(/\$\{?#{match.first}\}?/, test.cached_values[match.first]) end /#{parsed.tr("/", "")}/ =~ actual_value elsif !!(expected.match?(/^-?[0-9]{1}\.[0-9]+E[0-9]+/)) # When the value in the yaml test is a big number, the format is # different from what Ruby uses, so we transform X.XXXXEXX to X.XXXXXe+XX # to be able to compare the values actual_value.to_s == expected.gsub('E', 'e+') elsif expected == '' && actual_value != '' actual_value == response else expected == actual_value end end def compare_array(expected, actual, test, response) expected.each_with_index do |value, i| case value when Hash return false unless compare_hash(value, actual[i], test) when Array return false unless compare_array(value, actual[i], test, response) when String return false unless compare_string(value, actual[i], test, response) end end end def compare_string_response(expected_string, response) regexp = Regexp.new(expected_string.strip[1..-2], Regexp::EXTENDED|Regexp::MULTILINE) regexp =~ response end end # Match that a request returned a given error. RSpec::Matchers.define :match_error do |expected_error| match do |actual_error| # Remove surrounding '/' in string representing Regex expected_error = expected_error.chomp("/") expected_error = expected_error[1..-1] if expected_error =~ /^\// message = actual_error.message.tr("\\","") case expected_error when 'request_timeout' message =~ /\[408\]/ when 'missing' message =~ /\[404\]/ when 'conflict' message =~ /\[409\]/ when 'request' message =~ /\[500\]/ when 'bad_request' message =~ /\[400\]/ when 'param' message =~ /\[400\]/ || actual_error.is_a?(ArgumentError) when 'unauthorized' actual_error.is_a?(Elasticsearch::Transport::Transport::Errors::Unauthorized) when 'forbidden' actual_error.is_a?(Elasticsearch::Transport::Transport::Errors::Forbidden) else message =~ /#{expected_error}/ end end end elastic-elasticsearch-ruby-c38be0c/api-spec-testing/test_file.rb000066400000000000000000000133401462737751600251200ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require_relative 'test_file/action' require_relative 'test_file/test' require_relative 'test_file/task_group' require 'logger' module Elasticsearch module RestAPIYAMLTests # Custom exception to raise when a test file needs to be skipped. This is # captured as soon as possible so the test runners can move on to the next test. class SkipTestsException < StandardError end # Class representing a single test file, containing a setup, teardown, and multiple tests. # # @since 6.2.0 class TestFile attr_reader :features_to_skip, :name, :client LOGGER = Logger.new($stdout) # Initialize a single test file. # # @example Create a test file object. # TestFile.new(file_name) # # @param [ String ] file_name The name of the test file. # @param [ Client] An instance of the client # @param [ Array ] skip_features The names of features to skip. # # @since 6.1.0 def initialize(file_name, client, features_to_skip = []) @name = file_name @client = client begin documents = YAML.load_stream(File.new(file_name)) rescue StandardError => e LOGGER.error e LOGGER.error "Filename : #{@name}" end @test_definitions = documents.reject { |doc| doc['setup'] || doc['teardown'] } @setup = documents.find { |doc| doc['setup'] } skip_entire_test_file? if @setup @teardown = documents.find { |doc| doc['teardown'] } @features_to_skip = REST_API_YAML_SKIP_FEATURES + features_to_skip end def skip_entire_test_file? @skip = @setup['setup']&.select { |a| a['skip'] } return false if @skip.empty? raise SkipTestsException if skip_version?(@client, @skip.first['skip']) end def skip_version?(client, skip_definition) return true if skip_definition['version'] == 'all' return unless (versions = skip_definition['version']) begin server_version = client.info['version']['number'] rescue warn('Could not determine Elasticsearch version when checking if test should be skipped.') end range_partition = /\s*-\s*/ if versions.include?(',') # == " - 7.17.3, 8.0.0 - 8.2.99" versions.split(',').each do |version_range| low, high = __parse_versions(version_range.partition(range_partition)) range = low..high return true if range.cover?(Gem::Version.new(server_version)) end else low, high = __parse_versions(versions.partition(range_partition)) range = low..high range.cover?(Gem::Version.new(server_version)) end end def __parse_versions(versions) versions = versions.split('-') if versions.is_a? String low = (['', nil].include? versions[0]) ? '0' : versions[0] high = (['', nil].include? versions[2]) ? '9999' : versions[2] [Gem::Version.new(low), Gem::Version.new(high)] end # Get a list of tests in the test file. # # @example Get the list of tests # test_file.tests # # @return [ Array ] A list of Test objects. # # @since 6.2.0 def tests @test_definitions.collect do |test_definition| Test.new(self, test_definition) end end # Run the setup tasks defined for a single test file. # # @example Run the setup tasks. # test_file.setup # # @param [ Elasticsearch::Client ] client The client to use to perform the setup tasks. # # @return [ self ] # # @since 6.2.0 def setup return unless @setup actions = @setup['setup'].select { |action| action['do'] }.map { |action| Action.new(action['do']) } count = 0 loop do actions.delete_if do |action| begin action.execute(client) true rescue Elasticsearch::Transport::Transport::Errors::ServiceUnavailable => e # The action sometimes gets the cluster in a recovering state, so we # retry a few times and then raise an exception if it's still # happening count += 1 raise e if count > 9 false end end break if actions.empty? end self end # Run the teardown tasks defined for a single test file. # # @example Run the teardown tasks. # test_file.teardown # # @param [ Elasticsearch::Client ] client The client to use to perform the teardown tasks. # # @return [ self ] # # @since 6.2.0 def teardown return unless @teardown actions = @teardown['teardown'].select { |action| action['do'] }.map { |action| Action.new(action['do']) } actions.each { |action| action.execute(client) } self end class << self end end end end elastic-elasticsearch-ruby-c38be0c/api-spec-testing/test_file/000077500000000000000000000000001462737751600245725ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/api-spec-testing/test_file/action.rb000066400000000000000000000145551462737751600264060ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module RestAPIYAMLTests # Class representing a single action. An action is one of the following: # # 1. Applying header settings on a client. # 2. Sending some request to Elasticsearch. # 3. Sending some request to Elasticsearch, expecting an exception. # # @since 6.2.0 class Action attr_reader :response # Initialize an Action object. # # @example Create an action object: # Action.new("xpack.watcher.get_watch" => { "id" => "my_watch" }) # # @param [ Hash ] definition The action definition. # # @since 6.2.0 def initialize(definition) @definition = definition end # Execute the action. The method returns the client, in case the action created a new client # with header settings. # # @example Execute the action. # action.execute(client, test) # # @param [ Elasticsearch::Client ] client The client to use to execute the action. # @param [ Test ] test The test containing this action. Necessary for caching variables. # # @return [ Elasticsearch::Client ] The client. It will be a new one, not the one passed in, # if the action is to set headers. # # @since 6.2.0 def execute(client, test = nil) @definition.each.inject(client) do |client, (method_chain, args)| chain = method_chain.split('.') # If we have a method nested in a namespace, client becomes the # client/namespace. Eg for `indices.resolve_index`, `client = # client.indices` and then we call `resolve_index` on `client`. if chain.size > 1 client = chain[0...-1].inject(client) do |_client, _method| _client.send(_method) end end _method = chain[-1] case _method when 'bulk' arguments = prepare_arguments(args, test) arguments[:body].map! do |item| if item.is_a?(Hash) item elsif item.is_a?(String) symbolize_keys(JSON.parse(item)) end end if arguments[:body].is_a? Array @response = client.send(_method, arguments) client when 'headers' headers = prepare_arguments(args, test) # TODO: Remove Authorization headers while x_pack_rest_user is fixed if headers[:Authorization] == 'Basic eF9wYWNrX3Jlc3RfdXNlcjp4LXBhY2stdGVzdC1wYXNzd29yZA==' headers.delete(:Authorization) end # Stringify keys: headers = headers.transform_keys(&:to_s) if ENV['QUIET'] == 'true' # todo: create a method on Elasticsearch::Client that can clone the client with new options Elasticsearch::Client.new( host: URL, transport_options: TRANSPORT_OPTIONS.merge(headers: headers) ) else Elasticsearch::Client.new( host: URL, tracer: Logger.new($stdout), transport_options: TRANSPORT_OPTIONS.merge(headers: headers) ) end when 'catch', 'warnings', 'allowed_warnings', 'allowed_warnings_regex' client when 'put_trained_model_alias' args.merge!('reassign' => true) unless args['reassign'] == false @response = client.send(_method, prepare_arguments(args, test)) client else @response = client.send(_method, prepare_arguments(args, test)) client end end end def yaml_response? @definition['headers'] && @definition['headers']['Accept'] == 'application/yaml' end private def prepare_arguments(args, test) symbolize_keys(args).tap do |args| if test if args.is_a?(Hash) args.each do |key, value| case value when Hash args[key] = prepare_arguments(value, test) when Array args[key] = value.collect { |v| prepare_arguments(v, test) } when String # Find the cached values where the variable name is contained in the arguments. if(cached_values = test.cached_values.keys.select { |k| value =~ /\$\{?#{k}\}?/ }) cached_values.each do |cached| # Arguments can be $variable, ${variable} or a Hash: retrieved = test.cached_values[cached] if retrieved.is_a?(Hash) value = retrieved else # Regex substitution to replace ${variable} or $variable for the value value.gsub!(/\$\{?#{cached}\}?/, retrieved.to_s) end end args[key] = value end when Time # The YAML parser reads in dates as Time objects, reconvert to a format Elasticsearch accepts args[key] = (value.to_f * 1000).to_i end end elsif args.is_a?(String) if cached_value = test.cached_values.find { |k, v| args =~ /\$\{?#{k}\}?/ } return cached_value[1] end end end end end def symbolize_keys(object) if object.is_a? Hash object.reduce({}) { |memo,(k,v)| memo[k.to_s.to_sym] = symbolize_keys(v); memo } else object end end end end end elastic-elasticsearch-ruby-c38be0c/api-spec-testing/test_file/task_group.rb000066400000000000000000000261471462737751600273070ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module RestAPIYAMLTests class TestFile class Test # Representation of a block of actions consisting of some 'do' actions and their verifications. # # For example, this is a task group: # # - do: # xpack.security.get_role: # name: "admin_role" # - match: { admin_role.cluster.0: "all" } # - match: { admin_role.metadata.key1: "val1" } # - match: { admin_role.metadata.key2: "val2" } # # @since 6.2.0 class TaskGroup attr_reader :exception, :response, :test # Initialize a TaskGroup object. # # @example Create a TaskGroup # TaskGroup.new(test) # # @param [ Test ] test The test this task group is part of. # # @since 6.2.0 def initialize(test) @actions = [] @exception = nil @response = nil @variables = {} @test = test end # Add an action to the task group definition. # # @example Add an action # task_group.add_action(action) # # @param [ Hash ] action The hash representation of an action. # # @return [ self ] # # @since 6.2.0 def add_action(action) @actions << action if ACTIONS.any? { |a| action[a] } self end # Run the actions in the task group. # # @example Run the actions # task_group.run(client) # # @param [ Elasticsearch::Client ] client The client to use to run the actions. # # @return [ self ] # # @since 6.2.0 def run(client) # Allow the actions to be execute only once. return if @executed @executed = true do_actions.inject(client) do |_client, action| action.execute(_client, test) # Cache the result of the action, if a set action is defined. set_variable(action) transform_and_set_variable(action) _client end self rescue => ex raise ex unless catch_exception? # Cache the exception raised as a result of the operation, if the task group has a 'catch' defined. @exception = ex end # Consider the response of interest the one resulting from the last action. # # @return [ Hash ] The response from the last action. # # @since 6.2.0 def response @response ||= begin if do_actions.any? { |a| a.yaml_response? } YAML.load(do_actions[-1].response) else do_actions[-1].response end end end # Does this task group expect to raise an exception for an action? # # @return [ true, false ] If the task group contains an action expected to raise an exception. # # @since 6.2.0 def catch_exception? !!expected_exception_message end # Does this task group have match clauses. # # @return [ true, false ] If the task group has match clauses. # # @since 6.2.0 def has_match_clauses? !!match_clauses end # Does this task group have match clauses on field value length. # # @return [ true, false ] If the task group has match clauses on field value length. # # @since 6.2.0 def has_length_match_clauses? !!length_match_clauses end # Does this task group have match clauses on a field value being true. # # @return [ true, false ] If the task group has match clauses on a field value being true. # # @since 6.2.0 def has_true_clauses? !!true_clauses end # Does this task group have match clauses on a field value being false. # # @return [ true, false ] If the task group has match clauses on a field value being false. # # @since 6.2.0 def has_false_clauses? !!false_clauses end # Does this task group have clauses on a field value being gte. # # @return [ true, false ] If the task group has clauses on a field value being gte. # # @since 6.2.0 def has_gte_clauses? !!gte_clauses end # Does this task group have clauses on a field value being gt. # # @return [ true, false ] If the task group has clauses on a field value being gt. # # @since 6.2.0 def has_gt_clauses? !!gt_clauses end # Does this task group have clauses on a field value being lte. # # @return [ true, false ] If the task group has clauses on a field value being lte. # # @since 6.2.0 def has_lte_clauses? !!lte_clauses end # Does this task group have clauses on a field value being lt. # # @return [ true, false ] If the task group has clauses on a field value being lt. # # @since 6.2.0 def has_lt_clauses? !!lt_clauses end # The expected exception message. # # @return [ String ] The expected exception message. # # @since 6.2.0 def expected_exception_message @expected_exception_message ||= begin if do_definitions = @actions.group_by { |a| a.keys.first }['do'] if catch_exception = do_definitions.find { |a| a['do']['catch'] } catch_exception['do']['catch'] end end end end # The match clauses. # # @return [ Array ] The match clauses. # # @since 6.2.0 def match_clauses @match_actions ||= @actions.group_by { |a| a.keys.first }['match'] end # The true match clauses. # # @return [ Array ] The true match clauses. # # @since 6.2.0 def true_clauses @true_clauses ||= @actions.group_by { |a| a.keys.first }['is_true'] end # The false match clauses. # # @return [ Array ] The false match clauses. # # @since 6.2.0 def false_clauses @false_clauses ||= @actions.group_by { |a| a.keys.first }['is_false'] end # The gte clauses. # # @return [ Array ] The gte clauses. # # @since 6.2.0 def gte_clauses @gte_clauses ||= @actions.group_by { |a| a.keys.first }['gte'] end # The gt clauses. # # @return [ Array ] The gt clauses. # # @since 6.2.0 def gt_clauses @gt_clauses ||= @actions.group_by { |a| a.keys.first }['gt'] end # The lte clauses. # # @return [ Array ] The lte clauses. # # @since 6.2.0 def lte_clauses @lte_clauses ||= @actions.group_by { |a| a.keys.first }['lte'] end # The lt clauses. # # @return [ Array ] The lt clauses. # # @since 6.2.0 def lt_clauses @lt_clauses ||= @actions.group_by { |a| a.keys.first }['lt'] end # The field length match clauses. # # @return [ Array ] The field length match clauses. # # @since 6.2.0 def length_match_clauses @match_length ||= @actions.group_by { |a| a.keys.first }['length'] end private ACTIONS = (Test::GROUP_TERMINATORS + ['do']).freeze def do_actions @do_actions ||= @actions.group_by { |a| a.keys.first }['do'].map { |definition| Action.new(definition['do']) } end def variables_to_set @variables_to_set ||= (@actions.group_by { |a| a.keys.first }['set'] || []) end def variables_to_transform_and_set @variables_to_transform_and_set ||= (@actions.group_by { |a| a.keys.first }['transform_and_set'] || []) end def transform_and_set_variable(action) variables_to_transform_and_set.each do |set_definition| set_definition['transform_and_set'].each do |response_key, transform_description| match_base_64_transform = /(\#base64EncodeCredentials\()(\S*)\)/ matches = match_base_64_transform.match(transform_description) fields = matches[2].split(',') if matches.length > 0 values_to_encode = action.response.select do |key| fields.include?(key) end.values if fields to_set = Base64.strict_encode64(values_to_encode.join(':')) @test.cache_value(response_key, to_set) end end end def set_variable(action) variables_to_set.each do |set_definition| set_definition['set'].each do |response_key, variable_name| nested_key_chain = response_key.split('.').map do |key| # If there's a variable in the set key, get the value: key.gsub!(key, @test.cached_values[key.gsub('$', '')]) if key.match?(/\$.+/) (key =~ /\A[-+]?[0-9]+\z/) ? key.to_i: key end if to_set = find_value(nested_key_chain, action.response) @test.cache_value(variable_name, to_set) end end end end def find_value(chain, document) # Return the first key if an 'arbitrary key' should be returned return document.keys[0] if chain[0] == '_arbitrary_key_' return document[chain[0]] unless chain.size > 1 find_value(chain[1..-1], document[chain[0]]) if document[chain[0]] end end end end end end elastic-elasticsearch-ruby-c38be0c/api-spec-testing/test_file/test.rb000066400000000000000000000234611462737751600261040ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module RestAPIYAMLTests class TestFile # Represents a single test in a test file. A single test can have many operations and validations. # # @since 6.2.0 class Test class << self # Given a list of keys, find the value in a recursively nested document. # # @param [ Array ] chain The list of nested document keys. # @param [ Hash ] document The document to find the value in. # # @return [ Object ] The value at the nested key. # # @since 6.2.0 def find_value_in_document(chain, document) return document[chain] unless chain.is_a?(Array) return document[chain[0]] unless chain.size > 1 # a number can be a string key in a Hash or indicate an element in a list if document.is_a?(Hash) find_value_in_document(chain[1..-1], document[chain[0].to_s]) if document[chain[0].to_s] elsif document[chain[0]] find_value_in_document(chain[1..-1], document[chain[0]]) if document[chain[0]] end end # Given a string representing a nested document key using dot notation, # split it, keeping escaped dots as part of a key name and replacing # numerics with a Ruby Integer. # # For example: # "joe.metadata.2.key2" => ['joe', 'metadata', 2, 'key2'] # "jobs.0.node.attributes.ml\\.enabled" => ["jobs", 0, "node", "attributes", "ml\\.enabled"] # # @param [ String ] chain The list of nested document keys. # @param [ Hash ] document The document to find the value in. # # @return [ Array ] A list of the nested keys. # # @since 6.2.0 def split_and_parse_key(key) key.split(/(? ] The list of task groups. # # @since 6.2.0 def task_groups @task_groups ||= begin @definition.each_with_index.inject([]) do |task_groups, (action, i)| # the action has a catch, it's a singular task group if action['do'] && action['do']['catch'] task_groups << TaskGroup.new(self) elsif action['do'] && i > 0 && is_a_validation?(@definition[i-1]) task_groups << TaskGroup.new(self) elsif i == 0 task_groups << TaskGroup.new(self) end task_groups[-1].add_action(action) && task_groups end end end # Cache a value on this test object. # # @example # test.cache_value(cache_key, value) # # @param [ String ] cache_key The cache key for the value. # @param [ Object ] value The value to cache. # # @return [ Hash ] The cached values. # # @since 6.2.0 def cache_value(cache_key, value) @cached_values[cache_key] = value @cached_values end # Get a cached value. # # @example # test.get_cached_value('$watch_count_active') # # @param [ String ] key The key of the cached value. # # @return [ Hash ] The cached value at the key or the key if it's not found. # # @since 6.2.0 def get_cached_value(key) case key when String key =~ /^\$/ ? @cached_values.fetch(key.gsub(/[\$\{\}]/, ''), key) : key when Hash key.inject({}) do |hash, (k, v)| if v.is_a?(String) hash.merge(@cached_values.fetch(k.gsub(/[\$\{\}]/, ''), k) => @cached_values.fetch(v.gsub(/[\$\{\}]/, ''), v)) else hash.merge(@cached_values.fetch(k.gsub(/[\$\{\}]/, ''), k) => v) end end when Array key.collect do |k| k.is_a?(String) ? @cached_values.fetch(k.gsub(/[\$\{\}]/, ''), k) : k end else key end end # Run all the tasks in this test. # # @example # test.run(client) # # @param [ Elasticsearch::Client ] client The client to use when executing operations. # # @return [ self ] # # @since 6.2.0 def run(client) task_groups.each { |task_group| task_group.run(client) } self end # Determine whether this test should be skipped, given a list of unsupported features. # # @example # test.skip_test?(['warnings']) # # @param [ Array ] features_to_skip A list of the features to skip. # # @return [ true, false ] Whether this test should be skipped, given a list of unsupported features. # # @since 6.2.0 def skip_test?(client, features_to_skip = test_file.features_to_skip) return true if pre_defined_skip? if @skip @skip.collect { |s| s['skip'] }.any? do |skip_definition| contains_features_to_skip?(features_to_skip, skip_definition) || test_file.skip_version?(client, skip_definition) end end end # Replace the `$master` substring in a key with the cached master node's id. # # @param [ String ] expected_key The expected key, containing the substring `$master` that needs to be replaced. # # See test xpack/10_basic.yml # @return [ String ] The altered key. # # @since 7.2.0 def inject_master_node_id(expected_key) if cached_values['master'] expected_key.gsub(/\$master/, cached_values['master']) else expected_key end end private def contains_features_to_skip?(features_to_skip, skip_definition) !(features_to_skip & ([skip_definition['features']].flatten || [])).empty? end def pre_defined_skip? SKIPPED_TESTS.find do |t| file_basename == t[:file] && (description == t[:description] || t[:description] == '*') end end def is_a_validation?(action) GROUP_TERMINATORS.any? { |validation| action[validation] } || expects_exception?(action) end def expects_exception?(action) action['do'] && action['do']['catch'] end end end end end elastic-elasticsearch-ruby-c38be0c/api-spec-testing/wipe_cluster.rb000066400000000000000000000304641462737751600256550ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require_relative 'logging' include Elasticsearch::RestAPIYAMLTests::Logging module Elasticsearch module RestAPIYAMLTests module WipeCluster PRESERVE_ILM_POLICY_IDS = [ 'ilm-history-ilm-policy', 'slm-history-ilm-policy', 'watch-history-ilm-policy', 'ml-size-based-ilm-policy', 'logs', 'metrics', '.deprecation-indexing-ilm-policy', '.monitoring-8-ilm-policy', 'behavioral_analytics-events-default_policy' ].freeze # Wipe Cluster, based on PHP's implementation of ESRestTestCase.java:wipeCluster() # https://github.com/elastic/elasticsearch-php/blob/7.10/tests/Elasticsearch/Tests/Utility.php#L97 def self.run(client) if xpack? clear_rollup_jobs(client) wait_for_pending_tasks(client) clear_sml_policies(client) wipe_searchable_snapshot_indices(client) end clear_snapshots_and_repositories(client) clear_datastreams(client) clear_indices(client) if xpack? clear_templates_xpack(client) clear_datafeeds(client) clear_ml_jobs(client) else client.indices.delete_template(name: '*') client.indices.get_index_template['index_templates'].each do |template| next if xpack_template? template['name'] client.indices.delete_index_template(name: template['name']) end client.cluster.get_component_template['component_templates'].each do |template| next if xpack_template? template['name'] client.cluster.delete_component_template(name: template['name'], ignore: 404) end end clear_cluster_settings(client) return unless xpack? clear_ml_filters(client) clear_ilm_policies(client) clear_auto_follow_patterns(client) clear_tasks(client) clear_transforms(client) delete_all_node_shutdown_metadata(client) wait_for_cluster_tasks(client) end class << self def xpack? ENV['TEST_SUITE'] == 'platinum' end def wait_for_pending_tasks(client) filter = 'xpack/rollup/job' loop do results = client.cat.tasks(detailed: true).split("\n") count = 0 time = Time.now.to_i results.each do |task| next if task.empty? logger.debug "Pending task: #{task}" count += 1 if task.include?(filter) end break unless count.positive? && Time.now.to_i < (time + 30) end end def wait_for_cluster_tasks(client) time = Time.now.to_i count = 0 loop do results = client.cluster.pending_tasks results['tasks'].each do |task| next if task.empty? logger.debug "Pending cluster task: #{task}" count += 1 end break unless count.positive? && Time.now.to_i < (time + 30) end end def clear_sml_policies(client) policies = client.xpack.snapshot_lifecycle_management.get_lifecycle policies.each do |name, _| client.xpack.snapshot_lifecycle_management.delete_lifecycle(policy_id: name) end end def clear_ilm_policies(client) policies = client.xpack.ilm.get_lifecycle policies.each do |policy| client.xpack.ilm.delete_lifecycle(policy: policy[0]) unless PRESERVE_ILM_POLICY_IDS.include? policy[0] end end def clear_cluster_settings(client) settings = client.cluster.get_settings new_settings = [] settings.each do |name, value| next unless !value.empty? && value.is_a?(Array) new_settings[name] = [] if new_settings[name].empty? value.each do |key, _v| new_settings[name]["#{key}.*"] = nil end end client.cluster.put_settings(body: new_settings) unless new_settings.empty? end def clear_templates_xpack(client) templates = client.cat.templates(h: 'name').split("\n") templates.each do |template| next if xpack_template? template begin client.indices.delete_template(name: template) rescue Elasticsearch::Transport::Transport::Errors::NotFound => e if e.message.include?("index_template [#{template}] missing") client.indices.delete_index_template(name: template, ignore: 404) end end end # Delete component template result = client.cluster.get_component_template result['component_templates'].each do |template| next if xpack_template? template['name'] client.cluster.delete_component_template(name: template['name'], ignore: 404) end end XPACK_TEMPLATES = [ '.watches', 'logstash-index-template', '.logstash-management', 'security_audit_log', '.slm-history', '.async-search', 'saml-service-provider', 'ilm-history', 'logs', 'logs-settings', 'logs-mappings', 'metrics', 'metrics-settings', 'metrics-mappings', 'synthetics', 'synthetics-settings', 'synthetics-mappings', '.snapshot-blob-cache', '.deprecation-indexing-template', '.deprecation-indexing-mappings', '.deprecation-indexing-settings', 'security-index-template', 'data-streams-mappings', 'behavioral_analytics-events-mappings', 'behavioral_analytics-events-settings', 'ecs@dynamic_templates' ].freeze def xpack_template?(template) return true if template.include?('@') xpack_prefixes = [ '.monitoring', '.watch', '.triggered-watches', '.data-frame', '.ml-', '.transform', 'data-streams-mappings', 'elastic-connectors' ].freeze xpack_prefixes.map { |a| return true if (a.include?(template) || template.start_with?(a)) } XPACK_TEMPLATES.include? template end def clear_auto_follow_patterns(client) patterns = client.cross_cluster_replication.get_auto_follow_pattern patterns['patterns'].each do |pattern| client.cross_cluster_replication.delete_auto_follow_pattern(name: pattern) end end private def create_x_pack_rest_user(client) client.xpack.security.put_user(username: 'x_pack_rest_user', body: { password: 'x-pack-test-password', roles: ['superuser'] }) end def clear_roles(client) client.xpack.security.get_role.each do |role, _| begin; client.xpack.security.delete_role(name: role); rescue; end end end def clear_users(client) client.xpack.security.get_user.each do |user, _| begin; client.xpack.security.delete_user(username: user); rescue; end end end def clear_privileges(client) client.xpack.security.get_privileges.each do |privilege, _| begin; client.xpack.security.delete_privileges(name: privilege); rescue; end end end def clear_datafeeds(client) client.xpack.ml.stop_datafeed(datafeed_id: '_all', force: true) client.xpack.ml.get_datafeeds['datafeeds'].each do |d| client.xpack.ml.delete_datafeed(datafeed_id: d['datafeed_id']) end end def clear_ml_jobs(client) client.xpack.ml.close_job(job_id: '_all', force: true) client.xpack.ml.get_jobs['jobs'].each do |d| client.xpack.ml.delete_job(job_id: d['job_id']) end end def clear_rollup_jobs(client) client.xpack.rollup.get_jobs(id: '_all')['jobs'].each do |d| client.xpack.rollup.stop_job(id: d['config']['id']) client.xpack.rollup.delete_job(id: d['config']['id']) end end def clear_tasks(client) tasks = client.tasks.get['nodes'].values.first['tasks'].values.select do |d| d['cancellable'] end.map do |d| "#{d['node']}:#{d['id']}" end tasks.each { |t| client.tasks.cancel task_id: t } end def clear_machine_learning_indices(client) client.indices.delete(index: '.ml-*', ignore: 404) end def clear_index_templates(client) client.indices.delete_template(name: '*') templates = client.indices.get_index_template templates['index_templates'].each do |template| client.indices.delete_index_template(name: template['name']) end end def clear_snapshots_and_repositories(client) return unless (repositories = client.snapshot.get_repository) repositories.each_key do |repository| client.snapshot.delete(repository: repository, snapshot: '*', ignore: 404) if repositories[repository]['type'] == 'fs' begin response = client.perform_request('DELETE', "_snapshot/#{repository}", ignore: [500, 404]) client.snapshot.delete_repository(repository: repository, ignore: 404) rescue Elasticsearch::Transport::Transport::Errors::InternalServerError => e regexp = /indices that use the repository: \[docs\/([a-zA-Z0-9]+)/ raise e unless response.body['error']['root_cause'].first['reason'].match(regexp) # Try again after clearing indices if we get a 500 error from delete repository clear_indices(client) client.snapshot.delete_repository(repository: repository, ignore: 404) end end end def clear_transforms(client) client.transform.get_transform(transform_id: '*')['transforms'].each do |transform| client.transform.delete_transform(transform_id: transform[:id]) end end def clear_datastreams(client) datastreams = client.xpack.indices.get_data_stream(name: '*', expand_wildcards: 'all') datastreams['data_streams'].each do |datastream| client.xpack.indices.delete_data_stream(name: datastream['name'], expand_wildcards: 'all') end begin client.xpack.indices.delete_data_stream(name: '*', expand_wildcards: 'all') rescue StandardError => e logger.error "Caught exception attempting to delete data streams: #{e}" client.xpack.indices.delete_data_stream(name: '*') end end def clear_ml_filters(client) filters = client.xpack.ml.get_filters['filters'] filters.each do |filter| client.xpack.ml.delete_filter(filter_id: filter['filter_id']) end end def clear_indices(client) client.indices.delete(index: '*,-.ds-ilm-history-*', expand_wildcards: 'open,closed,hidden', ignore: 404) end def wipe_searchable_snapshot_indices(client) indices = client.cluster.state(metric: 'metadata', filter_path: 'metadata.indices.*.settings.index.store.snapshot') return if indices.dig('metadata', 'indices') indices.each do |index| client.indices.delete(index: index, ignore: 404) end end def delete_all_node_shutdown_metadata(client) nodes = client.shutdown.get_node return if nodes['_nodes'] && nodes['cluster_name'] || nodes&.[]("nodes").empty? nodes.each do |node| client.shutdown.delete_node(node['node_id']) end end end end end end elastic-elasticsearch-ruby-c38be0c/api-spec-testing/wipe_cluster_8.rb000066400000000000000000000370121462737751600261000ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require_relative 'logging' include Elasticsearch::RestAPIYAMLTests::Logging module Elasticsearch module RestAPIYAMLTests module WipeCluster8 PRESERVE_ILM_POLICY_IDS = [ 'ilm-history-ilm-policy', 'slm-history-ilm-policy', 'watch-history-ilm-policy', 'watch-history-ilm-policy-16', 'ml-size-based-ilm-policy', 'logs', 'metrics', 'profiling', 'synthetics', '7-days-default', '30-days-default', '90-days-default', '180-days-default', '365-days-default', '.fleet-files-ilm-policy', '.fleet-file-data-ilm-policy', '.fleet-actions-results-ilm-policy', '.fleet-file-fromhost-data-ilm-policy', '.fleet-file-fromhost-meta-ilm-policy', '.fleet-file-tohost-data-ilm-policy', '.fleet-file-tohost-meta-ilm-policy', '.deprecation-indexing-ilm-policy', '.monitoring-8-ilm-policy', 'behavioral_analytics-events-default_policy' ].freeze PLATINUM_TEMPLATES = [ '.watches', 'logstash-index-template', '.logstash-management', 'security_audit_log', '.slm-history', '.async-search', 'saml-service-provider', 'ilm-history', 'logs', 'logs-settings', 'logs-mappings', 'metrics', 'metrics-settings', 'metrics-mappings', 'synthetics', 'synthetics-settings', 'synthetics-mappings', '.snapshot-blob-cache', '.deprecation-indexing-template', '.deprecation-indexing-mappings', '.deprecation-indexing-settings', 'security-index-template', 'data-streams-mappings', 'search-acl-filter' ].freeze # Wipe Cluster, based on PHP's implementation of ESRestTestCase.java:wipeCluster() # https://github.com/elastic/elasticsearch-php/blob/7.10/tests/Elasticsearch/Tests/Utility.php#L97 def self.run(client) ensure_no_initializing_shards(client) wipe_cluster(client) wait_for_cluster_tasks(client) check_for_unexpectedly_recreated_objects(client) end def self.create_xpack_rest_user(client) client.security.put_user( username: 'x_pack_rest_user', body: { password: 'x-pack-test-password', roles: ['superuser'] } ) end class << self private def wipe_cluster(client) read_plugins(client) if @has_rollups wipe_rollup_jobs(client) # wait_for_pending_rollup_tasks(client) end delete_all_slm_policies(client) wipe_searchable_snapshot_indices(client) if @has_xpack wipe_snapshots(client) wipe_datastreams(client) wipe_all_indices(client) wipe_all_templates(client) wipe_cluster_settings(client) if platinum? clear_ml_jobs(client) clear_datafeeds(client) delete_data_frame_analytics(client) clear_ml_filters(client) end delete_all_ilm_policies(client) if @has_ilm delete_all_follow_patterns(client) if @has_ccr delete_all_node_shutdown_metadata(client) clear_tasks(client) clear_transforms(client) wipe_calendars(client) end def ensure_no_initializing_shards(client) client.cluster.health(wait_for_no_initializing_shards: true, timeout: '70s', level: 'shards') end def check_for_unexpectedly_recreated_objects(client) unexpected_ilm_policies = client.ilm.get_lifecycle unexpected_ilm_policies.reject! { |k, _| preserve_policy?(k) } unless unexpected_ilm_policies.empty? logger.info( "Expected no ILM policies after deletions, but found #{unexpected_ilm_policies.keys.join(',')}" ) end return unless platinum? templates = client.indices.get_index_template unexpected_templates = templates['index_templates'].reject do |t| # reject platinum templates platinum_template?(t['name']) end.map { |t| t['name'] } # only keep the names legacy_templates = client.indices.get_template unexpected_templates << legacy_templates.keys.reject { |t| platinum_template?(t) } unless unexpected_templates.reject(&:empty?).empty? logger.info( "Expected no templates after deletions, but found #{unexpected_templates.join(',')}" ) end end def platinum? ENV['TEST_SUITE'] == 'platinum' end def read_plugins(client) response = client.perform_request('GET', '_nodes/plugins').body response['nodes'].each do |node| node[1]['modules'].each do |mod| @has_xpack = true if mod['name'].include?('x-pack') @has_ilm = true if mod['name'].include?('x-pack-ilm') @has_rollups = true if mod['name'].include?('x-pack-rollup') @has_ccr = true if mod['name'].include?('x-pack-ccr') @has_shutdown = true if mod['name'].include?('x-pack-shutdown') end end end def wipe_rollup_jobs(client) client.rollup.get_jobs(id: '_all')['jobs'].each do |d| client.rollup.stop_job(id: d['config']['id'], wait_for_completion: true, timeout: '10s', ignore: 404) client.rollup.delete_job(id: d['config']['id'], ignore: 404) end end def wait_for_pending_rollup_tasks(client) filter = 'xpack/rollup/job' start_time = Time.now.to_i count = 0 loop do results = client.cat.tasks(detailed: true).split("\n") results.each do |task| next if task.empty? || skippable_task?(task) || task.include?(filter) count += 1 end break unless count.positive? && Time.now.to_i < (start_time + 1) end logger.debug("Waited for #{count} pending rollup tasks for #{Time.now.to_i - start_time}s.") if count.positive? end def delete_all_slm_policies(client) policies = client.snapshot_lifecycle_management.get_lifecycle policies.each do |name, _| client.snapshot_lifecycle_management.delete_lifecycle(policy_id: name) end end def wipe_searchable_snapshot_indices(client) indices = client.cluster.state(metric: 'metadata', filter_path: 'metadata.indices.*.settings.index.store.snapshot') return unless indices.dig('metadata', 'indices') indices['metadata']['indices'].each do |index| index_name = if index.is_a?(Array) index[0] elsif index.is_a?(Hash) index.keys.first end client.indices.delete(index: index_name, ignore: 404) end end def wipe_snapshots(client) # Repeatedly delete the snapshots until there aren't any loop do repositories = client.snapshot.get_repository(repository: '_all') break if repositories.empty? repositories.each_key do |repository| if ['fs', 'source'].include? repositories[repository]['type'] response = client.snapshot.get(repository: repository, snapshot: '_all', ignore_unavailable: true) response['snapshots'].each do |snapshot| if snapshot['state'] != 'SUCCESS' logger.debug("Found snapshot that did not succeed #{snapshot}") end client.snapshot.delete(repository: repository, snapshot: snapshot['snapshot'], ignore: 404) end end client.snapshot.delete_repository(repository: repository, ignore: 404) end end end def wipe_datastreams(client) begin client.indices.delete_data_stream(name: '*', expand_wildcards: 'all') rescue StandardError => e logger.error "Caught exception attempting to delete data streams: #{e}" client.indices.delete_data_stream(name: '*') end end def wipe_all_indices(client) client.indices.delete(index: '*,-.ds-ilm-history-*', expand_wildcards: 'open,closed,hidden', ignore: 404) end def wipe_all_templates(client) templates = client.indices.get_index_template templates['index_templates'].each do |template| next if platinum_template? template['name'] begin client.indices.delete_index_template(name: template['name'], ignore: 404) end end # Delete component template result = client.cluster.get_component_template result['component_templates'].each do |template| next if platinum_template? template['name'] client.cluster.delete_component_template(name: template['name'], ignore: 404) end # Always check for legacy templates templates = client.indices.get_template templates.each do |name, _| next if platinum_template?(name) begin client.indices.delete_template(name: name) rescue StandardError => e logger.info("Unable to remove index template #{name}") end end end def platinum_template?(template) return true if template.include?('@') platinum_prefixes = [ '.monitoring', '.watch', '.triggered-watches', '.data-frame', '.ml-', '.transform', '.deprecation', 'data-streams-mappings', '.fleet', 'behavioral_analytics-', 'profiling', 'elastic-connectors', 'ilm-history', '.slm-history' ].freeze return true if template.start_with?(*platinum_prefixes) PLATINUM_TEMPLATES.include? template end def preserve_policy?(policy) PRESERVE_ILM_POLICY_IDS.include?(policy) || policy.include?('@') end def wait_for_cluster_tasks(client) start_time = Time.now.to_i count = 0 loop do results = client.cluster.pending_tasks results['tasks'].each do |task| next if task.empty? || skippable_task?(task) count += 1 end break unless count.positive? && Time.now.to_i < (start_time + 5) end logger.debug("Waited for #{count} pending cluster tasks for #{Time.now.to_i - start_time}s.") if count.positive? end def skippable_task?(task) names = ['health-node', 'cluster:monitor/tasks/lists', 'create-index-template-v2', 'remove-component-template'] if task.is_a?(String) names.select { |n| task.match? n }.any? elsif task.is_a?(Hash) names.select { |n| task['source'].match? n }.any? end end def delete_all_ilm_policies(client) policies = client.ilm.get_lifecycle policies.each do |policy| client.ilm.delete_lifecycle(policy: policy[0]) unless preserve_policy?(policy[0]) end end def wipe_cluster_settings(client) settings = client.cluster.get_settings new_settings = [] settings.each do |name, value| next unless !value.empty? && value.is_a?(Array) new_settings[name] = [] if new_settings[name].empty? value.each do |key, _v| new_settings[name]["#{key}.*"] = nil end end client.cluster.put_settings(body: new_settings) unless new_settings.empty? end def delete_all_follow_patterns(client) patterns = client.cross_cluster_replication.get_auto_follow_pattern patterns['patterns'].each do |pattern| client.cross_cluster_replication.delete_auto_follow_pattern(name: pattern) end end def clear_roles(client) client.security.get_role.each do |role, _| begin; client.security.delete_role(name: role); rescue; end end end def clear_users(client) client.security.get_user.each do |user, _| begin; client.security.delete_user(username: user); rescue; end end end def clear_privileges(client) client.security.get_privileges.each do |privilege, _| begin; client.security.delete_privileges(name: privilege); rescue; end end end def clear_ml_jobs(client) client.ml.close_job(job_id: '_all', force: true) client.ml.get_jobs['jobs'].each do |d| client.ml.delete_job(job_id: d['job_id']) end end def clear_datafeeds(client) client.ml.stop_datafeed(datafeed_id: '_all', force: true) client.ml.get_datafeeds['datafeeds'].each do |d| client.ml.delete_datafeed(datafeed_id: d['datafeed_id']) end end def clear_tasks(client) tasks = client.tasks.get['nodes'].values.first['tasks'].values.select do |d| d['cancellable'] end.map do |d| "#{d['node']}:#{d['id']}" end tasks.each { |t| client.tasks.cancel task_id: t } end def clear_machine_learning_indices(client) client.indices.delete(index: '.ml-*', ignore: 404) end def clear_index_templates(client) client.indices.delete_template(name: '*') templates = client.indices.get_index_template templates['index_templates'].each do |template| client.indices.delete_index_template(name: template['name']) end end def clear_transforms(client) client.transform.get_transform(transform_id: '*')['transforms'].each do |transform| client.transform.delete_transform(transform_id: transform['id']) end end def clear_ml_filters(client) filters = client.ml.get_filters['filters'] filters.each do |filter| client.ml.delete_filter(filter_id: filter['filter_id']) end end def delete_all_node_shutdown_metadata(client) nodes = client.shutdown.get_node return unless nodes['nodes'] nodes['nodes'].each do |node| client.shutdown.delete_node(node['node_id']) end end def delete_data_frame_analytics(client) dfs = client.ml.get_data_frame_analytics return unless dfs['data_frame_analytics'] dfs['data_frame_analytics'].each do |df| client.ml.delete_data_frame_analytics(id: df['id'], force: true) end end def wipe_calendars(client) calendars = client.ml.get_calendars(calendar_id: '_all')['calendars'] calendars.each do |calendar| client.ml.delete_calendar(calendar_id: calendar['calendar_id']) end end end end end end elastic-elasticsearch-ruby-c38be0c/docs/000077500000000000000000000000001462737751600203705ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/docs/advanced-config.asciidoc000066400000000000000000000264611462737751600251110ustar00rootroot00000000000000[[advanced-config]] === Advanced configuration The client supports many configurations options for setting up and managing connections, configuring logging, customizing the transport library, and so on. [discrete] [[setting-hosts]] ==== Setting hosts To connect to a specific {es} host: ```ruby Elasticsearch::Client.new(host: 'search.myserver.com') ``` To connect to a host with specific port: ```ruby Elasticsearch::Client.new(host: 'myhost:8080') ``` To connect to multiple hosts: ```ruby Elasticsearch::Client.new(hosts: ['myhost1', 'myhost2']) ``` Instead of strings, you can pass host information as an array of Hashes: ```ruby Elasticsearch::Client.new(hosts: [ { host: 'myhost1', port: 8080 }, { host: 'myhost2', port: 8080 } ]) ``` NOTE: When specifying multiple hosts, you probably want to enable the `retry_on_failure` or `retry_on_status` options to perform a failed request on another node (refer to <>). Common URL parts – scheme, HTTP authentication credentials, URL prefixes, and so on – are handled automatically: ```ruby Elasticsearch::Client.new(url: 'https://username:password@api.server.org:4430/search') ``` You can pass multiple URLs separated by a comma: ```ruby Elasticsearch::Client.new(urls: 'http://localhost:9200,http://localhost:9201') ``` Another way to configure URLs is to export the `ELASTICSEARCH_URL` variable. The client is automatically going to use a round-robin algorithm across the hosts (unless you select or implement a different <>). [discrete] [[default-port]] ==== Default port The default port is `9200`. Specify a port for your host(s) if they differ from this default. If you are using Elastic Cloud, the default port is port `9243`. You must supply your username and password separately, and optionally a port. Refer to <>. [discrete] [[logging]] ==== Logging To log requests and responses to standard output with the default logger (an instance of Ruby's `::Logger` class), set the log argument to true: ```ruby Elasticsearch::Client.new(log: true) ``` You can also use https://github.com/elastic/ecs-logging-ruby[`ecs-logging`] which is a set of libraries that enables you to transform your application logs to structured logs that comply with the https://www.elastic.co/guide/en/ecs/current/ecs-reference.html[Elastic Common Schema (ECS)]: [source,ruby] ------------------------------------ logger = EcsLogging::Logger.new($stdout) Elasticsearch::Client.new(logger: logger) ------------------------------------ To trace requests and responses in the Curl format, set the `trace` argument: ```ruby Elasticsearch::Client.new(trace: true) ``` You can customize the default logger or tracer: [source,ruby] ------------------------------------ client.transport.logger.formatter = proc { |s, d, p, m| "#{s}: #{m}\n" } client.transport.logger.level = Logger::INFO ------------------------------------ Or, you can use a custom `::Logger` instance: ```ruby Elasticsearch::Client.new(logger: Logger.new(STDERR)) ``` You can pass the client any conforming logger implementation: [source,ruby] ------------------------------------ require 'logging' # https://github.com/TwP/logging/ log = Logging.logger['elasticsearch'] log.add_appenders Logging.appenders.stdout log.level = :info client = Elasticsearch::Client.new(logger: log) ------------------------------------ [discrete] [[apm-integration]] ==== APM integration This client integrates seamlessly with Elastic APM via the Elastic APM Agent. It automatically captures client requests if you are using the agent on your code. If you're using `elastic-apm` v3.8.0 or up, you can set `capture_elasticsearch_queries` to `true` in `config/elastic_apm.yml` to also capture the body from requests in {es}. Refer to https://github.com/elastic/elasticsearch-ruby/tree/master/docs/examples/apm[this example]. [discrete] [[custom-http-headers]] ==== Custom HTTP Headers You can set a custom HTTP header on the client's initializer: [source,ruby] ------------------------------------ client = Elasticsearch::Client.new( transport_options: { headers: {user_agent: "My App"} } ) ------------------------------------ You can also pass in `headers` as a parameter to any of the API Endpoints to set custom headers for the request: ```ruby client.search(index: 'myindex', q: 'title:test', headers: {user_agent: "My App"}) ``` [discrete] [[x-opaque-id]] ==== Identifying running tasks with X-Opaque-Id The X-Opaque-Id header allows to track certain calls, or associate certain tasks with the client that started them (refer to https://www.elastic.co/guide/en/elasticsearch/reference/current/tasks.html#_identifying_running_tasks[the documentation]). To use this feature, you need to set an id for `opaque_id` on the client on each request. Example: [source,ruby] ------------------------------------ client = Elasticsearch::Client.new client.search(index: 'myindex', q: 'title:test', opaque_id: '123456') ------------------------------------ The search request includes the following HTTP Header: ```ruby X-Opaque-Id: 123456 ``` You can also set a prefix for X-Opaque-Id when initializing the client. This is prepended to the id you set before each request if you're using X-Opaque-Id. Example: [source,ruby] ------------------------------------ client = Elasticsearch::Client.new(opaque_id_prefix: 'eu-west1_') client.search(index: 'myindex', q: 'title:test', opaque_id: '123456') ------------------------------------ The request includes the following HTTP Header: ```ruby X-Opaque-Id: eu-west1_123456 ``` [discrete] [[setting-timeouts]] ==== Setting Timeouts For many operations in {es}, the default timeouts of HTTP libraries are too low. To increase the timeout, you can use the `request_timeout` parameter: ```ruby Elasticsearch::Client.new(request_timeout: 5*60) ``` You can also use the `transport_options` argument documented below. [discrete] [[randomizing-hosts]] ==== Randomizing Hosts If you pass multiple hosts to the client, it rotates across them in a round-robin fashion by default. When the same client would be running in multiple processes (for example, in a Ruby web server such as Thin), it might keep connecting to the same nodes "at once". To prevent this, you can randomize the hosts collection on initialization and reloading: ```ruby Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], randomize_hosts: true) ``` [discrete] [[retry-failures]] ==== Retrying on Failures When the client is initialized with multiple hosts, it makes sense to retry a failed request on a different host: ```ruby Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], retry_on_failure: true) ``` By default, the client retries the request 3 times. You can specify how many times to retry before it raises an exception by passing a number to `retry_on_failure`: ```ruby Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], retry_on_failure: 5) ``` You can also use `retry_on_status` to retry when specific status codes are returned: ```ruby Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], retry_on_status: [502, 503]) ``` These two parameters can also be used together: ```ruby Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], retry_on_status: [502, 503], retry_on_failure: 10) ``` You can also set a `delay_on_retry` value in milliseconds. This will add a delay to wait between retries: ```ruby Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], retry_on_failure: 5, delay_on_retry: 1000) ``` [discrete] [[reload-hosts]] ==== Reloading Hosts {es} dynamically discovers new nodes in the cluster by default. You can leverage this in the client, and periodically check for new nodes to spread the load. To retrieve and use the information from the https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-nodes-info.html[Nodes Info API] on every 10,000th request: ```ruby Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], reload_connections: true) ``` You can pass a specific number of requests after which reloading should be performed: ```ruby Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], reload_connections: 1_000) ``` To reload connections on failures, use: ```ruby Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], reload_on_failure: true) ``` The reloading timeouts if not finished under 1 second by default. To change the setting: ```ruby Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], sniffer_timeout: 3) ``` NOTE: When using reloading hosts ("sniffing") together with authentication, pass the scheme, user and password with the host info – or, for more clarity, in the `http` options: [source,ruby] ------------------------------------ Elasticsearch::Client.new( host: 'localhost:9200', http: { scheme: 'https', user: 'U', password: 'P' }, reload_connections: true, reload_on_failure: true ) ------------------------------------ [discrete] [[connection-selector]] ==== Connection Selector By default, the client rotates the connections in a round-robin fashion, using the `Elasticsearch::Transport::Transport::Connections::Selector::RoundRobin` strategy. You can implement your own strategy to customize the behaviour. For example, let's have a "rack aware" strategy, which prefers the nodes with a specific attribute. The strategy uses the other nodes, only when these are unavailable: [source,ruby] ------------------------------------ class RackIdSelector include Elasticsearch::Transport::Transport::Connections::Selector::Base def select(options={}) connections.select do |c| # Try selecting the nodes with a `rack_id:x1` attribute first c.host[:attributes] && c.host[:attributes][:rack_id] == 'x1' end.sample || connections.to_a.sample end end Elasticsearch::Client.new hosts: ['x1.search.org', 'x2.search.org'], selector_class: RackIdSelector ------------------------------------ [discrete] [[serializer-implementations]] ==== Serializer Implementations By default, the https://rubygems.org/gems/multi_json[MultiJSON] library is used as the serializer implementation, and it picks up the "right" adapter based on gems available. The serialization component is pluggable, though, so you can write your own by including the `Elasticsearch::Transport::Transport::Serializer::Base` module, implementing the required contract, and passing it to the client as the `serializer_class` or `serializer` parameter. [discrete] [[exception-handling]] ==== Exception Handling The library defines a https://github.com/elastic/elasticsearch-ruby/blob/master/elasticsearch-transport/lib/elasticsearch/transport/transport/errors.rb[number of exception classes] for various client and server errors, as well as unsuccessful HTTP responses, making it possible to rescue specific exceptions with desired granularity. The highest-level exception is `Elasticsearch::Transport::Transport::Error` and is raised for any generic client or server errors. `Elasticsearch::Transport::Transport::ServerError` is raised for server errors only. As an example for response-specific errors, a 404 response status raises an `Elasticsearch::Transport::Transport::Errors::NotFound` exception. Finally, `Elasticsearch::Transport::Transport::SnifferTimeoutError` is raised when connection reloading ("sniffing") times out. elastic-elasticsearch-ruby-c38be0c/docs/basic-config.asciidoc000066400000000000000000000064211462737751600244170ustar00rootroot00000000000000[[basic-config]] === Basic configuration The table below contains the most important initialization parameters that you can use. [cols="<,<,<"] |=== | **Parameter** | **Data type** | **Description** | `adapter` | Symbol | A specific adapter for Faraday (for example, `:patron`). | `api_key` | String, Hash | For API key Authentication. Either the base64 encoding of `id` and `api_key` joined by a colon as a string, or a hash with the `id` and `api_key` values. | `compression` | Boolean | Whether to compress requests. Gzip compression is used. Defaults to `false`. Responses are automatically inflated if they are compressed. If a custom transport object is used, it must handle the request compression and response inflation. | `enable_meta_header` | Boolean | Whether to enable sending the meta data header to Cloud. Defaults to `true`. | `hosts` | String, Array | Single host passed as a string or hash, or multiple hosts passed as an array; `host` or `url` keys are also valid. | `log` | Boolean | Whether to use the default logger. Disabled by default. | `logger` | Object | An instance of a Logger-compatible object. | `opaque_id_prefix` | String | Sets a prefix for X-Opaque-Id when initializing the client. This is prepended to the id you set before each request if you're using X-Opaque-Id. | `randomize_hosts` | Boolean | Whether to shuffle connections on initialization and reload. Defaults to `false`. | `reload_connections` | Boolean, Number | Whether to reload connections after X requests. Defaults to `false`. | `reload_on_failure` | Boolean | Whether to reload connections after failure. Defaults to `false`. | `request_timeout` | Integer | The request timeout to be passed to transport in options. | `resurrect_after` | Integer | Specifies after how many seconds a dead connection should be tried again. | `retry_on_failure` | Boolean, Number | Whether to retry X times when request fails before raising and exception. Defaults to `false`. | `retry_on_status` | Array, Number | Specifies which status code needs to be returned to retry. | `selector` | Constant | An instance of selector strategy implemented with {Elasticsearch::Transport::Transport::Connections::Selector::Base}. | `send_get_body_as` | String | Specifies the HTTP method to use for GET requests with a body. Defaults to `GET`. | `serializer_class` | Constant | Specifies a serializer class to use. It is initialized by the transport and passed the transport instance. | `sniffer_timeout` | Integer | Specifieds the timeout for reloading connections in seconds. Defaults to `1`. | `trace` | Boolean | Whether to use the default tracer. Disabled by default. | `tracer` | Object | Specifies an instance of a Logger-compatible object. | `transport` | Object | Specifies a transport instance. | `transport_class` | Constant | Specifies a transport class to use. It is initialized by the client and passed hosts and all arguments. | `transport_options` | Hash | Specifies the options to be passed to the `Faraday::Connection` constructor. |===elastic-elasticsearch-ruby-c38be0c/docs/config.asciidoc000066400000000000000000000004421462737751600233350ustar00rootroot00000000000000[[ruby-config]] == Configuration This page contains information about how to configure the Ruby client tailored to your needs. Almost every aspect of the client is configurable. However, in most cases you only need to set a couple of parameters. * <> * <>elastic-elasticsearch-ruby-c38be0c/docs/connecting.asciidoc000066400000000000000000000152601462737751600242230ustar00rootroot00000000000000[[connecting]] == Connecting This page contains the information you need to connect and use the Client with {es}. **On this page** * <> * <> * <> * <> [discrete] [[client-auth]] === Authentication This document contains code snippets to show you how to connect to various {es} providers. [discrete] [[auth-ec]] ==== Elastic Cloud If you are using https://www.elastic.co/cloud[Elastic Cloud], the client offers an easy way to connect to it. You must pass the Cloud ID that you can find in the cloud console, then your username and password. [source,ruby] ------------------------------------ require 'elasticsearch' client = Elasticsearch::Client.new( cloud_id: '' user: '', password: '', ) ------------------------------------ You can also connect to the Cloud by using API Key authentication: [source,ruby] ------------------------------------ client = Elasticsearch::Client.new( cloud_id: '', api_key: {id: '', api_key: ''} ) ------------------------------------ [discrete] [[auth-api-key]] ==== API Key authentication You can also use the https://www.elastic.co/guide/en/elasticsearch/reference/7.16/security-api-create-api-key.html[ApiKey] authentication. NOTE: If you provide both basic authentication credentials and the ApiKey configuration, the ApiKey takes precedence. You can also use API Key authentication: [source,ruby] ------------------------------------ Elasticsearch::Client.new( host: host, transport_options: transport_options, api_key: credentials ) ------------------------------------ Where credentials is either the base64 encoding of `id` and `api_key` joined by a colon or a hash with the `id` and `api_key`: [source,ruby] ------------------------------------ Elasticsearch::Client.new( host: host, transport_options: transport_options, api_key: {id: 'my_id', api_key: 'my_api_key'} ) ------------------------------------ [discrete] [[auth-basic]] ==== Basic authentication You can pass the authentication credentials, scheme and port in the host configuration hash: [source,ruby] ------------------------------------ client = Elasticsearch::Client.new( hosts: [ { host: 'my-protected-host', port: '443', user: 'USERNAME', password: 'PASSWORD', scheme: 'https' } ] ) ------------------------------------ Or use the common URL format: client = Elasticsearch::Client.new(url: 'https://username:password@localhost:9200') To pass a custom certificate for SSL peer verification to Faraday-based clients, use the `transport_options` option: [source,ruby] ------------------------------------ Elasticsearch::Client.new( url: 'https://username:password@localhost:9200', transport_options: { ssl: { ca_file: '/path/to/cacert.pem' } } ) ------------------------------------ [discrete] [[ca-fingerprint]] ==== CA fingerprint You can configure the client to only trust certificates that are signed by a specific CA certificate (CA certificate pinning) by providing a `ca_fingerprint` option. This will verify that the fingerprint of the CA certificate that has signed the certificate of the server matches the supplied value: [source,ruby] ------------------------------------ ca_fingerprint = '64F2593F...' client = Elasticsearch::Client.new( host: 'https://elastic:changeme@localhost:9200', transport_options: { ssl: { verify: false } }, ca_fingerprint: ca_fingerprint ) ------------------------------------ The verification will be run once per connection. [discrete] [[client-usage]] === Usage The following snippet shows an example of using the Ruby client: [source,ruby] ------------------------------------ require 'elasticsearch' client = Elasticsearch::Client.new log: true client.cluster.health client.index(index: 'my-index', id: 1, body: { title: 'Test' }) client.indices.refresh(index: 'my-index') client.search(index: 'my-index', body: { query: { match: { title: 'test' } } }) ------------------------------------ [discrete] [[client-faas]] === Using the Client in a Function-as-a-Service Environment This section illustrates the best practices for leveraging the {es} client in a Function-as-a-Service (FaaS) environment. The most influential optimization is to initialize the client outside of the function, the global scope. This practice does not only improve performance but also enables background functionality as – for example – sniffing. The following examples provide a skeleton for the best practices. [discrete] ==== GCP Cloud Functions [source,ruby] ------------------------------------ require 'functions_framework' require 'elasticsearch' client = Elasticsearch::Client.new( cloud_id: "elasic-cloud-id", user: "elastic", password: "password", log: true ) FunctionsFramework.http "hello_world" do |request| client.search( index: 'stack-overflow', body: { query: { match: { title: { query: 'phone application' } } } } ) end ------------------------------------ [discrete] ==== AWS Lambda [source,ruby] ------------------------------------ require 'elasticsearch' def client @client ||= Elasticsearch::Client.new( cloud_id: "elastic-cloud-id", user: "elastic", password: "password", log: true ) end def lambda_handler(event:, context:) client.search( index: 'stack-overflow', body: { query: { match: { title: { query: 'phone application' } } } } ) end ------------------------------------ Resources used to assess these recommendations: * https://cloud.google.com/functions/docs/bestpractices/tips#use_global_variables_to_reuse_objects_in_future_invocations[GCP Cloud Functions: Tips & Tricks] * https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html[Best practices for working with AWS Lambda functions] [discrete] [[client-comp]] === Enabling the Compatibility Mode The Elasticsearch server version 8.0 is introducing a new compatibility mode that allows you a smoother upgrade experience from 7 to 8. In a nutshell, you can use the latest 7.x Elasticsearch client with an 8.x Elasticsearch server, giving more room to coordinate the upgrade of your codebase to the next major version. If you want to leverage this functionality, please make sure that you are using the latest 7.x client and set the environment variable `ELASTIC_CLIENT_APIVERSIONING` to `true`. The client is handling the rest internally. For every 8.0 and beyond client, you're all set! The compatibility mode is enabled by default. elastic-elasticsearch-ruby-c38be0c/docs/dsl.asciidoc000066400000000000000000000010101462737751600226420ustar00rootroot00000000000000[[dsl]] === Elasticsearch DSL The https://github.com/elastic/elasticsearch-dsl-ruby[elasticsearch-dsl] gem provides a Ruby API for the https://www.elasticsearch.com/guide/en/elasticsearch/reference/current/query-dsl.html[Elasticsearch Query DSL]. The library allows to programmatically build complex search definitions for {es} in Ruby, which are translated to Hashes, and ultimately, JSON, the language of {es}. See https://github.com/elastic/elasticsearch-dsl-ruby#elasticsearchdsl[the README] for more information. elastic-elasticsearch-ruby-c38be0c/docs/examples.asciidoc000066400000000000000000000172411462737751600237130ustar00rootroot00000000000000[[examples]] == Examples Below you can find examples of how to use the most frequently called APIs with the Ruby client. * <> * <> * <> * <> * <> * <> * <> * <> [discrete] [[ex-index]] === Indexing a document Let's index a document with the following fields: `name`, `author`, `release_date`, and `page_count`: ```ruby body = { name: "The Hitchhiker's Guide to the Galaxy", author: "Douglas Adams", release_date: "1979-10-12", page_count: 180 } client.index(index: 'books', body: body) ``` [discrete] [[ex-get]] === Getting a document You can get a document by ID: ```ruby id = 'l7LRjXgB2_ry9btNEv_V' client.get(index: 'books', id: id) ``` [discrete] [[ex-update]] === Updating a document Assume you have the following document: ``` book = {"name": "Foundation", "author": "Isaac Asimov", "release_date": "1951-06-01", "page_count": 224} ``` You can update the document by using the following script: ```ruby response = client.index(index: 'books', body: book) id = response['_id'] client.update(index: 'books', id: id, body: { doc: { page_count: 225 } }) ``` [discrete] [[ex-delete]] === Deleting a document You can delete a document by ID: ```ruby id = 'l7LRjXgB2_ry9btNEv_V' client.delete(index: 'books', id: id) ``` [discrete] [[ex-bulk]] === Bulk requests The `bulk` operation of the client supports various different formats of the payload: array of strings, header/data pairs, or the combined format where data is passed along with the header in a single item in a custom `:data` key. Index several documents in one request: ```ruby body = [ { index: { _index: 'books', _id: '42' } }, { name: "The Hitchhiker's Guide to the Galaxy", author: 'Douglas Adams', release_date: '1979-10-12', page_count: 180}, { index: { _index: 'books', _id: '43' } }, { name: 'Snow Crash', author: 'Neal Stephenson', release_date: '1992-06-01', page_count: 470 }, { index: { _index: 'books', _id: '44' } }, { name: 'Starship Troopers', author: 'Robert A. Heinlein', release_date: '1959-12-01', page_count: 335} ] client.bulk(body: body) ``` Delete several documents: ```ruby body = [ { delete: { _index: 'books', _id: '42' } }, { delete: { _index: 'books', _id: '43' } }, ] client.bulk(body: body) ``` As mentioned, you can perform several operations in a single request with the combined format passing data in the `:data` option: ```ruby body = [ { index: { _index: 'books', _id: 45, data: { name: '1984', author: 'George Orwell', release_date: '1985-06-01', page_count: 328 } } }, { update: { _index: 'books', _id: 43, data: { doc: { page_count: 471 } } } }, { delete: { _index: 'books', _id: 44 } } ] client.bulk(body: body) ``` [discrete] [[ex-search]] === Searching for a document This example uses the same data that is used in the https://www.elastic.co/guide/en/elasticsearch/reference/current/find-structure.html#find-structure-example-nld-json[Find structure API documentation]. First, bulk index it: [source,ruby] ---- body = [ { index: { _index: 'books', data: {name: "Leviathan Wakes", "author": "James S.A. Corey", "release_date": "2011-06-02", "page_count": 561} } }, { index: { _index: 'books', data: {name: "Hyperion", "author": "Dan Simmons", "release_date": "1989-05-26", "page_count": 482} } }, { index: { _index: 'books', data: {name: "Dune", "author": "Frank Herbert", "release_date": "1965-06-01", "page_count": 604} } }, { index: { _index: 'books', data: {name: "Dune Messiah", "author": "Frank Herbert", "release_date": "1969-10-15", "page_count": 331} } }, { index: { _index: 'books', data: {name: "Children of Dune", "author": "Frank Herbert", "release_date": "1976-04-21", "page_count": 408} } }, { index: { _index: 'books', data: {name: "God Emperor of Dune", "author": "Frank Herbert", "release_date": "1981-05-28", "page_count": 454} } }, { index: { _index: 'books', data: {name: "Consider Phlebas", "author": "Iain M. Banks", "release_date": "1987-04-23", "page_count": 471} } }, { index: { _index: 'books', data: {name: "Pandora's Star", "author": "Peter F. Hamilton", "release_date": "2004-03-02", "page_count": 768} } }, { index: { _index: 'books', data: {name: "Revelation Space", "author": "Alastair Reynolds", "release_date": "2000-03-15", "page_count": 585} } }, { index: { _index: 'books', data: {name: "A Fire Upon the Deep", "author": "Vernor Vinge", "release_date": "1992-06-01", "page_count": 613} } }, { index: { _index: 'books', data: {name: "Ender's Game", "author": "Orson Scott Card", "release_date": "1985-06-01", "page_count": 324} } }, { index: { _index: 'books', data: {name: "1984", "author": "George Orwell", "release_date": "1985-06-01", "page_count": 328} } }, { index: { _index: 'books', data: {name: "Fahrenheit 451", "author": "Ray Bradbury", "release_date": "1953-10-15", "page_count": 227} } }, { index: { _index: 'books', data: {name: "Brave New World", "author": "Aldous Huxley", "release_date": "1932-06-01", "page_count": 268} } }, { index: { _index: 'books', data: {name: "Foundation", "author": "Isaac Asimov", "release_date": "1951-06-01", "page_count": 224} } }, { index: { _index: 'books', data: {name: "The Giver", "author": "Lois Lowry", "release_date": "1993-04-26", "page_count": 208} } }, { index: { _index: 'books', data: {name: "Slaughterhouse-Five", "author": "Kurt Vonnegut", "release_date": "1969-06-01", "page_count": 275} } }, { index: { _index: 'books', data: {name: "The Hitchhiker's Guide to the Galaxy", "author": "Douglas Adams", "release_date": "1979-10-12", "page_count": 180} } }, { index: { _index: 'books', data: {name: "Snow Crash", "author": "Neal Stephenson", "release_date": "1992-06-01", "page_count": 470} } }, { index: { _index: 'books', data: {name: "Neuromancer", "author": "William Gibson", "release_date": "1984-07-01", "page_count": 271} } }, { index: { _index: 'books', data: {name: "The Handmaid's Tale", "author": "Margaret Atwood", "release_date": "1985-06-01", "page_count": 311} } }, { index: { _index: 'books', data: {name: "Starship Troopers", "author": "Robert A. Heinlein", "release_date": "1959-12-01", "page_count": 335} } }, { index: { _index: 'books', data: {name: "The Left Hand of Darkness", "author": "Ursula K. Le Guin", "release_date": "1969-06-01", "page_count": 304} } }, { index: { _index: 'books', data: {name: "The Moon is a Harsh Mistress", "author": "Robert A. Heinlein", "release_date": "1966-04-01", "page_count": 288 } } } ] client.bulk(body: body) ---- The `field` parameter is a common parameter, so it can be passed in directly in the following way: ```ruby client.search(index: 'books', q: 'dune', field: 'name') ``` You can do the same by using body request parameters: ```ruby client.search(index: 'books', q: 'dune', body: { fields: [{ field: 'name' }] }) response = client.search(index: 'books', body: { size: 15 }) response['hits']['hits'].count # => 15 ``` [discrete] [[ex-scroll]] === Scrolling Submit a search API request that includes an argument for the scroll query parameter, save the search ID, then print out the book names you found: ```ruby # Search request with a scroll argument: response = client.search(index: 'books', scroll: '10m') # Save the scroll id: scroll_id = response['_scroll_id'] # Print out the names of all the books we find: while response['hits']['hits'].size.positive? response = client.scroll(scroll: '5m', body: { scroll_id: scroll_id }) puts(response['hits']['hits'].map { |r| r['_source']['name'] }) end ``` [discrete] [[ex-reindex]] === Reindexing The following example shows how to reindex the `books` index into a new index called `books-reindexed`: ```ruby client.reindex(body: {source: { index: 'books'}, dest: {index: 'books-reindexed' } }) ``` elastic-elasticsearch-ruby-c38be0c/docs/index.asciidoc000066400000000000000000000006351462737751600232030ustar00rootroot00000000000000= Elasticsearch Ruby Client :doctype: book include::{asciidoc-dir}/../../shared/attributes.asciidoc[] include::overview.asciidoc[] include::installation.asciidoc[] include::connecting.asciidoc[] include::config.asciidoc[] include::basic-config.asciidoc[] include::advanced-config.asciidoc[] include::integrations.asciidoc[] include::examples.asciidoc[] include::release_notes/index.asciidoc[]elastic-elasticsearch-ruby-c38be0c/docs/installation.asciidoc000066400000000000000000000024731462737751600245770ustar00rootroot00000000000000[[ruby-install]] == Installation Install the Rubygem for the latest {es} version by using the following command: [source,sh] ------------------------------------ gem install elasticsearch ------------------------------------ Or add the `elasticsearch` Ruby gem to your Gemfile: [source,ruby] ------------------------------------ gem 'elasticsearch' ------------------------------------ You can install the Ruby gem for a specific {es} version by using the following command: [source,sh] ------------------------------------ gem install elasticsearch -v 7.0.0 ------------------------------------ Or you can add a specific version of {es} to your Gemfile: [source,ruby] ------------------------------------ gem 'elasticsearch', '~> 7.0' ------------------------------------ [discrete] === {es} and Ruby Version Compatibility The {es} client is compatible with currently maintained Ruby versions. We follow Ruby’s own maintenance policy and officially support all currently maintained versions per https://www.ruby-lang.org/en/downloads/branches/[Ruby Maintenance Branches]. Language clients are forward compatible; meaning that clients support communicating with greater or equal minor versions of {es}. Elasticsearch language clients are only backwards compatible with default distributions and without guarantees made. elastic-elasticsearch-ruby-c38be0c/docs/integrations.asciidoc000066400000000000000000000005611462737751600246000ustar00rootroot00000000000000[[integrations]] == Integrations The Rubygems listed on this page make it easier to operate with {es} by using the Ruby client. * <> * <> * <> * <> * <> include::transport.asciidoc[] include::model.asciidoc[] include::rails.asciidoc[] include::persistence.asciidoc[] include::dsl.asciidoc[] elastic-elasticsearch-ruby-c38be0c/docs/model.asciidoc000066400000000000000000000040231462737751600231670ustar00rootroot00000000000000[[activemodel_activerecord]] === ActiveModel / ActiveRecord The `elasticsearch-model` http://rubygems.org/gems/elasticsearch-model[Rubygem] provides integration with Ruby domain objects ("models"), commonly found for example, in Ruby on Rails applications. It uses the `elasticsearch` Rubygem as the client communicating with the {es} cluster. [discrete] ==== Features * ActiveModel integration with adapters for ActiveRecord and Mongoid * Enumerable-based wrapper for search results * ActiveRecord::Relation-based wrapper for returning search results as records * Convenience model methods such as `search`, `mapping`, `import`, etc * Support for Kaminari and WillPaginate pagination * Extension implemented via proxy object to shield model namespace from collisions * Convenience methods for (re)creating the index, setting up mappings, indexing documents, ... [discrete] ==== Usage Add the library to your Gemfile: [source,ruby] ------------------------------------ gem 'elasticsearch-rails' ------------------------------------ Include the extension module in your model class: [source,ruby] ------------------------------------ class Article < ActiveRecord::Base include Elasticsearch::Model end ------------------------------------ Import some data and perform a search: [source,ruby] ------------------------------------ Article.import response = Article.search 'fox dog' response.took # => 3 ------------------------------------ It is possible to either return results as model instances, or decorated documents from {es}, with the `records` and `results` methods, respectively: [source,ruby] ------------------------------------ response.records.first # Article Load (0.4ms) SELECT "articles".* FROM "articles" WHERE ... => #
response.results.first._score # => 0.02250402 response.results.first._source.title # => "Quick brown fox" ------------------------------------ Consult the https://github.com/elastic/elasticsearch-rails/tree/master/elasticsearch-model[documentation] for more information. elastic-elasticsearch-ruby-c38be0c/docs/overview.asciidoc000066400000000000000000000042511462737751600237400ustar00rootroot00000000000000[[ruby_client]] == Overview The `elasticsearch` http://rubygems.org/gems/elasticsearch[Rubygem] provides a low-level client for communicating with an {es} cluster, fully compatible with other official clients. More documentation is hosted in https://github.com/elastic/elasticsearch-ruby[Github] and http://rubydoc.info/gems/elasticsearch[RubyDoc]. [discrete] === Features * Pluggable logging and tracing * Pluggable connection selection strategies (round-robin, random, custom) * Pluggable transport implementation, customizable and extendable * Pluggable serializer implementation * Request retries and dead connections handling * Node reloading (based on cluster state) on errors or on demand * Modular API implementation * 100% REST API coverage [discrete] [[transport-api]] === Transport and API The `elasticsearch` gem combines three separate Rubygems: * https://github.com/elastic/elasticsearch-ruby/tree/7.16/elasticsearch-transport[`elasticsearch-transport`] provides an HTTP Ruby client for connecting to the {es} cluster, * https://github.com/elastic/elasticsearch-ruby/tree/7.16/elasticsearch-api[`elasticsearch-api`] provides a Ruby API for the {es} RESTful API. * https://github.com/elastic/elasticsearch-ruby/tree/7.16/elasticsearch-xpack/[`elasticsearch-xpack`] provides a Ruby API for the {es} RESTful API for X-Pack endpoints. Notice that the API endpoints living in `elasticsearch-xpack` will be moved into `elasticsearch-api` in version 8.0.0 and forward. You should be able to keep using `elasticsearch-xpack` and the `xpack` namespace in `7.x` versions. We're running the same tests in `elasticsearch-xpack`, but if you encounter any problems, please let us know https://github.com/elastic/elasticsearch-ruby/issues/1274[in this issue]. Please consult their respective documentation for configuration options and technical details. Notably, the documentation and comprehensive examples for all the API methods are contained in the source, and available online at http://rubydoc.info/gems/elasticsearch-api/Elasticsearch/API/Actions[Rubydoc]. Keep in mind, that for optimal performance, you should use an HTTP library which supports persistent ("keep-alive") HTTP connections. elastic-elasticsearch-ruby-c38be0c/docs/persistence.asciidoc000066400000000000000000000073231462737751600244210ustar00rootroot00000000000000[[persistence]] === Persistence The `elasticsearch-persistence` http://rubygems.org/gems/elasticsearch-persistence[Rubygem] provides persistence layer for Ruby domain objects. It supports the repository design patterns. Versions before 6.0 also supported the _active record_ design pattern. [discrete] ==== Repository The `Elasticsearch::Persistence::Repository` module provides an implementation of the repository pattern and allows to save, delete, find and search objects stored in {es}, as well as configure mappings and settings for the index. [discrete] ===== Features * Access to the {es} client * Setting the index name, document type, and object class for deserialization * Composing mappings and settings for the index * Creating, deleting or refreshing the index * Finding or searching for documents * Providing access both to domain objects and hits for search results * Providing access to the {es} response for search results * Defining the methods for serialization and deserialization [discrete] ===== Usage Let's have a simple plain old Ruby object (PORO): [source,ruby] ------------------------------------ class Note attr_reader :attributes def initialize(attributes={}) @attributes = attributes end def to_hash @attributes end end ------------------------------------ Create a default, "dumb" repository, as a first step: [source,ruby] ------------------------------------ require 'elasticsearch/persistence' class MyRepository; include Elasticsearch::Persistence::Repository; end repository = MyRepository.new ------------------------------------ Save a `Note` instance into the repository: [source,ruby] ------------------------------------ note = Note.new id: 1, text: 'Test' repository.save(note) # PUT http://localhost:9200/repository/_doc/1 [status:201, request:0.210s, query:n/a] # > {"id":1,"text":"Test"} # < {"_index":"repository","_type":"note","_id":"1","_version":1,"created":true} ------------------------------------ Find it: [source,ruby] ------------------------------------ n = repository.find(1) # GET http://localhost:9200/repository/_doc/1 [status:200, request:0.003s, query:n/a] # < {"_index":"repository","_type":"note","_id":"1","_version":2,"found":true, "_source" : {"id":1,"text":"Test"}} => 1, "text"=>"Test"}> ------------------------------------ Search for it: [source,ruby] ------------------------------------ repository.search(query: { match: { text: 'test' } }).first # GET http://localhost:9200/repository/_search [status:200, request:0.005s, query:0.002s] # > {"query":{"match":{"text":"test"}}} # < {"took":2, ... "hits":{"total":1, ... "hits":[{ ... "_source" : {"id":1,"text":"Test"}}]}} => 1, "text"=>"Test"}> ------------------------------------ Delete it: [source,ruby] ------------------------------------ repository.delete(note) # DELETE http://localhost:9200/repository/_doc/1 [status:200, request:0.014s, query:n/a] # < {"found":true,"_index":"repository","_type":"note","_id":"1","_version":3} => {"found"=>true, "_index"=>"repository", "_type"=>"note", "_id"=>"1", "_version"=>2} ------------------------------------ The repository module provides a number of features and facilities to configure and customize the behaviour, as well as support for extending your own, custom repository class. Please refer to the https://github.com/elastic/elasticsearch-rails/tree/master/elasticsearch-persistence#the-repository-pattern[documentation] for more information. Also, check out the https://github.com/elastic/elasticsearch-rails/tree/master/elasticsearch-persistence#example-application[example application] which demonstrates the usage patterns of the _repository_ approach to persistence. elastic-elasticsearch-ruby-c38be0c/docs/rails.asciidoc000066400000000000000000000011751462737751600232060ustar00rootroot00000000000000[[ruby_on_rails]] === Ruby On Rails The `elasticsearch-rails` http://rubygems.org/gems/elasticsearch-rails[Rubygem] provides features suitable for Ruby on Rails applications. [discrete] ==== Features * Rake tasks for importing data from application models * Integration with Rails' instrumentation framework * Templates for generating example Rails application [discrete] ==== Example applications You can generate a fully working example Ruby on Rails application with templates provides. Please refer to the https://github.com/elastic/elasticsearch-rails/tree/master/elasticsearch-rails[documentation] for more information. elastic-elasticsearch-ruby-c38be0c/docs/release_notes/000077500000000000000000000000001462737751600232205ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/docs/release_notes/70.asciidoc000066400000000000000000000220451462737751600251510ustar00rootroot00000000000000[[release_notes_70]] === 7.0 Release notes This version contains the following changes: * Added `elastic_ruby_console` executable. It opens a console with the elasticsearch gems you have installed required. * Added macro benchmarking framework, available when developing. Use `rake -T` to view all available benchmarking tasks. [discrete] ==== Client * Fixed failing integration test * Updated the Manticore development dependency * Fixed a failing Manticore unit test * Removed "turn" and switched the tests to Minitest * Fixed integration tests for Patron * Allow passing request headers in `perform_request` * Added integration test for passing request headers in `perform_request` * Added, that request headers are printed in trace output, if set * Fix typos in elasticsearch-transport/README.md * Assert that connection count is at least previous count when reloaded * Adjust test for change in default number of shards on ES 7 * Abstract logging functionality into a Loggable Module (#556) * Convert client integration tests to rspec * Add flexible configuration in spec helper * Use helper methods in spec_helper * Remove minitest client integration tests in favor of rspec test * Convert tests to rspec and refactor client * minor changes to the client specs * Use pry-nav in development for JRuby * Keep arguments variable name for now * Skip round-robin test for now * Mark test as pending until there is a better way to detect rotating nodes * Remove client unit test in favor of rspec test * Comment-out round-robin test as it occasionally passes and pending is ineffective * Document the default host and port constant * Add documentation to spec_helper methods * Redacted password if host info is printed in error message * Adds tests for not including password in logged error message * The redacted string change will be in 6.1.1 * Add more tests for different ways to specify client host argument * Do not duplicate connections in connection pool after rebuild (#591) * Ensure that the spec rake task is run as part of integration tests * Use constant to define Elasticsearch hosts and avoid yellow status when number of nodes is 1 * Update handling of publish_address in _nodes/http response * Add another test for hostname/ipv6:port format [discrete] ==== API * Added the `wait_for_active_shards` parameter to the "Indices Open" API * Added the "Indices Split" API * Added the `wait_for_no_initializing_shards` argument to the "Cluster Health" API * Added the "Cluster Remote Info" API * Remove the dependency on "turn" * Clear cluster transient settings in test setups * Use `YAML.load_documents` in the REST tests runner * Removed pinning dependency for Minitest * Replaced the testing framework from Test::Unit to Minites and improved test output * Added, that trace logs are printed when the `TRACE` environment variable is set * Removed the "turn" dependency from generated test_helper.rb * Update the "Delete By Query" API to support :slices * Speed up `Elasticsearch::API::Utils.__listify` * Speed up `Elasticsearch::API::Utils.__pathify` * Use "String#strip" and "String.empty?" in `Utils.__pathify` * Updated the inline documentation for using scripts in the "Update" API * Updated the "Scroll" API inline example with passing the scroll ID in the body * Marked the `percolate` method as deprecated and added an example for current percolator * Fixed, that `Utils.__report_unsupported_parameters` and `Utils.__report_unsupported_method` use `Kernel.warn` so they can be suppressed * Fixed the "greedy" regex in the `Utils.__rescue_from_not_found` method * Fixed the incorrect `create` method * Allow passing headers in `perform_request` * Set application/x-ndjson content type on Bulk and Msearch requests * Update the Reindex API to support :slices * Fixed and improved the YAML tests runner * Added the `include_type_name` parameter to APIs * Fixed the helper for unit tests * Removed the requirement for passing the `type` parameter to APIs * Removed dead code from the YAML tests runner * Fixed the `api:code:generate` Thor task * Add copy_settings as valid param to split API * Port api/actions tests to rspec (#543) * Update tests to not require type * Account for escape_utils not being available for JRuby * Add nodes/reload_secure_settings endpoint support (#546) * Add new params for search and msearch API * Retrieve stashed variable if referenced in test * Convert cat API tests to rspec * Convert cluster API tests to rspec * Convert indices tests to rspec * Fix documentation of #indices.analyze * Avoid instantiating an array of valid params for each request, each time it is called (#550) * Add headers to custom client documentation (#527) * Fix typos in README * Minor update to scroll documentation example * Convert snapshot, ingest, tasks, nodes api tests to rspec * Update source_includes and source_excludes params names for mget * Update source_includes and source_excludes params names for get, search, bulk, explain * Update source_includes and source_excludes params names for get_source * Mark _search endpoint as deprecated * Link to 6.0 documentation explicitly for _suggest deprecation * Update documentation for msearch * Update documentation for scroll_id to be in body of scroll endpoint * Remove reference to deprecated format option for _analyze endpoint * Correct endpoints used for get and put search template * Fix minor typo * Note that a non-empty body argument is required for the bulk api * Add note about empty body in yard documentation * Support if_primary_term param on index API * Delete test2 template in between tests in case a test is not cleanup up properly * Support ignore_throttled option on search API * Updates for types removal changes * Add missing update param * Add missing params to methods * Support if_primary_term param for delete * Delete an index and index template not cleaned up after in rest api tests * Update supported params for cat API endpoints * Update supported params for cluster API endpoints * Update supported params for indices API endpoints * Update supported params for ingest API endpoints * Update supported params for nodes API endpoints * Update supported params for snapshot API endpoints * Update missed node API endpoints * Update missed tasks API endpoints * Update top-level api endpoints * Adjust specs and code after test failures * Fix accidental overwrite of index code * Add missing param in cat/thread_pool * The type argument is not required in the index method * Delete 'nomatch' template to account for lack of test cleanup * Ensure that the :index param is supported for cat.segments * Ensure that the :name param is passed to the templates API [discrete] ==== DSL * Add inner_hits option support for has_parent query * Add inner_hits option support for has_child query * Add inner_hits option support for has_parent filter * Add inner_hits option support for has_child filter * adds query support for nested queries in filter context (#531) * Convert aggregations/pipeline tests to rspec (#564) * Convert aggregations tests to rspec (#566) * Convert filters tests to rspec (#567) * Fix bug in applying no_match_filter to indices filter * Update test for current elasticsearch version * Fix integration tests for join field syntax * Update agg scripted metric test for deprecation in ES issue #29328 * Fix script in update for #29328 * minor: fix spacing * Convert queries tests to rspec (#569) * Add inner_hits test after cherry-picking rspec conversion * Remove tests already converted to rspec * spec directory structure should mirror code directory structure * Support query_string type option * Ensure that filters are registered when called on bool queries (#609) * Don't specify a type when creating mappings in tests [discrete] ==== X-Pack * Embedded the source code for the `elasticsearch-xpack` Rubygem * Fixed the `setup` for YAML integration tests * Added missing X-Pack APIs * Improved the YAML integration test runner * Updated the Rakefile for running integration tests * Added, that password for Elasticsearch is generated * Fixed the Watcher example * Updated the README * Added gitignore for the `elasticsearch-xpack` Rubygem * Add ruby-prof as a development dependency * Handle multiple roles passed to get_role_mapping * Minor updates to xpack api methods (#586) * Support freeze and unfreeze APIs * Rewrite xpack rest api yaml test handler (#585) * Updates to take into account SSL settings * Fix mistake in testing version range so test can be skipped * Support set_upgrade_mode machine learning API * Support typed_keys and rest_total_hits_as_int params for rollup_search * Improve string output for xpack rest api tests * Fix logic in version checking * Support if_seq_no and if_primary_term in put_watch * Don't test execute_watch/60_http_input because of possible Docker issue * Support api key methods * Fix minor typo in test description * Fix issue with replacing argument value with an Integer value * Support transform_and_set in yaml tests * Skip two more tests * Run security tests against elasticsearch 7.0.0-rc2 * Account for error when forecast_id is not provided and legacy path is used * Blacklist specific tests, not the whole file * Fix version check for skipping testelastic-elasticsearch-ruby-c38be0c/docs/release_notes/710.asciidoc000066400000000000000000000052051462737751600252310ustar00rootroot00000000000000[[release_notes_710]] === 7.10 Release notes [discrete] [[release_notes_7101]] === 7.10.1 Release notes [discrete] ==== Client - Updates for connecting with Cloud. [discrete] [[release_notes_7100]] === 7.10 Release notes [discrete] ==== Client - Support for Elasticsearch version `7.10.0`. - Fixes a bug when building the complete endpoint URL could end with duplicate slashes `//`. - Fixes a bug when building the complete endpoint URL with cloud id could end with duplicate ports https://github.com/elastic/elasticsearch-ruby/issues/1081[#1081]. [discrete] ==== API - Fix in RubyDoc comments, some parameters were being duplicated. - Deprecation notice: Synced flush (`indices.flush_synced`) is deprecated and will be removed in 8.0. Use flush instead. [discrete] ===== New API Endpoints - `snapshot.clone` [discrete] ===== API Changes - `bulk`, `index`, `update`: new parameter `require_alias` (boolean): When true, requires destination to be an alias (default: false) for `index` and `update`. For `bulk` it sets `require_alias` for all incoming documents. Defaults to unset (false). [discrete] ==== X-Pack Deprecation notice: `searchable_snapshots.repository_stats` is deprecated and is replaced by the Repositories Metering API. [discrete] ===== New API Endpoints - `close_point_in_time` - `open_point_in_time` - `security.clear_api_key_cache` - `security.grant_api_key` [discrete] ===== API Changes - `cat.ml_datafeeds`, `cat.ml_jobs`, `machine_learning.close_job`, `machine_learning.get_datafeed_stats`, `machine_learning.get_datafeeds`, `machine_learning.get_job_stats`, `machine_learning.get_jobs`, `machine_learning.get_overall_buckets`, `machine_learning.stop_datafeed`: new parameter `allow_no_match` (boolean): Whether to ignore if a wildcard expression matches no datafeeds (this includes `_all` string or when no datafeeds have been specified). -`machine_learning.get_data_frame_analytics`: new parameter `verbose` (boolean), whether the stats response should be verbose. - `machine_learning.get_trained_models`: new parameter `include` (string), a comma-separate list of fields to optionally include. Valid options are 'definition' and 'total_feature_importance'. Default is none. - `machine_learning.stop_datafeed`: endpoint now accepts a `body`: the URL params optionally sent in the body. - `security.get_role`, `security/get_role_mapping`: The name parameter is now a comma-separated list of role-mapping names. - `machine_learning.delete_trained_model`, `machine_learning.get_trained_models`, `machine_learning.get_trained_models_stats`, `machine_learning.put_trained_model`: Internal change, url changed from `_ml/inference` to `_ml/trained_models`. elastic-elasticsearch-ruby-c38be0c/docs/release_notes/711.asciidoc000066400000000000000000000063571462737751600252430ustar00rootroot00000000000000[[release_notes_711]] === 7.11 Release notes [discrete] [[release_notes_7112]] === 7.11.2 Release notes [discrete] ==== Client * Bug fix in meta header, fixes fail when http adapter library hasn't been loaded yet: https://github.com/elastic/elasticsearch-ruby/issues/1224[Issue]. [discrete] [[release_notes_7111]] === 7.11.1 Release notes [discrete] ==== Client * Bug fix in meta header, adds support for unknown Faraday adapters. https://github.com/elastic/elasticsearch-ruby/pull/1204[Pull Request]. [discrete] [[release_notes_7110]] === 7.11.0 Release notes [discrete] ==== Client - Support for Elasticsearch version `7.11.0`. - Fixes a bug with headers in our default Faraday class. https://github.com/elastic/elasticsearch-ruby/commit/9c4afc452467cc6344359b54b98bbe5af1469219[Commit]. - Adds the `X-Elastic-Client-Meta` HTTP header which is used by Elastic Cloud and can be disabled with the `enable_meta_header` parameter set to `false`. [discrete] ==== API - `cat.tasks` - Parameter `node_id` changes name to `nodes`, a comma-separated list of node IDS or names. Parameter `parent_task` changes name to `parent_task_id`. - APIs that are no longer experimental: `cluster.delete_component_template`, `cluster.exists_component_template`, `cluster.get_component_template`, `cluster.put_component_template`, `indices.delete_index_template`, `indices.exists_index_template`, `indices.get_index_template`, `indices.put_index_template`, `indices.simulate_index_template`, `indices.simulate_template`. - Deprecation notice: The _upgrade API is no longer useful and will be removed. Instead, see `_reindex API`. Deprecated since version 8.0.0. Endpoints: `indices.get_upgrade`, `indices.upgrade` [discrete] ==== X-Pack - New endpoints:`async_search.status`, `autoscaling.get_autoscaling_capacity` (experimental), `indices.migrate_to_data_stream`, `indices.promote_data_stream`, `machine_learning.upgrade_job_snapshot`, `rollup.rollup`, `watcher.query_watches`. - APIs that are no longer experimental: `eql.delete`, `eql.get`, `eql.search`, - APIs promoted from experimental to beta: `machine_learning.delete_data_frame_analytics`, `ml.delete_trained_model`, `machine_learning.evaluate_data_frame`, `machine_learning.explain_data_frame_analytics`, `machine_learning.get_data_frame_analytics`, `machine_learning.get_datafeed_stats`, `machine_learning.get_trained_models`, `machine_learning.get_trained_models_stats`, `machine_learning.put_data_frame_analytics`, `machine_learning.put_trained_model`, `machine_learning.start_data_frame_analytics`, `machine_learning.stop_data_frame_analytics`, `machine_learning.update_data_frame_analytics` - `indices.delete_data_stream`, `indices.get_data_stream` add parameter `expand_wildcards`, wether wildcard expressions should get expanded to open or closed indices (default: open). Options: open, closed, hidden, none, all. - `machine_learning.get_data_frame_analytics`, `machine_learning.get_datafeeds`, `machine_learning.get_jobs`, `machine_learning.get_trained_models`, `transform.get_transform` add parameter `exclude_generated` - omits fields that are illegal to set on PUT. - `data_frame_transform_deprecated.get_transform` (_data_frame/transforms/ is deprecated, use _transform/ in the future) adds parameter `exclude_generated` - omits generated files. elastic-elasticsearch-ruby-c38be0c/docs/release_notes/712.asciidoc000066400000000000000000000037301462737751600252340ustar00rootroot00000000000000[[release_notes_712]] === 7.12 Release notes [discrete] ==== Client - Support for Elasticsearch version 7.12.0 - Ruby 3 is now tested, it was added to the entire test suite. - New official documentation pages for configuration: https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/current/basic-config.html[Basic Configuration] and https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/current/advanced-config.html[Advanced Configuration]. - Integration tests runner refactored to keep skipped tests in a yaml file. [discrete] ==== API - New API namespace: `features` and endpoints `features.get_features` and `snapshot.get_features`. - `cat.plugins` adds parameter `include_bootstrap`: Include bootstrap plugins in the response. - Update in `indices.close` parameter `wait_for_active_shards`: Sets the number of active shards to wait for before the operation returns. Set to `index-setting` to wait according to the index setting `index.write.wait_for_active_shards`, or `all` to wait for all shards, or an integer. Defaults to `0`. - `actions.search` adds parameter `min_compatible_shard_node`: The minimum compatible version that all shards involved in search should have for this request to be successful. [discrete] ==== X-Pack - New API namespace: `text_structure` and endpoints `text_structure.find_structure`. - New API namespace: `logstash` and endpoints `logstash.delete_pipeline`, `logstash.get_pipeline`, `logstash.put_pipeline`. - New API: `eql.get_status`. - APIs migrated from experimental to stable: `autoscaling.delete_autoscaling_policy`, `autoscaling.get_autoscaling_capacity`, `autoscaling.get_autoscaling_policy`, `autoscaling.put_autoscaling_policy`. - `searchable_snapshots.mount` adds parameter `storage`: Selects the kind of local storage used to accelerate searches. Experimental, and defaults to `full_copy`. - `searchable_snapshots.stats` adds parameter `level`: Return stats aggregated at cluster, index or shard level (options: cluster, indices, shards). elastic-elasticsearch-ruby-c38be0c/docs/release_notes/713.asciidoc000066400000000000000000000060721462737751600252370ustar00rootroot00000000000000[[release_notes_713]] === 7.13 Release notes [discrete] [[release_notes_7133]] === 7.13.3 Release notes - API Support for Elasticsearch version 7.13.3 [discrete] [[release_notes_7132]] === 7.13.2 Release notes - Mute release, yanked from RubyGems. [discrete] [[release_notes_7131]] === 7.13.1 Release notes [discrete] ==== Client - Support for Elasticsearch version 7.13.1 - Fixes thread safety issue in `get_connection` - https://github.com/elastic/elasticsearch-ruby/pull/1325[Pull Request]. [discrete] [[release_notes_7130]] === 7.13.0 Release notes [discrete] ==== Client - Support for Elasticsearch version 7.13.0 - Adds support for compatibility header for Elasticsearch. If the environment variable 'ELASTIC_CLIENT_APIVERSIONING' is set to `true` or `1`, the client will send the headers `Accept` and `Content-Type` with the following value: `application/vnd.elasticsearch+json;compatible-with=7`. - Better detection of Elasticsearch and Enterprise Search clients in the meta header used by cloud. [discrete] ==== API - The REST API tests now use an artifact downloaded from the Elastic servers instead of depending of cloning `elasticsearch` locally. Check the README for more information. - New parameter `include_unloaded_segments` in `cat.nodes`, `nodes.stats`: If set to true segment stats will include stats for segments that are not currently loaded into memory - New parameter `summary` in `ingest.get_pipeline`: Return pipelines without their definitions (default: false) - New parameter `index_details` in `snapshot.get`: Whether to include details of each index in the snapshot, if those details are available. Defaults to false. - New endpoint `features.reset_features`, `ingest/geo_ip_stats` - New experimental endpoints: `shutdown.delete_node`, `shutdown.get_node`, `shutdown.put_node`. [discrete] ==== X-Pack - Refactored test tasks, made it easier to run the tests by default. - New experimental endpoints: `fleet.global_checkpoints`, `searchable_snapshots.cache_stats`. - New beta endpoints: `security.clear_cached_service_tokens`, `security.create_service_token`, `security.delete_service_token`, `security.get_service_accounts`, `security.get_service_credentials` - New endpoints: `machine_learning.delete_trained_model_alias`, `machine_learning.preview_data_frame_analytics`, `machine_learning.put_trained_model_alias`. - APIs migrated from experimental or beta to stable: `machine_learning.delete_data_frame_analytics`, `machine_learning.delete_trained_model`, `machine_learning.estimate_model_memory`, `machine_learning.explain_data_frame_analytics`, `machine_learning.get_data_frame_analytics`, `machine_learning.get_data_frame_analytics_stats`, `machine_learning.get_trained_models`, `machine_learning.get_trained_models_stats`, `machine_learning.put_data_frame_analytics`, `machine_learning.put_trained_model`, `machine_learning.start_data_frame_analytics`, `machine_learning.stop_data_frame_analytics`, `machine_learning.update_data_frame_analytics` - New parameter `body` in `machine_learning.preview_datafeed`: The datafeed config and job config with which to execute the preview. elastic-elasticsearch-ruby-c38be0c/docs/release_notes/714.asciidoc000066400000000000000000000106251462737751600252370ustar00rootroot00000000000000[[release_notes_714]] === 7.14 Release notes [discrete] [[release_notes_7141]] === 7.14.1 Release notes [discrete] ==== Client - Fixes for Manticore Implementation: Addresses custom headers on initialization (https://github.com/elastic/elasticsearch-ruby/commit/3732dd4f6de75365460fa99c1cd89668b107ef1c[3732dd4]) and fixes tracing (https://github.com/elastic/elasticsearch-ruby/commit/3c48ebd9a783988d1f71bfb9940459832ccd63e4[3c48ebd]). Related to https://github.com/elastic/elasticsearch-ruby/issues/1426[#1426] and https://github.com/elastic/elasticsearch-ruby/issues/1428[#1428]. [discrete] [[release_notes_7140]] === 7.14.0 Release notes [discrete] ==== Client Added check that client is connected to an Elasticsearch cluster. If the client isn't connected to a supported Elasticsearch cluster the `UnsupportedProductError` exception will be raised. This release changes the way in which the transport layer and the client interact. Previously, when using `elasticsearch-transport`, `Elasticsearch::Transport::Client` had a convenient wrapper, so it could be used as `Elasticsearch::Client`. Now, we are decoupling the transport layer from the Elasticsearch client. If you're using the `elasticsearch` gem, not much will change. It will instantiate a new `Elasticsearch::Transport::Client` when you instantiate `Elasticsearch::Client` and the endpoints from `elasticsearch-api` will be available. `Elasticsearch::Client` has an `attr_accessor` for the transport instance: [source,ruby] ------------------------------------ > client = Elasticsearch::Client.new > client.transport.class => Elasticsearch::Transport::Client > client.transport.transport.class => Elasticsearch::Transport::Transport::HTTP::Faraday ------------------------------------ The interaction with `elasticsearch-api` remains unchanged. You can use the API endpoints just like before: [source,ruby] ------------------------------------ > client.info => {"name"=>"instance", "cluster_name"=>"elasticsearch", "cluster_uuid"=>"id", "version"=> {"number"=>"7.14.0", ... }, "tagline"=>"You Know, for Search"} ------------------------------------ Or perform request directly from the client which will return an `Elasticsearch::Transport::Response` object: [source,ruby] ------------------------------------ > client.perform_request('GET', '/') # This is the same as doing client.transport.perform_request('GET', '/') => #"instance", "cluster_name"=>"elasticsearch", "cluster_uuid"=>"id", "version"=> {"number"=>"7.14.0-SNAPSHOT", ... }, "tagline"=>"You Know, for Search"}, @headers= {"content-type"=>"application/json; charset=UTF-8", "content-length"=>"571", ... }, @status=200> ------------------------------------ If you have any problems, please report them in https://github.com/elastic/elasticsearch-ruby/issues/1344[this issue]. [discrete] ==== API Code is now generated from Elastic artifacts instead of checked out code of Elasticsearch. See https://github.com/elastic/elasticsearch-ruby/blob/7.14/elasticsearch-api/utils/README.md#generate[the Generator README] for more info. - Endpoints `msearch`, `msearch_template` and `search_template` remove `query_and_fetch` and `dfs_query_and_fetch` options from the `search_type` parameter. - New parameter `include_repository` in `snapshot.get`: (boolean) Whether to include the repository name in the snapshot info. Defaults to true. [discrete] ==== X-Pack X-Pack is being deprecated. The first time using `xpack` on the client, a warning will be triggered. Please check https://github.com/elastic/elasticsearch-ruby/issues/1274[this issue] for more information. - New endpoints: `index_lifecycle_management.migrate_to_data_tiers`, `machine_learning.reset_job`, `security.saml_authenticate`, `security.saml_complete_logout`, `security.saml_invalidate`, `security.saml_logout`, `security.saml_prepare_authentication`, `security.saml_service_provider_metadata`, `sql.delete_async`, `sql.get_async`, `sql.get_async_status`, `terms_enum`. - New experimental endpoints: `machine_learning.infer_trained_model_deployment`, `machine_learning.start_trained_model_deployment`, `machine_learning.stop_trained_model_deployment`. - Deprecation: `indices.freeze` and `indices.unfreeze`: Frozen indices are deprecated because they provide no benefit given improvements in heap memory utilization. They will be removed in a future release. elastic-elasticsearch-ruby-c38be0c/docs/release_notes/715.asciidoc000066400000000000000000000020511462737751600252320ustar00rootroot00000000000000[[release_notes_715]] === 7.15 Release notes [discrete] ==== Client - Support for Elasticsearch v7.15.0 APIs. - We've tested and added documentation on best practices for leveraging the client in a Function-as-a-Service (FaaS) environment to the https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/current/connecting.html#client-faas[official docs]. [discrete] ==== API - New experimental endpoints: `indices.disk_usage`. `indices.field_usage_stats`, `nodes.clear_repositories_metering_archive`, `get_repositories_metering_info`, https://www.elastic.co/guide/en/elasticsearch/reference/7.15/search-vector-tile-api.html[`search_mvt`] - The `index` parameter is now required for `open_point_in_time`. - The `index_metric` parameter in `nodes.stats` adds the `shards` option. [discrete] ==== X-Pack - New parameters for `ml.put_job`: `ignore_unavailable`, `allow_no_indices`, `ignore_throttled`, `expand_wildcards`. - New endpoint: https://www.elastic.co/guide/en/elasticsearch/reference/7.15/security-api-query-api-key.html[`security.query_api_keys`]. elastic-elasticsearch-ruby-c38be0c/docs/release_notes/716.asciidoc000066400000000000000000000120571462737751600252420ustar00rootroot00000000000000[[release_notes_716]] === 7.16 Release notes [discrete] [[release_notes_7163]] === 7.16.3 Release notes ==== API Bugfix for https://github.com/elastic/elasticsearch-ruby/issues/1475[#1475], an issue where if you indexed a document with an id such as `an id`, it would get escaped to `an+id` instead of `an%20id` when using `index` or `create`. This would result in the document id being `an+id` instead of the intended value `an id`. [discrete] [[release_notes_7162]] === 7.16.2 Release notes No release. [discrete] [[release_notes_7161]] === 7.16.1 Release notes Patch release corresponding with Elastic Stack version 7.16.1 that addresses the Apache Log4j2 vulnerability, https://discuss.elastic.co/t/apache-log4j2-remote-code-execution-rce-vulnerability-cve-2021-44228-esa-2021-31/291476[more information]. ==== Client The only changes in the client since 7.16.0 are a few minor updates for the https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/current/connecting.html#client-comp[Compatibility mode with 8.0]. We added the compatibility header in `7.13.0`, but now we have integration tests and compatibility tests for version `7.x` of the client with Elasticsearch `8.0`. [discrete] [[release_notes_7160]] === 7.16.0 Release notes [discrete] ==== Client - Adds the `delay_on_retry` parameter, a value in milliseconds to wait between each failed connection, thanks https://github.com/DinoPullerUqido[DinoPullerUqido]! https://github.com/elastic/elasticsearch-ruby/pull/1521[Pull Request] and https://github.com/elastic/elasticsearch-ruby/pull/1523[backport]. - Adds *CA fingerprinting*. You can configure the client to only trust certificates that are signed by a specific CA certificate (CA certificate pinning) by providing a `ca_fingerprint` option. This will verify that the fingerprint of the CA certificate that has signed the certificate of the server matches the supplied value. The verification will be run once per connection. Code example: [source,ruby] ------------------------------------ ca_fingerprint = '64F2593F...' client = Elasticsearch::Client.new( host: 'https://elastic:changeme@localhost:9200', transport_options: { ssl: { verify: false } }, ca_fingerprint: ca_fingerprint ) ------------------------------------ - Fixes compression. When `compression` is set to `true`, the client will now gzip the request body properly and use the appropiate headers. Thanks https://github.com/johnnyshields[johnnyshields]! https://github.com/elastic/elasticsearch-ruby/pull/1478[Pull Request] and https://github.com/elastic/elasticsearch-ruby/pull/1526[backport]. - Warnings emitted by Elasticsearch are now logged via `log_warn` through the Loggable interface in the client, instead of using `Kernel.warn`. https://github.com/elastic/elasticsearch-ruby/pull/1517[Pull Request]. [discrete] ==== API - Cleaned up some deprecated code. - `count` - The API is documented as using `GET`, but it supports both GET and POST on the Elasticsearch side. So it was updated to only use `POST` when there's a body present, or else use `GET`. Elasticsearch would still accept a body with `GET`, but to be more semantically correct in the clients we use `POST` when there's a body. - `delete_index_template` was updated to support the `ignore_404` parameter to ignore 404 errors when attempting to delete a non-existing template. - `ingest.put_pipeline` adds new parameter `if_version`: Required version for optimistic concurrency control for pipeline updates. - `ml.put_trained_model`: adds new parameter `defer_definition_decompression`: If set to `true` and a `compressed_definition` is provided, the request defers definition decompression and skips relevant validations. - `nodes.hot_threads` adds new parameter `sort`: The sort order for 'cpu' type (default: total) (options: cpu, total). - `open_point_in_time`: `keep_alive` is now a required parameter. - `search_mvt`: adds new parameter `track_total_hits`: Indicate if the number of documents that match the query should be tracked. A number can also be specified, to accurately track the total hit count up to the number. - `transform.preview_transform`: adds new parameter `transform_id`. Body is now optional and the API will use `GET` or `POST` depending on the presence of a body. *APIs promoted from experimental to stable since last version:* - `fleet.global_checkpoints` - `get_script_context` - `get_script_language` - `indices.resolve_index` - `monitoring.bulk` - `rank_eval` - `searchable_snapshots.mount` - `searchable_snapshots.stats` - `security.clear_cached_service_tokens` - `security.create_service_token` - `security.delete_service_token` - `security.get_service_accounts` - `security.get_service_credentials` - `shutdown.delete_node` - `shutdown.get_node` - `shutdown.put_node` - `terms_enum` *New APIs* - `fleet.mseach` - `fleet.search` - `indices.modify_data_stream` - `ml.infer_trained_model_deployment` - `ml.start_trained_model_deployment` - `ml.stop_trained_model_deployment` - `migration.get_feature_upgrade_status` - `migration.post_feature_upgrade_status` - `security.enroll_kibana` - `security.enroll_node` - `transform.updgrade_transforms` elastic-elasticsearch-ruby-c38be0c/docs/release_notes/717.asciidoc000066400000000000000000000101561462737751600252410ustar00rootroot00000000000000[[release_notes_717]] === 7.17 Release notes [discrete] [[release_notes_71711]] === 7.17.11 Release notes - Ruby 3.3 added to the test matrix. Tested versions of Ruby for 7.17.11: Ruby (MRI) 3.0, 3.1, 3.2, 3.3, JRuby 9.3, JRuby 9.4. - Adds `base64` dependency to `elasticsearch-transport`: base64 was added to the gemspec, since starting in Ruby 3.4.0, base64 will no longer be part of the default gems and will no longer be in the standard library, https://github.com/elastic/elasticsearch-ruby/pull/2400[#2400]. [discrete] [[release_notes_71710]] === 7.17.10 Release notes Backports support for Faraday 2 from `elastic-transport`. ¡Gracias https://github.com/santiagorodriguez96[santiagorodriguez96]! This version of the gem now supports Faraday v2. If you don't have a locked version of Faraday in your project, when you upgrade your gems, Faraday v2 will be installed. The main change on dependencies when using Faraday v2 is all adapters, except for the default `net_http` one, have been moved out of Faraday into separate gems. This means if you're not using the default adapter and you migrate to Faraday v2, you'll need to add the adapter gems to your Gemfile. These are the gems required for the different adapters with Faraday 2, instead of the libraries on which they were based: [source,ruby] ------------------------------------ # HTTPCLient gem 'faraday-httpclient' # NetHTTPPersistent gem 'faraday-net_http_persistent' # Patron gem 'faraday-patron' # Typhoeus gem 'faraday-typhoeus' ------------------------------------ Things should work fine if you migrate to Faraday 2 as long as you include the adapter (unless you're using the default one `net-http`), but worst case scenario, you can always lock the version of Faraday in your project to 1.x: gem 'faraday', '~> 1' Be aware if migrating to Faraday v2 that it requires at least Ruby `2.6`, unlike Faraday v1 which requires `2.4`. *Troubleshooting* If you see a message like: [source,ruby] ------------------------------------ :adapter is not registered on Faraday::Adapter (Faraday::Error) ------------------------------------ Then you probably need to include the adapter library in your gemfile and require it. Please https://github.com/elastic/elasticsearch-ruby/issues[submit an issue] if you encounter any problems. [discrete] [[release_notes_7179]] === 7.17.9 Release notes - Backports fix from `elastic-transport`, fixes https://github.com/elastic/elastic-transport-ruby/issues/66[#66]: Manticore transport unable to send custom headers with `perform_request` https://github.com/elastic/elastic-transport-ruby/pull/69[Pull Request]. [discrete] [[release_notes_7178]] === 7.17.8 Release notes - Patch releases back to being detached from Elastic stack releases. - Tested compatibility with latest releases of Elasticsearch v7.17 APIs. - Tested versions of Ruby for 7.17.8: Ruby (MRI) 2.7, 3.0, 3.1, 3.2, JRuby 9.3, JRuby 9.4. - Bugfix in elasticsearch-transport: Fixes enforcing UTF-8 in Response body, causing an error when the string is frozen, particularly when using webmock: https://github.com/elastic/elastic-transport-ruby/issues/63[issue #63]. [discrete] [[release_notes_7177]] === 7.17.7 Release notes - Compatibility with Elasticsearch v7.17.7 APIs. - Tested versions of Ruby for 7.17.7: Ruby (MRI) 2.6, 2.7, 3.0 and 3.1, JRuby 9.3. [discrete] [[release_notes_7172]] === 7.17.2, 7.17.3, 7.17.4, 7.17.5, 7.17.6 Release notes No release. [discrete] [[release_notes_7171]] === 7.17.1 Release notes - Improves handling of YAML parsing, uses `safe_load` instead of `load` when doing the product verification (should only affect Ruby < 3.0). - Updates headers setup when using the Manticore adapter. This fixes an issue where the user-agent header was being foverridden even when it was being set on initialization via the transport options. https://github.com/elastic/elasticsearch-ruby/pull/1685[Pull Request], https://github.com/elastic/elasticsearch-ruby/issues/1684[issue]. [discrete] [[release_notes_7170]] === 7.17.0 Release notes - Drops Ruby 2.5 from the test matrix. Support for Ruby 2.5 was dropped March 2021. - Updates the product verification when the response is a `413` error. elastic-elasticsearch-ruby-c38be0c/docs/release_notes/75.asciidoc000066400000000000000000000055501462737751600251600ustar00rootroot00000000000000[[release_notes_75]] === 7.5 Release notes - Support for Elasticsearch 7.5. - Update API spec generator: The code for Elasticsearch OSS and X-Pack APIs is being generated from the rest api spec. - Specs have been updated to address new/deprecated parameters. - Ruby versions tested: 2.3.8, 2.4.9, 2.5.7, 2.6.5 and 2.7.0 (new). [discrete] ==== API Endpoints that changed: - `_bulk`: body is now required as an argument. - `cat`: `local` and `master_timeout` parameters are gone. - `health`: New parameter `health`. - `indices`: Adds `time` and `include_unload_segments` parameters. - `nodes`: Adds `bytes`, `time` parameters. - `pending_tasks`: Adds `time` parameter. - `recovery`: Adds `active_only`, `detailed`, `index`, `time` parameters. - `segments`: Removes `index` parameter and it's now a url part. - `shards`: Adds `time` parameter. - `snapshots`: Adds `time` parameter. - `tasks`: Adds `time` parameter. - `templates`: The `name` parameter is now passed in as a part but not a parameter. - `thread_pool`: The `thread_pool_patterns` parameter is now passed in as a part but not as a parameter. - `cluster` - `put_settings`: body is required. - `state`: `index_templates` is gone. - `node_id` is now a url part. - `delete` - `parent` parameter is gone. - `delete_by_query`: `analyzer` parameters are gone, `max_docs` is a new parameter, `body` is now a required parameter. - `delete_by_query_rethrottle` new endpoint. - `delete_by_rethrottle` - uses `delete_by_query_rethrottle` and hasn't changed. - `exists`, `exists_source`, `explain`: `parent` parameter is gone. - `field_caps`: `fields` param is no longer required. - `get`: `parent` parameter is gone - `get_source`: `parent` parameter is gone - `index`: `body` parameter is required, `wait_for_shard` is a new parameter, `consistency`, `include_type_name`, `parent`, `percolate`, `replication`, `timestamp`, `ttl` parameters are gone - `indices` - `get`: `feature` paramatere was deprecated and is gone. - `delete_aliases`, `put_alias`: URL changed internally to 'aliases' instead of 'alias' but shouldn't affect the client's API. - `render_search_template`: `id` is now a part not a parameter - `search`: `fielddata_fields`, `include_type_name`, `fields`, `ignore_indices`, `lowercase_expanded_terms`, `query_cache`, `source` parameters are gone, `ccs_minimize_roundtrips`, `track_scores` are new parameters. - `tasks` - `list`: task_id is not supported anymore, it's in get now. - `termvectors`: `parent` parameter is gone. - `update`: `version` parameter is not supported anymore. [discrete] ==== X-Pack Some urls changed internally to remove `_xpack`, but it shouldn't affect the client's API. - `explore`: `index` is now required. - `info`: `human` parameter is gone. - `migration`: some endpoints are gone: `get_assistance`, `get_assistance_test` and `upgrade_test`. - `watcher`: `restart` endpoint is gone. elastic-elasticsearch-ruby-c38be0c/docs/release_notes/76.asciidoc000066400000000000000000000062351462737751600251620ustar00rootroot00000000000000[[release_notes_76]] === 7.6 Release notes [discrete] ==== Client * Support for Elasticsearch version 7.6. * Last release supporting Ruby 2.4. Ruby 2.4 has reached it's end of life and no more security updates will be provided, users are suggested to update to a newer version of Ruby. [discrete] ===== API Key Support The client now supports API Key Authentication, check "Authentication" on the https://github.com/elastic/elasticsearch-ruby/tree/7.x/elasticsearch-transport#authentication[transport README] for information on how to use it. [discrete] ===== X-Opaque-Id Support The client now supports identifying running tasks with X-Opaque-Id. Check https://github.com/elastic/elasticsearch-ruby/tree/7.x/elasticsearch-transport#identifying-running-tasks-with-x-opaque-id[transport README] for information on how to use X-Opaque-Id. [discrete] ===== Faraday migrated to 1.0 We're now using version 1.0 of Faraday: * The client initializer was modified but this should not disrupt final users at all, check this commit for more information. * Migrated error checking to remove the deprecated Faraday::Error namespace. * *This change is not compatible with https://github.com/typhoeus/typhoeus[Typhoeus]*. The latest release is 1.3.1, but it's https://github.com/typhoeus/typhoeus/blob/v1.3.1/lib/typhoeus/adapters/faraday.rb#L100[still using the deprecated `Faraday::Error` namespace]. This has been fixed on master, but the last release was November 6, 2018. Version 1.4.0 should be ok once it's released. * Note: Faraday 1.0 drops official support for JRuby. It installs fine on the tests we run with JRuby in this repo, but it's something we should pay attention to. Reference: https://github.com/lostisland/faraday/blob/master/UPGRADING.md[Upgrading - Faraday 1.0] https://github.com/elastic/elasticsearch-ruby/pull/808[Pull Request] [discrete] ==== API [discrete] ===== API Changes: - `cat.indices`: argument `bytes` options were: `b,k,m,g` and are now `b,k,kb,m,mb,g,gb,t,tb,p,pb`. - `delete_by_query`: New parameter `analyzer` - The analyzer to use for the query string. - `indices.put_template`: Removed parameters: `timeout`, `flat_settings`. - `msearch_template`: New Parameter `ccs_minimize_roundtrips` - Indicates whether network round-trips should be minimized as part of cross-cluster search requests execution. - `rank_eval`: New parameter `search_type` - Search operation type (options: `query_then_fetch,dfs_query_then_fetch`). - `search_template`: New parameter `ccs_minimize_roundtrips` - Indicates whether network round-trips should be minimized as part of cross-cluster search requests execution. [discrete] ===== New API endpoints: - `get_script_context` - `get_script_languages` [discrete] ===== Warnings: Synced flush is deprecated and will be removed in 8.0. [discrete] ==== X-Pack [discrete] ===== New API endpoints: - `ml/delete_trained_model` - `ml/explain_data_frame_analytics` - `ml/get_trained_models` - `ml/get_trained_models_stats` - `ml/put_trained_model` [discrete] ===== API changes: - `license/get`: Added parameter `accept_enterprise`. - `ml/delete_data_frame_analytics` Added parameter `force`. - `monitoring/bulk` - Removed parameter `system_version`.elastic-elasticsearch-ruby-c38be0c/docs/release_notes/77.asciidoc000066400000000000000000000044571462737751600251670ustar00rootroot00000000000000[[release_notes_77]] === 7.7 Release notes This version drops support for Ruby 2.4 since it's reached it's end of life. [discrete] ==== Client - Support for Elasticsearch version `7.7` [discrete] ===== Custom Headers You can set custom HTTP headers on the client's initializer or pass them as a parameter to any API endpoint. https://github.com/elastic/elasticsearch-ruby/tree/7.x/elasticsearch-transport#custom-http-headers[More info and code examples]. [discrete] ==== API [discrete] ===== API Changes - Clean: Removes up some deprecated endpoints: `abort_benchmark`, `benchmark`, `delete_by_rethrottle`, `nodes.shutdown`, `remote.info`. - `expand_wildcards` Whether to expand wildcard expressions to concrete indices that are open, closed or both. Options: open, closed, hidden, none, all. `hidden` option is new. It was also added to the following endpoints: `cat.aliases`, `cat.indices`. - `delete_by_query`: Parameter `slices` can now be set to `auto`. - `reindex`: Parameter `slices` can now be set to `auto`. - `update_by_query`: Parameter `slices` can now be set to `auto`. - `snapshot.cleanup_repository`: Parameter `body` is removed. [discrete] ===== New API Endpoints - `cluster.delete_component_template` - `cluster.get_component_template` - `cluster.put_component_template` - `indices.create_data_stream` (experimental) - `indices.delete_data_stream` (experimental) - `indices.get_data_stream` (experimental) [discrete] ==== X-Pack [discrete] ===== API Changes - `machine_learing.get_trained_models`: New parameter `tags` - `machine_learning.put_datafeed`, `machine_learning.update_datafeed`: Added parameters `ignore_unavailable`, `allow_no_indices`, `ignore_throttled`, `expand_wildcards` - `reload_secure_settings`: New parameter `body`, an object containing the password for the keystore. [discrete] ===== New API Endpoints - `async_search.delete` - `async_search.get` - `async_search.submit` - `cat.ml_data_frame_analytics` - `cat.ml_datafeeds` - `cat.ml_jobs` - `cat.ml_trained_models` - `cat.transform` - `cat.transforms` - `machine_learning.estimate_model_memory` - `transform.delete_transform` - `transform.get_transform` - `transform.get_transform_stats` - `transform.preview_transform` - `transform.put_transform` - `transform.start_transform` - `transform.stop_transform` - `transform.update_transform`elastic-elasticsearch-ruby-c38be0c/docs/release_notes/78.asciidoc000066400000000000000000000061041462737751600251570ustar00rootroot00000000000000[[release_notes_78]] === 7.8 Release notes [discrete] [[release_notes_781]] === 7.8.1 Release notes [discrete] ==== Client - Support for Elasticsearch version `7.8.1`. - Bug fix: Fixed a bug on the API endpoints documentation for RubyDocs: there was an unnecessary empty new line in the documentation for parameters that have options. So the parameters before that empty newline were not being documented in RubyDocs. [discrete] ==== X-Pack [discrete] ===== API Changes - Update to `info` endpoint. New parameter `accept_enterprise` (boolean): If an enterprise license is installed, return the type and mode as 'enterprise' (default: false). [discrete] [[release_notes_780]] === 7.8.0 Release notes [discrete] ==== Client - Support for Elasticsearch version `7.8`. - Surface deprecation headers from Elasticsearch. When there's a `warning` response header in Elasticsearch's response, the client will emit a warning with `warn`. - Typhoeus is supported again, version 1.4+ and has been added back to the docs. - Adds documentation and example for integrating with Elastic APM. [discrete] ==== API [discrete] ===== New API Endpoints - `abort_benchmark` - `benchmark` - `cluster.delete_voting_config_exclusions` - `cluster.post_voting_config_exclusions` - `delete_by_rethrottle` - `nodes.shutdown` - `remote.info` Experimental endpoints: - `cluster.delete_component_template` - `cluster.exists_component_template` - `cluster.get_component_template` - `cluster.put_component_template` - `indices.delete_index_template` - `indices.exists_index_template` - `indices.get_index_template` - `indices.put_index_template` - `indices.simulate_index_template` [discrete] ===== API Changes - `cat/thread_pool`: `size` is deprecated. - `indices.get_data_streams`: `name` is now a string instead of list, the name or wildcard expression of the requested data streams. - `indices.put_index_template`: new parameter: `cause` (string), user defined reason for creating/updating the index template. - `indices.simulate_index_template`: Two new parameters: `create`, whether the index template we optionally defined in the body should only be dry-run added if new or can also replace an existing one. `cause` User defined reason for dry-run creating the new template for simulation purposes. - `snapshot.delete_repository`: New parameter `repository`, name of the snapshot repository, wildcard (`*`) patterns are now supported. - `task.cancel`: new parameter `wait_for_completion` (boolean) Should the request block until the cancellation of the task and its descendant tasks is completed. Defaults to false. [discrete] ==== X-Pack [discrete] ===== New API Endpoints New namespace: `indices` - `indices.freeze` - `indices.reload_search_analyzers` - `indices.unfreeze` New namespace: `searchable_snapshots` - `clear_cache` - `mount` - `repository_stats` - `stats` [discrete] ===== API Changes - `machine_learning.delete_expired_data` new param `body`: deleting expired data parameters. - `machine_learning.delete_data_frame_analytics` new param `timeout`: controls the time to wait until a job is deleted. Defaults to 1 minute.elastic-elasticsearch-ruby-c38be0c/docs/release_notes/79.asciidoc000066400000000000000000000061501462737751600251610ustar00rootroot00000000000000[[release_notes_79]] === 7.9 Release notes [discrete] ==== Client - Support for Elasticsearch version `7.9.0`. - Transport/Connection: Considers attributes values for equality - https://github.com/elastic/elasticsearch-ruby/commit/06ffd03bf51f5f33a0d87e9914e66b39357d40af[Commit]. - When an API endpoint accepts both `GET` and `POST`, the client will always use `POST` when a request body is present. [discrete] ==== API - Documentation for API endpoints will point out when an API is experimental, beta or unstable. [discrete] ===== New API Endpoints - New namespace: `dangling_indices` - `dangling_indices.delete_dangling_index` - `dangling_indices.import_dangling_index` - `dangling_indices.list_dangling_indices` - `indices.add_block` Experimental endpoints: - `indices.resolve_index` - `simulate_template` [discrete] ===== API Changes - `field_caps`: adds body parameter allowing to filter indices if `index_filter` is provided. - `eql.search`: new parameters `wait_for_completion`, `keep_on_completion` and `keep_alive`. - `info`: New parameter `accept_enterprise`: If an enterprise license is installed, return the type and mode as 'enterprise' (default: false). - `indices.put_mapping`: new parameter `write_index_only`. [discrete] ==== X-Pack [discrete] ===== New API Endpoints The Ruby client now supports all the X-Pack API endpoints. - New namespace `autoscaling`: `autoscaling.delete_autoscaling_policy`, `autoscaling.get_autoscaling_decision`, `autoscaling.get_autoscaling_policy`, `autoscaling.put_autoscaling_policy` - New namespace `enrich`: `enrich.delete_policy`, `enrich.execute_policy`, `enrich.get_policy`, `enrich.put_policy`, `enrich.stats` - New namespace `eql`: `eql.delete`, `eql.get`, `eql.search` - New namespace `cross_cluster_replication`: `cross_cluster_replication.delete_auto_follow_pattern`, `cross_cluster_replication.follow`, `cross_cluster_replication.follow_info`, `cross_cluster_replication.follow_stats`, `cross_cluster_replication.forget_follower`, `cross_cluster_replication.get_auto_follow_pattern`, `cross_cluster_replication.pause_auto_follow_pattern`, `cross_cluster_replication.pause_follow`, `cross_cluster_replication.put_auto_follow_pattern`, `cross_cluster_replication.resume_auto_follow_pattern`, `cross_cluster_replication.resume_follow`, `cross_cluster_replication.stats`, `cross_cluster_replication.unfollow` - New namespace `snapshot_lifecycle_management`: `snapshot_lifecycle_management.delete_lifecycle`, `snapshot_lifecycle_management.execute_lifecycle`, `snapshot_lifecycle_management.execute_retention`, `snapshot_lifecycle_management.get_lifecycle`, `snapshot_lifecycle_management.get_stats`, `snapshot_lifecycle_management.get_status`, `snapshot_lifecycle_management.put_lifecycle`, `snapshot_lifecycle_management.start`, `snapshot_lifecycle_management.stop` - `indices.create_data_stream` - `indices.data_streams_stats` - `indices.delete_data_stream` - `indices.get_data_stream` - `security.clear_cached_privileges` - `machine_learning.update_data_frame_analytics` [discrete] ===== API Changes - `machine_learning.delete_expired_data`: new parameters `job_id`, `requests_per_second` and `timeout`elastic-elasticsearch-ruby-c38be0c/docs/release_notes/index.asciidoc000066400000000000000000000017371462737751600260370ustar00rootroot00000000000000[[release_notes]] == Release Notes [discrete] === 7.x * <> * <> * <> * <> * <> * <> * <> * <> * <> * <> * <> * <> * <> * <> include::717.asciidoc[] include::716.asciidoc[] include::715.asciidoc[] include::714.asciidoc[] include::713.asciidoc[] include::712.asciidoc[] include::711.asciidoc[] include::710.asciidoc[] include::79.asciidoc[] include::78.asciidoc[] include::77.asciidoc[] include::76.asciidoc[] include::75.asciidoc[] include::70.asciidoc[] elastic-elasticsearch-ruby-c38be0c/docs/transport.asciidoc000066400000000000000000000161141462737751600241270ustar00rootroot00000000000000[[transport]] === Transport The `elasticsearch-transport` library provides a low-level Ruby client for connecting to an {es} cluster. It handles connecting to multiple nodes in the cluster, rotating across connections, logging and tracing requests and responses, maintaining failed connections, discovering nodes in the cluster, and provides an abstraction for data serialization and transport. It does not handle calling the {es} API. For optimal performance, use a HTTP library which supports persistent ("keep-alive") connections, such as https://github.com/toland/patron[patron] or https://github.com/typhoeus/typhoeus[Typhoeus]. Require the library (require 'patron') in your code, and it will be automatically used. [discrete] [[transport-install]] ==== Installation Install the package from https://rubygems.org/[Rubygems]: ``` gem install elasticsearch-transport ``` To use an unreleased version, either add it to your `Gemfile` for http://gembundler.com/[Bundler]: ``` gem 'elasticsearch-transport', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git' ``` or install it from a source code checkout: ``` git clone https://github.com/elasticsearch/elasticsearch-ruby.git cd elasticsearch-ruby/elasticsearch-transport bundle install rake install ``` [discrete] [[transport-example-usage]] ==== Example usage In the simplest form, connect to {es} running on http://localhost:9200 without any configuration: ```ruby require 'elasticsearch/transport' client = Elasticsearch::Client.new response = client.perform_request('GET', '_cluster/health') # => # ``` Full documentation is available at http://rubydoc.info/gems/elasticsearch-transport. [discrete] [[transport-implementations]] ==== Transport implementations By default, the client uses the https://rubygems.org/gems/faraday[Faraday] HTTP library as a transport implementation. It auto-detects and uses an adapter for Faraday based on gems loaded in your code, preferring HTTP clients with support for persistent connections. To use the https://github.com/toland/patron[Patron] HTTP, for example, require it: ``` require 'patron' ``` Then, create a new client, and the Patron gem will be used as the "driver": ```ruby client = Elasticsearch::Client.new client.transport.connections.first.connection.builder.adapter # => Faraday::Adapter::Patron 10.times do client.nodes.stats(metric: 'http')['nodes'].values.each do |n| puts "#{n['name']} : #{n['http']['total_opened']}" end end # => Stiletoo : 24 # => Stiletoo : 24 # => Stiletoo : 24 # => ... ``` To use a specific adapter for Faraday, pass it as the `adapter` argument: ```ruby client = Elasticsearch::Client.new adapter: :net_http_persistent client.transport.connections.first.connection.builder.handlers # => [Faraday::Adapter::NetHttpPersistent] ``` To pass options to the https://github.com/lostisland/faraday/blob/master/lib/faraday/connection.rb[`Faraday::Connection`] constructor, use the `transport_options` key: ```ruby client = Elasticsearch::Client.new transport_options: { request: { open_timeout: 1 }, headers: { user_agent: 'MyApp' }, params: { :format => 'yaml' }, ssl: { verify: false } } ``` To configure the Faraday instance directly, use a block: ```ruby require 'patron' client = Elasticsearch::Client.new(host: 'localhost', port: '9200') do |f| f.response :logger f.adapter :patron end ``` You can use any standard Faraday middleware and plugins in the configuration block. You can also initialize the transport class yourself, and pass it to the client constructor as the `transport` argument: ```ruby require 'patron' transport_configuration = lambda do |f| f.response :logger f.adapter :patron end transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new \ hosts: [ { host: 'localhost', port: '9200' } ], &transport_configuration # Pass the transport to the client # client = Elasticsearch::Client.new transport: transport ``` Instead of passing the transport to the constructor, you can inject it at run time: ```ruby # Set up the transport # faraday_configuration = lambda do |f| f.instance_variable_set :@ssl, { verify: false } f.adapter :excon end faraday_client = Elasticsearch::Transport::Transport::HTTP::Faraday.new \ hosts: [ { host: 'my-protected-host', port: '443', user: 'USERNAME', password: 'PASSWORD', scheme: 'https' }], &faraday_configuration # Create a default client # client = Elasticsearch::Client.new # Inject the transport to the client # client.transport = faraday_client ``` You can also use a bundled https://rubygems.org/gems/curb[Curb] based transport implementation: ```ruby require 'curb' require 'elasticsearch/transport/transport/http/curb' client = Elasticsearch::Client.new transport_class: Elasticsearch::Transport::Transport::HTTP::Curb client.transport.connections.first.connection # => # ``` It's possible to customize the Curb instance by passing a block to the constructor as well (in this case, as an inline block): ```ruby transport = Elasticsearch::Transport::Transport::HTTP::Curb.new \ hosts: [ { host: 'localhost', port: '9200' } ], & lambda { |c| c.verbose = true } client = Elasticsearch::Client.new transport: transport ``` You can write your own transport implementation by including the {Elasticsearch::Transport::Transport::Base} module, implementing the required contract, and passing it to the client as the `transport_class` parameter – or by injecting it directly. [discrete] [[transport-architecture]] ==== Transport architecture * `Elasticsearch::Transport::Client` is composed of `Elasticsearch::Transport::Transport`. * `Elasticsearch::Transport::Transport` is composed of `Elasticsearch::Transport::Transport::Connections`, and an instance of logger, tracer, serializer and sniffer. * Logger and tracer can be any object conforming to Ruby logging interface, for example, an instance of https://ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html[`Logger`], https://rubygems.org/gems/log4r[log4r], https://github.com/TwP/logging/[logging], and so on. * The `Elasticsearch::Transport::Transport::Serializer::Base` implementations handle converting data for {es} (for example, to JSON). You can implement your own serializer. * `Elasticsearch::Transport::Transport::Sniffer` allows to discover nodes in the cluster and use them as connections. * `Elasticsearch::Transport::Transport::Connections::Collection` is composed of `Elasticsearch::Transport::Transport::Connections::Connection` instances and a selector instance. * `Elasticsearch::Transport::Transport::Connections::Connection` contains the connection attributes such as hostname and port, as well as the concrete persistent "session" connected to a specific node. * The `Elasticsearch::Transport::Transport::Connections::Selector::Base` implementations allow to choose connections from the pool, for example, in a round-robin or random fashion. You can implement your own selector strategy. elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/000077500000000000000000000000001462737751600230215ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/.gitignore000066400000000000000000000002321462737751600250060ustar00rootroot00000000000000*.gem *.rbc .bundle .config .yardoc Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/Gemfile000066400000000000000000000031231462737751600243130ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. source 'https://rubygems.org' # Specify your gem's dependencies in elasticsearch-api.gemspec gemspec if File.exist? File.expand_path("../../elasticsearch-transport", __FILE__) gem 'elasticsearch-transport', path: File.expand_path("../../elasticsearch-transport", __FILE__), require: true end if File.exist? File.expand_path("../../elasticsearch/elasticsearch.gemspec", __FILE__) gem 'elasticsearch', path: File.expand_path("../../elasticsearch", __FILE__), require: false end if File.exist? File.expand_path("../../elasticsearch-extensions", __FILE__) gem 'elasticsearch-extensions', path: File.expand_path("../../elasticsearch-extensions", __FILE__), require: false end group :development do gem 'rspec' gem 'rspec_junit_formatter' if defined?(JRUBY_VERSION) gem 'pry-nav' else gem 'pry-byebug', '~> 3.9' end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/LICENSE000066400000000000000000000261361462737751600240360ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/README.md000066400000000000000000000144411462737751600243040ustar00rootroot00000000000000# Elasticsearch::API **This library is part of the [`elasticsearch-ruby`](https://github.com/elasticsearch/elasticsearch-ruby/) package; please refer to it, unless you want to use this library standalone.** ---- The `elasticsearch-api` library provides a Ruby implementation of the [Elasticsearch](http://elasticsearch.com) REST API. It does not provide an Elasticsearch client; see the [`elasticsearch-transport`](https://github.com/elasticsearch/elasticsearch-ruby/tree/master/elasticsearch-transport) library. Language clients are forward compatible; meaning that clients support communicating with greater or equal minor versions of Elasticsearch. Elasticsearch language clients are only backwards compatible with default distributions and without guarantees made. ## Installation Install the package from [Rubygems](https://rubygems.org): ``` gem install elasticsearch-api ``` Or add it to your Gemfile: ``` gem 'elasticsearch-api' ``` ## Usage The library is designed as a group of standalone Ruby modules, which can be mixed into a class providing connection to Elasticsearch -- an Elasticsearch client. It's possible to mix it into any client, and the methods will be available in the top namespace. ### Usage with the `elasticsearch` gem **When you use the client from the [`elasticsearch-ruby`](https://github.com/elasticsearch/elasticsearch-ruby/) package, the library modules have been already included**, so you just call the API methods: ```ruby require 'elasticsearch' client = Elasticsearch::Client.new(log: true) client.index(index: 'myindex', type: 'mytype', id: 1, body: { title: 'Test' }) # => {"_index"=>"myindex", ... "created"=>true} client.search(index: 'myindex', body: { query: { match: { title: 'test' } } }) # => {"took"=>2, ..., "hits"=>{"total":5, ...}} ``` Full documentation is included as RDoc annotations in the source code and available online at . ### Usage with a custom client When you want to mix the library into your own client, it must conform to a following _contract_: * It responds to a `perform_request(method, path, params, body, headers)` method, * the method returns an object with `status`, `body` and `headers` methods. A simple client could look like this (_with a dependency on `active_support` to parse the query params_): ```ruby require 'multi_json' require 'faraday' require 'elasticsearch/api' require 'active_support' class MySimpleClient include Elasticsearch::API CONNECTION = ::Faraday::Connection.new url: 'http://localhost:9200' def perform_request(method, path, params, body, headers = nil) puts "--> #{method.upcase} #{path} #{params} #{body} #{headers}" CONNECTION.run_request \ method.downcase.to_sym, path_with_params(path, params), ( body ? MultiJson.dump(body): nil ), {'Content-Type' => 'application/json'} end private def path_with_params(path, params) return path if params.blank? case params when String "#{path}?#{params}" when Hash "#{path}?#{params.to_query}" else raise ArgumentError, "Cannot parse params: '#{params}'" end end end client = MySimpleClient.new p client.cluster.health # --> GET _cluster/health {} # => "{"cluster_name":"elasticsearch" ... }" p client.index index: 'myindex', type: 'mytype', id: 'custom', body: { title: "Indexing from my client" } # --> PUT myindex/mytype/custom {} {:title=>"Indexing from my client"} # => "{"ok":true, ... }" ``` ### Using JSON Builders Instead of passing the `:body` argument as a Ruby _Hash_, you can pass it as a _String_, potentially taking advantage of JSON builders such as [JBuilder](https://github.com/rails/jbuilder) or [Jsonify](https://github.com/bsiggelkow/jsonify): ```ruby require 'jbuilder' query = Jbuilder.encode do |json| json.query do json.match do json.title do json.query 'test 1' json.operator 'and' end end end end client.search index: 'myindex', body: query # 2013-06-25 09:56:05 +0200: GET http://localhost:9200/myindex/_search [status:200, request:0.015s, query:0.011s] # 2013-06-25 09:56:05 +0200: > {"query":{"match":{"title":{"query":"test 1","operator":"and"}}}} # ... # => {"took"=>21, ..., "hits"=>{"total"=>1, "hits"=>[{ "_source"=>{"title"=>"Test 1", ...}}]}} ``` ### Using Hash Wrappers For a more comfortable access to response properties, you may wrap it in one of the _Hash_ "object access" wrappers, such as [`Hashie::Mash`](https://github.com/intridea/hashie): ```ruby require 'hashie' response = client.search index: 'myindex', body: { query: { match: { title: 'test' } }, aggregations: { tags: { terms: { field: 'tags' } } } } mash = Hashie::Mash.new response mash.hits.hits.first._source.title # => 'Test' mash.aggregations.tags.terms.first # => # ``` ### Using a Custom JSON Serializer The library uses the [MultiJson](https://rubygems.org/gems/multi_json/) gem by default, but allows you to set a custom JSON library, provided it uses the standard `load/dump` interface: ```ruby Elasticsearch::API.settings[:serializer] = JrJackson::Json Elasticsearch::API.serializer.dump({foo: 'bar'}) # => {"foo":"bar"} ``` ## Development To work on the code, clone and bootstrap the main repository first -- please see instructions in the main [README](../README.md#development). To run tests, launch a testing cluster -- again, see instructions in the main [README](../README.md#development) -- and use the Rake tasks: ``` time rake test:unit time rake test:integration ``` We run the test suite for Elasticsearch's Rest API tests. You can read more about this in [the test runner README](https://github.com/elastic/elasticsearch-ruby/tree/master/api-spec-testing#rest-api-yaml-test-runner). The `rest_api` needs the test files from Elasticsearch. You can run the rake task to download the test artifacts in the root folder of the project. This task needs a running cluster to determine which version and build hash of Elasticsearch to use and test against. `TEST_ES_SERVER=http://localhost:9200 rake elasticsearch:download_artifacts`. This will download the necessary files used for the integration tests to `./tmp`. ## License This software is licensed under the [Apache 2 license](./LICENSE). elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/Rakefile000066400000000000000000000076521462737751600245000ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'bundler/gem_tasks' require 'json' task(:default) { system 'rake --tasks' } task test: 'test:unit' # ----- Test tasks ------------------------------------------------------------ require 'rake/testtask' require 'rspec/core/rake_task' namespace :test do desc 'Wait for Elasticsearch to be in a green state' task :wait_for_green do sh '../scripts/wait-cluster.sh' end # Unit tests - rake test:unit # task unit: :spec RSpec::Core::RakeTask.new(:spec) do |t| t.exclude_pattern = 'spec/**{,/*/**}/rest_api_yaml_spec.rb' end desc "Run Rest API Spec tests" RSpec::Core::RakeTask.new(:rest_api) do |t| t.pattern = 'spec/**{,/*/**}/rest_api_yaml_spec.rb' end desc "Run integration tests" task :integration do Rake::Task['test:rest_api'].invoke end desc 'Run unit and integration tests' task :all do Rake::Task['test:unit'].invoke Rake::Task['test:integration'].invoke end def refresh_artifacts(build_hash, version_number) unless build_hash STDERR.puts "[!] Cannot determine checkout build hash -- server not running" exit(1) end puts 'Downloading artifacts file...' filename = 'tmp/artifacts.json' `curl -s https://artifacts-api.elastic.co/v1/versions/#{version_number} -o #{filename}` unless File.exist?("./#{filename}") STDERR.puts '[!] Couldn\'t download artifacts file' exit 1 end artifacts = JSON.parse(File.read('./tmp/artifacts.json')) build_hash_artifact = artifacts['version']['builds'].select do |a| a.dig('projects', 'elasticsearch', 'commit_hash') == build_hash end.first # Dig into the elasticsearch packages, search for the rest-resources-zip package and catch the URL: zip_url = build_hash_artifact.dig('projects', 'elasticsearch', 'packages').select { |k,v| k =~ /rest-resources-zip/ }.map { | _, v| v['url'] }.first filename = zip_url.split('/').last puts 'Downloading zip file:' `curl -s #{zip_url} -o tmp/#{filename}` unless File.exist?("./tmp/#{filename}") STDERR.puts '[!] Couldn\'t download artifact' exit 1 end puts "Unzipping file #{filename}" `unzip -o tmp/#{filename} -d tmp/` end namespace :cluster do desc "Start Elasticsearch nodes for tests" task :start do $LOAD_PATH << File.expand_path('../../elasticsearch-transport/lib', __FILE__) << File.expand_path('../test', __FILE__) require 'elasticsearch/extensions/test/cluster' Elasticsearch::Extensions::Test::Cluster.start end desc "Stop Elasticsearch nodes for tests" task :stop do $LOAD_PATH << File.expand_path('../../elasticsearch-transport/lib', __FILE__) << File.expand_path('../test', __FILE__) require 'elasticsearch/extensions/test/cluster' Elasticsearch::Extensions::Test::Cluster.stop end end end # ----- Documentation tasks --------------------------------------------------- require 'yard' YARD::Rake::YardocTask.new(:doc) do |t| t.options = %w| --embed-mixins --markup=markdown | end # ----- Code analysis tasks --------------------------------------------------- require 'cane/rake_task' Cane::RakeTask.new(:quality) do |cane| cane.abc_max = 15 cane.no_style = true end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/elasticsearch-api.gemspec000066400000000000000000000067341462737751600277610ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'elasticsearch/api/version' Gem::Specification.new do |s| s.name = 'elasticsearch-api' s.version = Elasticsearch::API::VERSION s.authors = ['Karel Minarik'] s.email = ['karel.minarik@elasticsearch.org'] s.summary = 'Ruby API for Elasticsearch.' s.homepage = 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.16/index.html' s.license = 'Apache-2.0' s.metadata = { 'homepage_uri' => 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.16/index.html', 'changelog_uri' => 'https://github.com/elastic/elasticsearch-ruby/blob/7.16/CHANGELOG.md', 'source_code_uri' => 'https://github.com/elastic/elasticsearch-ruby/tree/7.16/elasticsearch-api', 'bug_tracker_uri' => 'https://github.com/elastic/elasticsearch-ruby/issues' } s.files = `git ls-files`.split($/) s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } s.test_files = s.files.grep(%r{^(test|spec|features)/}) s.require_paths = ['lib'] s.extra_rdoc_files = [ 'README.md', 'LICENSE' ] s.rdoc_options = [ '--charset=UTF-8' ] s.required_ruby_version = '>= 2.4' s.add_dependency 'multi_json' s.add_development_dependency 'ansi' s.add_development_dependency 'bundler' s.add_development_dependency 'elasticsearch' s.add_development_dependency 'elasticsearch-transport' s.add_development_dependency 'elasticsearch-xpack' s.add_development_dependency 'minitest' s.add_development_dependency 'minitest-reporters' s.add_development_dependency 'mocha' s.add_development_dependency 'pry' s.add_development_dependency 'rake', '~> 13' s.add_development_dependency 'shoulda-context' s.add_development_dependency 'yard' # Gems for testing integrations s.add_development_dependency 'jsonify' s.add_development_dependency 'hashie' # Temporary support for Ruby 2.6, since it's EOL March 2022: if RUBY_VERSION < '2.7.0' s.add_development_dependency 'jbuilder', '< 7.0.0' else s.add_development_dependency 'activesupport' s.add_development_dependency 'jbuilder' end s.add_development_dependency 'cane' s.add_development_dependency 'escape_utils' unless defined? JRUBY_VERSION s.add_development_dependency 'require-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius) s.add_development_dependency 'simplecov' s.add_development_dependency 'test-unit', '~> 2' s.add_development_dependency 'ruby-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius) s.description = <<-DESC.gsub(/^ /, '') Ruby API for Elasticsearch. See the `elasticsearch` gem for full integration. DESC end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/000077500000000000000000000000001462737751600235675ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch-api.rb000066400000000000000000000014441462737751600275000ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'elasticsearch/api' elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/000077500000000000000000000000001462737751600264015ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api.rb000066400000000000000000000064551462737751600275110ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require "cgi" require "multi_json" require "elasticsearch/api/version" require "elasticsearch/api/namespace/common" require "elasticsearch/api/utils" require "elasticsearch/api/actions/params_registry" Dir[ File.expand_path('../api/actions/**/params_registry.rb', __FILE__) ].each { |f| require f } Dir[ File.expand_path('../api/actions/**/*.rb', __FILE__) ].each { |f| require f } Dir[ File.expand_path('../api/namespace/**/*.rb', __FILE__) ].each { |f| require f } module Elasticsearch module API DEFAULT_SERIALIZER = MultiJson COMMON_PARAMS = [ :ignore, # Client specific parameters :index, :type, :id, # :index/:type/:id :body, # Request body :node_id, # Cluster :name, # Alias, template, settings, warmer, ... :field # Get field mapping ] COMMON_QUERY_PARAMS = [ :ignore, # Client specific parameters :format, # Search, Cat, ... :pretty, # Pretty-print the response :human, # Return numeric values in human readable format :filter_path, # Filter the JSON response :opaque_id # Use X-Opaque-Id ] HTTP_GET = 'GET'.freeze HTTP_HEAD = 'HEAD'.freeze HTTP_POST = 'POST'.freeze HTTP_PUT = 'PUT'.freeze HTTP_DELETE = 'DELETE'.freeze UNDERSCORE_SEARCH = '_search'.freeze UNDERSCORE_ALL = '_all'.freeze DEFAULT_DOC = '_doc'.freeze # Auto-include all namespaces in the receiver # def self.included(base) base.send :include, Elasticsearch::API::Common, Elasticsearch::API::Actions, Elasticsearch::API::Cluster, Elasticsearch::API::Nodes, Elasticsearch::API::Indices, Elasticsearch::API::Ingest, Elasticsearch::API::Snapshot, Elasticsearch::API::Tasks, Elasticsearch::API::Cat, Elasticsearch::API::Remote, Elasticsearch::API::DanglingIndices, Elasticsearch::API::Features, Elasticsearch::API::Shutdown end # The serializer class # def self.serializer settings[:serializer] || DEFAULT_SERIALIZER end # Access the module settings # def self.settings @settings ||= {} end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/000077500000000000000000000000001462737751600271525ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/000077500000000000000000000000001462737751600306125ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/bulk.rb000066400000000000000000000105621462737751600321000ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Allows to perform multiple index/update/delete operations in a single request. # # @option arguments [String] :index Default index for items which don't provide one # @option arguments [String] :type Default document type for items which don't provide one # @option arguments [String] :wait_for_active_shards Sets the number of shard copies that must be active before proceeding with the bulk operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1) # @option arguments [String] :refresh If `true` then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` (the default) then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [String] :routing Specific routing value # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [List] :_source True or false to return the _source field or not, or default list of fields to return, can be overridden on each sub-request # @option arguments [List] :_source_excludes Default list of fields to exclude from the returned _source field, can be overridden on each sub-request # @option arguments [List] :_source_includes Default list of fields to extract and return from the _source field, can be overridden on each sub-request # @option arguments [String] :pipeline The pipeline id to preprocess incoming documents with # @option arguments [Boolean] :require_alias Sets require_alias for all incoming documents. Defaults to unset (false) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [String|Array] :body The operation definition and data (action-data pairs), separated by newlines. Array of Strings, Header/Data pairs, # or the conveniency "combined" format can be passed, refer to Elasticsearch::API::Utils.__bulkify documentation. # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-bulk.html # def bulk(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_POST path = if _index && _type "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/_bulk" elsif _index "#{Utils.__listify(_index)}/_bulk" else "_bulk" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] if body.is_a? Array payload = Elasticsearch::API::Utils.__bulkify(body) else payload = body end headers = Utils.ndjson_headers(headers) perform_request(method, path, params, payload, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:bulk, [ :wait_for_active_shards, :refresh, :routing, :timeout, :type, :_source, :_source_excludes, :_source_includes, :pipeline, :require_alias ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/000077500000000000000000000000001462737751600313615ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/aliases.rb000066400000000000000000000056301462737751600333330ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Shows information about currently configured aliases to indices including filter and routing infos. # # @option arguments [List] :name A comma-separated list of alias names to return # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-alias.html # def aliases(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = if _name "_cat/aliases/#{Utils.__listify(_name)}" else "_cat/aliases" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) params[:h] = Utils.__listify(params[:h]) if params[:h] body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:aliases, [ :format, :local, :h, :help, :s, :v, :expand_wildcards ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/allocation.rb000066400000000000000000000060471462737751600340420ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Provides a snapshot of how many shards are allocated to each data node and how much disk space they are using. # # @option arguments [List] :node_id A comma-separated list of node IDs or names to limit the returned information # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, kb, m, mb, g, gb, t, tb, p, pb) # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-allocation.html # def allocation(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _node_id = arguments.delete(:node_id) method = Elasticsearch::API::HTTP_GET path = if _node_id "_cat/allocation/#{Utils.__listify(_node_id)}" else "_cat/allocation" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) params[:h] = Utils.__listify(params[:h]) if params[:h] body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:allocation, [ :format, :bytes, :local, :master_timeout, :h, :help, :s, :v ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/count.rb000066400000000000000000000050661462737751600330450ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Provides quick access to the document count of the entire cluster, or individual indices. # # @option arguments [List] :index A comma-separated list of index names to limit the returned information # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-count.html # def count(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _index "_cat/count/#{Utils.__listify(_index)}" else "_cat/count" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) params[:h] = Utils.__listify(params[:h]) if params[:h] body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:count, [ :format, :h, :help, :s, :v ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/fielddata.rb000066400000000000000000000052671462737751600336350ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Shows how much heap memory is currently being used by fielddata on every data node in the cluster. # # @option arguments [List] :fields A comma-separated list of fields to return the fielddata size # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, kb, m, mb, g, gb, t, tb, p, pb) # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-fielddata.html # def fielddata(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _fields = arguments.delete(:fields) method = Elasticsearch::API::HTTP_GET path = if _fields "_cat/fielddata/#{Utils.__listify(_fields)}" else "_cat/fielddata" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:fielddata, [ :format, :bytes, :h, :help, :s, :v, :fields ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/health.rb000066400000000000000000000047321462737751600331610ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Returns a concise representation of the cluster health. # # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [String] :time The unit in which to display time values (options: d, h, m, s, ms, micros, nanos) # @option arguments [Boolean] :ts Set to false to disable timestamping # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-health.html # def health(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_cat/health" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) params[:h] = Utils.__listify(params[:h]) if params[:h] body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:health, [ :format, :h, :help, :s, :time, :ts, :v ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/help.rb000066400000000000000000000035141462737751600326410ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Returns help for the Cat APIs. # # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat.html # def help(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_cat" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:help, [ :help, :s ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/indices.rb000066400000000000000000000075651462737751600333410ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Returns information about indices: number of primaries and replicas, document counts, disk size, ... # # @option arguments [List] :index A comma-separated list of index names to limit the returned information # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, kb, m, mb, g, gb, t, tb, p, pb) # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) *Deprecated* # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [String] :health A health status ("green", "yellow", or "red" to filter only indices matching the specified health status (options: green, yellow, red) # @option arguments [Boolean] :help Return help information # @option arguments [Boolean] :pri Set to true to return stats only for primary shards # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [String] :time The unit in which to display time values (options: d, h, m, s, ms, micros, nanos) # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Boolean] :include_unloaded_segments If set to true segment stats will include stats for segments that are not currently loaded into memory # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-indices.html # def indices(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _index "_cat/indices/#{Utils.__listify(_index)}" else "_cat/indices" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) params[:h] = Utils.__listify(params[:h]) if params[:h] body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:indices, [ :format, :bytes, :local, :master_timeout, :h, :health, :help, :pri, :s, :time, :v, :include_unloaded_segments, :expand_wildcards ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/master.rb000066400000000000000000000046741462737751600332140ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Returns information about the master node. # # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-master.html # def master(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_cat/master" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:master, [ :format, :local, :master_timeout, :h, :help, :s, :v ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/nodeattrs.rb000066400000000000000000000047171462737751600337220ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Returns information about custom node attributes. # # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-nodeattrs.html # def nodeattrs(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_cat/nodeattrs" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:nodeattrs, [ :format, :local, :master_timeout, :h, :help, :s, :v ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/nodes.rb000066400000000000000000000063041462737751600330210ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Returns basic statistics about performance of cluster nodes. # # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, kb, m, mb, g, gb, t, tb, p, pb) # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [Boolean] :full_id Return the full node ID instead of the shortened version (default: false) # @option arguments [Boolean] :local Calculate the selected nodes using the local cluster state rather than the state from master node (default: false) *Deprecated* # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [String] :time The unit in which to display time values (options: d, h, m, s, ms, micros, nanos) # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Boolean] :include_unloaded_segments If set to true segment stats will include stats for segments that are not currently loaded into memory # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-nodes.html # def nodes(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_cat/nodes" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) params[:h] = Utils.__listify(params[:h], escape: false) if params[:h] body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:nodes, [ :bytes, :format, :full_id, :local, :master_timeout, :h, :help, :s, :time, :v, :include_unloaded_segments ].freeze) end end end end params_registry.rb000066400000000000000000000036751462737751600350550ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 6.1.1 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 6.1.1 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 6.1.1 def get(action) PARAMS.fetch(action, []) end end end end end end pending_tasks.rb000066400000000000000000000052731462737751600344670ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Returns a concise representation of the cluster pending tasks. # # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [String] :time The unit in which to display time values (options: d, h, m, s, ms, micros, nanos) # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-pending-tasks.html # def pending_tasks(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_cat/pending_tasks" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) params[:h] = Utils.__listify(params[:h]) if params[:h] body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:pending_tasks, [ :format, :local, :master_timeout, :h, :help, :s, :time, :v ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/plugins.rb000066400000000000000000000051251462737751600333720ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Returns information about installed plugins across nodes node. # # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [Boolean] :include_bootstrap Include bootstrap plugins in the response # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-plugins.html # def plugins(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_cat/plugins" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:plugins, [ :format, :local, :master_timeout, :h, :help, :include_bootstrap, :s, :v ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/recovery.rb000066400000000000000000000062361462737751600335530ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Returns information about index shard recoveries, both on-going completed. # # @option arguments [List] :index Comma-separated list or wildcard expression of index names to limit the returned information # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [Boolean] :active_only If `true`, the response only includes ongoing shard recoveries # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, kb, m, mb, g, gb, t, tb, p, pb) # @option arguments [Boolean] :detailed If `true`, the response includes detailed information about shard recoveries # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [String] :time The unit in which to display time values (options: d, h, m, s, ms, micros, nanos) # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-recovery.html # def recovery(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _index "_cat/recovery/#{Utils.__listify(_index)}" else "_cat/recovery" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) params[:h] = Utils.__listify(params[:h]) if params[:h] body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:recovery, [ :format, :active_only, :bytes, :detailed, :h, :help, :index, :s, :time, :v ].freeze) end end end end repositories.rb000066400000000000000000000047431462737751600343660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Returns information about snapshot repositories registered in the cluster. # # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-repositories.html # def repositories(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_cat/repositories" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:repositories, [ :format, :local, :master_timeout, :h, :help, :s, :v ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/segments.rb000066400000000000000000000052161462737751600335370ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Provides low-level information about the segments in the shards of an index. # # @option arguments [List] :index A comma-separated list of index names to limit the returned information # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, kb, m, mb, g, gb, t, tb, p, pb) # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-segments.html # def segments(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _index "_cat/segments/#{Utils.__listify(_index)}" else "_cat/segments" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:segments, [ :format, :bytes, :h, :help, :s, :v ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/shards.rb000066400000000000000000000061461462737751600332010ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Provides a detailed view of shard allocation on nodes. # # @option arguments [List] :index A comma-separated list of index names to limit the returned information # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, kb, m, mb, g, gb, t, tb, p, pb) # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) *Deprecated* # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [String] :time The unit in which to display time values (options: d, h, m, s, ms, micros, nanos) # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-shards.html # def shards(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _index "_cat/shards/#{Utils.__listify(_index)}" else "_cat/shards" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) params[:h] = Utils.__listify(params[:h]) if params[:h] body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:shards, [ :format, :bytes, :local, :master_timeout, :h, :help, :s, :time, :v ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/snapshots.rb000066400000000000000000000056121462737751600337340ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Returns all snapshots in a specific repository. # # @option arguments [List] :repository Name of repository from which to fetch the snapshot information # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [Boolean] :ignore_unavailable Set to true to ignore unavailable snapshots # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [String] :time The unit in which to display time values (options: d, h, m, s, ms, micros, nanos) # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-snapshots.html # def snapshots(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) method = Elasticsearch::API::HTTP_GET path = if _repository "_cat/snapshots/#{Utils.__listify(_repository)}" else "_cat/snapshots" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:snapshots, [ :format, :ignore_unavailable, :master_timeout, :h, :help, :s, :time, :v ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/tasks.rb000066400000000000000000000060201462737751600330310ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Returns information about the tasks currently executing on one or more nodes in the cluster. # # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [List] :nodes A comma-separated list of node IDs or names to limit the returned information; use `_local` to return information from the node you're connecting to, leave empty to get information from all nodes # @option arguments [List] :actions A comma-separated list of actions that should be returned. Leave empty to return all. # @option arguments [Boolean] :detailed Return detailed task information (default: false) # @option arguments [String] :parent_task_id Return tasks with specified parent task id (node_id:task_number). Set to -1 to return all. # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [String] :time The unit in which to display time values (options: d, h, m, s, ms, micros, nanos) # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/tasks.html # def tasks(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_cat/tasks" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:tasks, [ :format, :nodes, :actions, :detailed, :parent_task_id, :h, :help, :s, :time, :v ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat/templates.rb000066400000000000000000000053401462737751600337060ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Returns information about existing templates. # # @option arguments [String] :name A pattern that returned template names must match # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-templates.html # def templates(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = if _name "_cat/templates/#{Utils.__listify(_name)}" else "_cat/templates" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:templates, [ :format, :local, :master_timeout, :h, :help, :s, :v ].freeze) end end end end thread_pool.rb000066400000000000000000000062261462737751600341350ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions # Returns cluster-wide thread pool statistics per node. # By default the active, queue and rejected statistics are returned for all thread pools. # # @option arguments [List] :thread_pool_patterns A comma-separated list of regular-expressions to filter the thread pools in the output # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [String] :size The multiplier in which to display values *Deprecated* (options: , k, m, g, t, p) # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-thread-pool.html # def thread_pool(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _thread_pool_patterns = arguments.delete(:thread_pool_patterns) method = Elasticsearch::API::HTTP_GET path = if _thread_pool_patterns "_cat/thread_pool/#{Utils.__listify(_thread_pool_patterns)}" else "_cat/thread_pool" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) params[:h] = Utils.__listify(params[:h]) if params[:h] body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:thread_pool, [ :format, :size, :local, :master_timeout, :h, :help, :s, :v ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/clear_scroll.rb000066400000000000000000000037541462737751600336140ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Explicitly clears the search context for a scroll. # # @option arguments [List] :scroll_id A comma-separated list of scroll IDs to clear *Deprecated* # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body A comma-separated list of scroll IDs to clear if none was specified via the scroll_id parameter # # *Deprecation notice*: # A scroll id can be quite large and should be specified as part of the body # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/clear-scroll-api.html # def clear_scroll(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _scroll_id = arguments.delete(:scroll_id) method = Elasticsearch::API::HTTP_DELETE path = if _scroll_id "_search/scroll/#{Utils.__listify(_scroll_id)}" else "_search/scroll" end params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end close_point_in_time.rb000066400000000000000000000026701462737751600351070ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Close a point in time # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body a point-in-time id to close # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/point-in-time-api.html # def close_point_in_time(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_DELETE path = "_pit" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster/000077500000000000000000000000001462737751600322735ustar00rootroot00000000000000allocation_explain.rb000066400000000000000000000045101462737751600364060ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Provides explanations for shard allocations in the cluster. # # @option arguments [Boolean] :include_yes_decisions Return 'YES' decisions in explanation (default: false) # @option arguments [Boolean] :include_disk_info Return information about disk usage and shard sizes (default: false) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The index, shard, and primary flag to explain. Empty means 'explain a randomly-chosen unassigned shard' # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-allocation-explain.html # def allocation_explain(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = "_cluster/allocation/explain" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:allocation_explain, [ :include_yes_decisions, :include_disk_info ].freeze) end end end end delete_component_template.rb000066400000000000000000000042141462737751600377610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Deletes a component template # # @option arguments [String] :name The name of the template # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-component-template.html # def delete_component_template(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_DELETE path = "_component_template/#{Utils.__listify(_name)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_component_template, [ :timeout, :master_timeout ].freeze) end end end end delete_voting_config_exclusions.rb000066400000000000000000000037311462737751600411760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Clears cluster voting config exclusions. # # @option arguments [Boolean] :wait_for_removal Specifies whether to wait for all excluded nodes to be removed from the cluster before clearing the voting configuration exclusions list. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/voting-config-exclusions.html # def delete_voting_config_exclusions(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_DELETE path = "_cluster/voting_config_exclusions" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_voting_config_exclusions, [ :wait_for_removal ].freeze) end end end end exists_component_template.rb000066400000000000000000000045151462737751600400420ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Returns information about whether a particular component template exist # # @option arguments [String] :name The name of the template # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-component-template.html # def exists_component_template(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_HEAD path = "_component_template/#{Utils.__listify(_name)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end alias_method :exists_component_template?, :exists_component_template # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:exists_component_template, [ :master_timeout, :local ].freeze) end end end end get_component_template.rb000066400000000000000000000044171462737751600373030ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Returns one or more component templates # # @option arguments [List] :name The comma separated names of the component templates # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-component-template.html # def get_component_template(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = if _name "_component_template/#{Utils.__listify(_name)}" else "_component_template" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_component_template, [ :master_timeout, :local ].freeze) end end end end get_settings.rb000066400000000000000000000042241462737751600352420ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Returns cluster settings. # # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Boolean] :include_defaults Whether to return all default clusters setting. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-get-settings.html # def get_settings(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_cluster/settings" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_settings, [ :flat_settings, :master_timeout, :timeout, :include_defaults ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster/health.rb000066400000000000000000000072631462737751600340750ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Returns basic information about the health of the cluster. # # @option arguments [List] :index Limit the information returned to a specific index # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [String] :level Specify the level of detail for returned information (options: cluster, indices, shards) # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [String] :wait_for_active_shards Wait until the specified number of shards is active # @option arguments [String] :wait_for_nodes Wait until the specified number of nodes is available # @option arguments [String] :wait_for_events Wait until all currently queued events with the given priority are processed (options: immediate, urgent, high, normal, low, languid) # @option arguments [Boolean] :wait_for_no_relocating_shards Whether to wait until there are no relocating shards in the cluster # @option arguments [Boolean] :wait_for_no_initializing_shards Whether to wait until there are no initializing shards in the cluster # @option arguments [String] :wait_for_status Wait until cluster is in a specific state (options: green, yellow, red) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-health.html # def health(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _index "_cluster/health/#{Utils.__listify(_index)}" else "_cluster/health" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:health, [ :expand_wildcards, :level, :local, :master_timeout, :timeout, :wait_for_active_shards, :wait_for_nodes, :wait_for_events, :wait_for_no_relocating_shards, :wait_for_no_initializing_shards, :wait_for_status ].freeze) end end end end params_registry.rb000066400000000000000000000037011462737751600357550ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 6.1.1 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 6.1.1 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 6.1.1 def get(action) PARAMS.fetch(action, []) end end end end end end pending_tasks.rb000066400000000000000000000040661462737751600354000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Returns a list of any cluster-level changes (e.g. create index, update mapping, # allocate or fail shard) which have not yet been executed. # # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-pending.html # def pending_tasks(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_cluster/pending_tasks" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:pending_tasks, [ :local, :master_timeout ].freeze) end end end end post_voting_config_exclusions.rb000066400000000000000000000044371462737751600407250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Updates the cluster voting config exclusions by node ids or node names. # # @option arguments [String] :node_ids A comma-separated list of the persistent ids of the nodes to exclude from the voting configuration. If specified, you may not also specify ?node_names. # @option arguments [String] :node_names A comma-separated list of the names of the nodes to exclude from the voting configuration. If specified, you may not also specify ?node_ids. # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/voting-config-exclusions.html # def post_voting_config_exclusions(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_cluster/voting_config_exclusions" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:post_voting_config_exclusions, [ :node_ids, :node_names, :timeout ].freeze) end end end end put_component_template.rb000066400000000000000000000047371462737751600373410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Creates or updates a component template # # @option arguments [String] :name The name of the template # @option arguments [Boolean] :create Whether the index template should only be added if new or can also replace an existing one # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The template definition (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-component-template.html # def put_component_template(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_PUT path = "_component_template/#{Utils.__listify(_name)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_component_template, [ :create, :timeout, :master_timeout ].freeze) end end end end put_settings.rb000066400000000000000000000044341462737751600352760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Updates the cluster settings. # # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The settings to be updated. Can be either `transient` or `persistent` (survives cluster restart). (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-update-settings.html # def put_settings(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_PUT path = "_cluster/settings" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] || {} perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_settings, [ :flat_settings, :master_timeout, :timeout ].freeze) end end end end remote_info.rb000066400000000000000000000027101462737751600350470ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Returns the information about configured remote clusters. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-remote-info.html # def remote_info(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_remote/info" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end reroute.rb000066400000000000000000000053111462737751600342260ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Allows to manually change the allocation of individual shards in the cluster. # # @option arguments [Boolean] :dry_run Simulate the operation only and return the resulting state # @option arguments [Boolean] :explain Return an explanation of why the commands can or cannot be executed # @option arguments [Boolean] :retry_failed Retries allocation of shards that are blocked due to too many subsequent allocation failures # @option arguments [List] :metric Limit the information returned to the specified metrics. Defaults to all but metadata (options: _all, blocks, metadata, nodes, routing_table, master_node, version) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The definition of `commands` to perform (`move`, `cancel`, `allocate`) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-reroute.html # def reroute(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_cluster/reroute" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] || {} perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:reroute, [ :dry_run, :explain, :retry_failed, :metric, :master_timeout, :timeout ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster/state.rb000066400000000000000000000073511462737751600337460ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Returns a comprehensive information about the state of the cluster. # # @option arguments [List] :metric Limit the information returned to the specified metrics (options: _all, blocks, metadata, nodes, routing_table, routing_nodes, master_node, version) # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false) # @option arguments [Number] :wait_for_metadata_version Wait for the metadata version to be equal or greater than the specified metadata version # @option arguments [Time] :wait_for_timeout The maximum time to wait for wait_for_metadata_version before timing out # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-state.html # def state(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _metric = arguments.delete(:metric) _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _metric && _index "_cluster/state/#{Utils.__listify(_metric)}/#{Utils.__listify(_index)}" elsif _metric "_cluster/state/#{Utils.__listify(_metric)}" else "_cluster/state" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:state, [ :local, :master_timeout, :flat_settings, :wait_for_metadata_version, :wait_for_timeout, :ignore_unavailable, :allow_no_indices, :expand_wildcards ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/cluster/stats.rb000066400000000000000000000045031462737751600337600ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions # Returns high-level overview of cluster statistics. # # @option arguments [List] :node_id A comma-separated list of node IDs or names to limit the returned information; use `_local` to return information from the node you're connecting to, leave empty to get information from all nodes # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false) # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-stats.html # def stats(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _node_id = arguments.delete(:node_id) method = Elasticsearch::API::HTTP_GET path = if _node_id "_cluster/stats/nodes/#{Utils.__listify(_node_id)}" else "_cluster/stats" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:stats, [ :flat_settings, :timeout ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/count.rb000066400000000000000000000111521462737751600322670ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns number of documents matching a query. # # @option arguments [List] :index A comma-separated list of indices to restrict the results # @option arguments [List] :type A comma-separated list of types to restrict the results # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :ignore_throttled Whether specified concrete, expanded or aliased indices should be ignored when throttled # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Number] :min_score Include only documents with a specific `_score` value in the result # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) # @option arguments [List] :routing A comma-separated list of specific routing values # @option arguments [String] :q Query in the Lucene query string syntax # @option arguments [String] :analyzer The analyzer to use for the query string # @option arguments [Boolean] :analyze_wildcard Specify whether wildcard and prefix queries should be analyzed (default: false) # @option arguments [String] :default_operator The default operator for query string query (AND or OR) (options: AND, OR) # @option arguments [String] :df The field to use as default where no field prefix is given in the query string # @option arguments [Boolean] :lenient Specify whether format-based query failures (such as providing text to a numeric field) should be ignored # @option arguments [Number] :terminate_after The maximum count for each shard, upon reaching which the query execution will terminate early # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body A query to restrict the results specified with the Query DSL (optional) # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-count.html # def count(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _index && _type "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/_count" elsif _index "#{Utils.__listify(_index)}/_count" else "_count" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:count, [ :ignore_unavailable, :ignore_throttled, :allow_no_indices, :expand_wildcards, :min_score, :preference, :routing, :q, :analyzer, :analyze_wildcard, :default_operator, :df, :lenient, :terminate_after ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/create.rb000066400000000000000000000054321462737751600324060ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Creates a new document in the index. # # Returns a 409 response when a document with a same ID already exists in the index. # # @option arguments [String] :id Document ID # @option arguments [String] :index The name of the index # @option arguments [String] :type The type of the document *Deprecated* # @option arguments [String] :wait_for_active_shards Sets the number of shard copies that must be active before proceeding with the index operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1) # @option arguments [String] :refresh If `true` then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` (the default) then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [String] :routing Specific routing value # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Number] :version Explicit version number for concurrency control # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte) # @option arguments [String] :pipeline The pipeline id to preprocess incoming documents with # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The document (*Required*) # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-index_.html # def create(arguments = {}) if arguments[:id] index arguments.update op_type: 'create' else index arguments end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/dangling_indices/000077500000000000000000000000001462737751600340735ustar00rootroot00000000000000delete_dangling_index.rb000066400000000000000000000045111462737751600406360ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/dangling_indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module DanglingIndices module Actions # Deletes the specified dangling index # # @option arguments [String] :index_uuid The UUID of the dangling index # @option arguments [Boolean] :accept_data_loss Must be set to true in order to delete the dangling index # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-gateway-dangling-indices.html # def delete_dangling_index(arguments = {}) raise ArgumentError, "Required argument 'index_uuid' missing" unless arguments[:index_uuid] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index_uuid = arguments.delete(:index_uuid) method = Elasticsearch::API::HTTP_DELETE path = "_dangling/#{Utils.__listify(_index_uuid)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_dangling_index, [ :accept_data_loss, :timeout, :master_timeout ].freeze) end end end end import_dangling_index.rb000066400000000000000000000045071462737751600407130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/dangling_indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module DanglingIndices module Actions # Imports the specified dangling index # # @option arguments [String] :index_uuid The UUID of the dangling index # @option arguments [Boolean] :accept_data_loss Must be set to true in order to import the dangling index # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-gateway-dangling-indices.html # def import_dangling_index(arguments = {}) raise ArgumentError, "Required argument 'index_uuid' missing" unless arguments[:index_uuid] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index_uuid = arguments.delete(:index_uuid) method = Elasticsearch::API::HTTP_POST path = "_dangling/#{Utils.__listify(_index_uuid)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:import_dangling_index, [ :accept_data_loss, :timeout, :master_timeout ].freeze) end end end end list_dangling_indices.rb000066400000000000000000000027101462737751600406550ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/dangling_indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module DanglingIndices module Actions # Returns all dangling indices. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-gateway-dangling-indices.html # def list_dangling_indices(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_dangling" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end params_registry.rb000066400000000000000000000037111462737751600375560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/dangling_indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module DanglingIndices module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 6.1.1 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 6.1.1 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 6.1.1 def get(action) PARAMS.fetch(action, []) end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/delete.rb000066400000000000000000000101361462737751600324020ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Removes a document from the index. # # @option arguments [String] :id The document ID # @option arguments [String] :index The name of the index # @option arguments [String] :type The type of the document *Deprecated* # @option arguments [String] :wait_for_active_shards Sets the number of shard copies that must be active before proceeding with the delete operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1) # @option arguments [String] :refresh If `true` then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` (the default) then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [String] :routing Specific routing value # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Number] :if_seq_no only perform the delete operation if the last operation that has changed the document has the specified sequence number # @option arguments [Number] :if_primary_term only perform the delete operation if the last operation that has changed the document has the specified primary term # @option arguments [Number] :version Explicit version number for concurrency control # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte, force) # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-delete.html # def delete(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_DELETE path = if _index && _type && _id "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/#{Utils.__listify(_id)}" else "#{Utils.__listify(_index)}/_doc/#{Utils.__listify(_id)}" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil if Array(arguments[:ignore]).include?(404) Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete, [ :wait_for_active_shards, :refresh, :routing, :timeout, :if_seq_no, :if_primary_term, :version, :version_type ].freeze) end end end delete_by_query.rb000066400000000000000000000162011462737751600342410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Deletes documents matching the provided query. # # @option arguments [List] :index A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices (*Required*) # @option arguments [List] :type A comma-separated list of document types to search; leave empty to perform the operation on all types # @option arguments [String] :analyzer The analyzer to use for the query string # @option arguments [Boolean] :analyze_wildcard Specify whether wildcard and prefix queries should be analyzed (default: false) # @option arguments [String] :default_operator The default operator for query string query (AND or OR) (options: AND, OR) # @option arguments [String] :df The field to use as default where no field prefix is given in the query string # @option arguments [Number] :from Starting offset (default: 0) # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :conflicts What to do when the delete by query hits version conflicts? (options: abort, proceed) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :lenient Specify whether format-based query failures (such as providing text to a numeric field) should be ignored # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) # @option arguments [String] :q Query in the Lucene query string syntax # @option arguments [List] :routing A comma-separated list of specific routing values # @option arguments [Time] :scroll Specify how long a consistent view of the index should be maintained for scrolled search # @option arguments [String] :search_type Search operation type (options: query_then_fetch, dfs_query_then_fetch) # @option arguments [Time] :search_timeout Explicit timeout for each search request. Defaults to no timeout. # @option arguments [Number] :size Deprecated, please use `max_docs` instead # @option arguments [Number] :max_docs Maximum number of documents to process (default: all documents) # @option arguments [List] :sort A comma-separated list of : pairs # @option arguments [Number] :terminate_after The maximum number of documents to collect for each shard, upon reaching which the query execution will terminate early. # @option arguments [List] :stats Specific 'tag' of the request for logging and statistical purposes # @option arguments [Boolean] :version Specify whether to return document version as part of a hit # @option arguments [Boolean] :request_cache Specify if request cache should be used for this request or not, defaults to index level setting # @option arguments [Boolean] :refresh Should the effected indexes be refreshed? # @option arguments [Time] :timeout Time each individual bulk request should wait for shards that are unavailable. # @option arguments [String] :wait_for_active_shards Sets the number of shard copies that must be active before proceeding with the delete by query operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1) # @option arguments [Number] :scroll_size Size on the scroll request powering the delete by query # @option arguments [Boolean] :wait_for_completion Should the request should block until the delete by query is complete. # @option arguments [Number] :requests_per_second The throttle for this request in sub-requests per second. -1 means no throttle. # @option arguments [Number|string] :slices The number of slices this task should be divided into. Defaults to 1, meaning the task isn't sliced into subtasks. Can be set to `auto`. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The search definition using the Query DSL (*Required*) # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-delete-by-query.html # def delete_by_query(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_POST path = if _index && _type "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/_delete_by_query" else "#{Utils.__listify(_index)}/_delete_by_query" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_by_query, [ :analyzer, :analyze_wildcard, :default_operator, :df, :from, :ignore_unavailable, :allow_no_indices, :conflicts, :expand_wildcards, :lenient, :preference, :q, :routing, :scroll, :search_type, :search_timeout, :size, :max_docs, :sort, :terminate_after, :stats, :version, :request_cache, :refresh, :timeout, :wait_for_active_shards, :scroll_size, :wait_for_completion, :requests_per_second, :slices ].freeze) end end end delete_by_query_rethrottle.rb000066400000000000000000000042021462737751600365130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Changes the number of requests per second for a particular Delete By Query operation. # # @option arguments [String] :task_id The task id to rethrottle # @option arguments [Number] :requests_per_second The throttle to set on this request in floating sub-requests per second. -1 means set no throttle. (*Required*) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-delete-by-query.html # def delete_by_query_rethrottle(arguments = {}) raise ArgumentError, "Required argument 'task_id' missing" unless arguments[:task_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _task_id = arguments.delete(:task_id) method = Elasticsearch::API::HTTP_POST path = "_delete_by_query/#{Utils.__listify(_task_id)}/_rethrottle" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_by_query_rethrottle, [ :requests_per_second ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/delete_script.rb000066400000000000000000000037451462737751600337760ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Deletes a script. # # @option arguments [String] :id Script ID # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-scripting.html # def delete_script(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_DELETE path = "_scripts/#{Utils.__listify(_id)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_script, [ :timeout, :master_timeout ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/exists.rb000066400000000000000000000076621462737751600324710ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns information about whether a document exists in an index. # # @option arguments [String] :id The document ID # @option arguments [String] :index The name of the index # @option arguments [String] :type The type of the document (use `_all` to fetch the first document matching the ID across all types) *Deprecated* # @option arguments [List] :stored_fields A comma-separated list of stored fields to return in the response # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) # @option arguments [Boolean] :realtime Specify whether to perform the operation in realtime or search mode # @option arguments [Boolean] :refresh Refresh the shard containing the document before performing the operation # @option arguments [String] :routing Specific routing value # @option arguments [List] :_source True or false to return the _source field or not, or a list of fields to return # @option arguments [List] :_source_excludes A list of fields to exclude from the returned _source field # @option arguments [List] :_source_includes A list of fields to extract and return from the _source field # @option arguments [Number] :version Explicit version number for concurrency control # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte, force) # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-get.html # def exists(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_HEAD path = if _index && _type && _id "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/#{Utils.__listify(_id)}" else "#{Utils.__listify(_index)}/_doc/#{Utils.__listify(_id)}" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil Utils.__rescue_from_not_found do perform_request(method, path, params, body, headers).status == 200 ? true : false end end alias_method :exists?, :exists # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:exists, [ :stored_fields, :preference, :realtime, :refresh, :routing, :_source, :_source_excludes, :_source_includes, :version, :version_type ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/exists_source.rb000066400000000000000000000073471462737751600340510ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns information about whether a document source exists in an index. # # @option arguments [String] :id The document ID # @option arguments [String] :index The name of the index # @option arguments [String] :type The type of the document; deprecated and optional starting with 7.0 *Deprecated* # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) # @option arguments [Boolean] :realtime Specify whether to perform the operation in realtime or search mode # @option arguments [Boolean] :refresh Refresh the shard containing the document before performing the operation # @option arguments [String] :routing Specific routing value # @option arguments [List] :_source True or false to return the _source field or not, or a list of fields to return # @option arguments [List] :_source_excludes A list of fields to exclude from the returned _source field # @option arguments [List] :_source_includes A list of fields to extract and return from the _source field # @option arguments [Number] :version Explicit version number for concurrency control # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte, force) # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-get.html # def exists_source(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_HEAD path = if _index && _type && _id "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/#{Utils.__listify(_id)}/_source" else "#{Utils.__listify(_index)}/_source/#{Utils.__listify(_id)}" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end alias_method :exists_source?, :exists_source # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:exists_source, [ :preference, :realtime, :refresh, :routing, :_source, :_source_excludes, :_source_includes, :version, :version_type ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/explain.rb000066400000000000000000000104251462737751600326010ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns information about why a specific matches (or doesn't match) a query. # # @option arguments [String] :id The document ID # @option arguments [String] :index The name of the index # @option arguments [String] :type The type of the document *Deprecated* # @option arguments [Boolean] :analyze_wildcard Specify whether wildcards and prefix queries in the query string query should be analyzed (default: false) # @option arguments [String] :analyzer The analyzer for the query string query # @option arguments [String] :default_operator The default operator for query string query (AND or OR) (options: AND, OR) # @option arguments [String] :df The default field for query string query (default: _all) # @option arguments [List] :stored_fields A comma-separated list of stored fields to return in the response # @option arguments [Boolean] :lenient Specify whether format-based query failures (such as providing text to a numeric field) should be ignored # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) # @option arguments [String] :q Query in the Lucene query string syntax # @option arguments [String] :routing Specific routing value # @option arguments [List] :_source True or false to return the _source field or not, or a list of fields to return # @option arguments [List] :_source_excludes A list of fields to exclude from the returned _source field # @option arguments [List] :_source_includes A list of fields to extract and return from the _source field # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The query definition using the Query DSL # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-explain.html # def explain(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) _index = arguments.delete(:index) _type = arguments.delete(:type) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _index && _type && _id "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/#{Utils.__listify(_id)}/_explain" else "#{Utils.__listify(_index)}/_explain/#{Utils.__listify(_id)}" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:explain, [ :analyze_wildcard, :analyzer, :default_operator, :df, :stored_fields, :lenient, :preference, :q, :routing, :_source, :_source_excludes, :_source_includes ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/features/000077500000000000000000000000001462737751600324305ustar00rootroot00000000000000get_features.rb000066400000000000000000000036031462737751600353550ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/features# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Features module Actions # Gets a list of features which can be included in snapshots using the feature_states field when creating a snapshot # # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-features-api.html # def get_features(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_features" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_features, [ :master_timeout ].freeze) end end end end params_registry.rb000066400000000000000000000037021462737751600361130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/features# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Features module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 6.1.1 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 6.1.1 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 6.1.1 def get(action) PARAMS.fetch(action, []) end end end end end end reset_features.rb000066400000000000000000000033721462737751600357230ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/features# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Features module Actions # Resets the internal state of features, usually by deleting system indices # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-snapshots.html # def reset_features(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_features/_reset" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/field_caps.rb000066400000000000000000000060351462737751600332340ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns the information about the capabilities of fields among multiple indices. # # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices # @option arguments [List] :fields A comma-separated list of field names # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :include_unmapped Indicates whether unmapped fields should be included in the response. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body An index filter specified with the Query DSL # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-field-caps.html # def field_caps(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _index "#{Utils.__listify(_index)}/_field_caps" else "_field_caps" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:field_caps, [ :fields, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :include_unmapped ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/get.rb000066400000000000000000000076741462737751600317340ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns a document. # # @option arguments [String] :id The document ID # @option arguments [String] :index The name of the index # @option arguments [String] :type The type of the document (use `_all` to fetch the first document matching the ID across all types) *Deprecated* # @option arguments [List] :stored_fields A comma-separated list of stored fields to return in the response # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) # @option arguments [Boolean] :realtime Specify whether to perform the operation in realtime or search mode # @option arguments [Boolean] :refresh Refresh the shard containing the document before performing the operation # @option arguments [String] :routing Specific routing value # @option arguments [List] :_source True or false to return the _source field or not, or a list of fields to return # @option arguments [List] :_source_excludes A list of fields to exclude from the returned _source field # @option arguments [List] :_source_includes A list of fields to extract and return from the _source field # @option arguments [Number] :version Explicit version number for concurrency control # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte, force) # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-get.html # def get(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_GET path = if _index && _type && _id "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/#{Utils.__listify(_id)}" else "#{Utils.__listify(_index)}/_doc/#{Utils.__listify(_id)}" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil if Array(arguments[:ignore]).include?(404) Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get, [ :stored_fields, :preference, :realtime, :refresh, :routing, :_source, :_source_excludes, :_source_includes, :version, :version_type ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/get_script.rb000066400000000000000000000036051462737751600333060ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns a script. # # @option arguments [String] :id Script ID # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-scripting.html # def get_script(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = "_scripts/#{Utils.__listify(_id)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_script, [ :master_timeout ].freeze) end end end get_script_context.rb000066400000000000000000000025651462737751600347770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns all script contexts. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/painless/7.17/painless-contexts.html # def get_script_context(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_script_context" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end get_script_languages.rb000066400000000000000000000026231462737751600352540ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns available script types, languages and contexts # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-scripting.html # def get_script_languages(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_script_language" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/get_source.rb000066400000000000000000000072061462737751600333030ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns the source of a document. # # @option arguments [String] :id The document ID # @option arguments [String] :index The name of the index # @option arguments [String] :type The type of the document; deprecated and optional starting with 7.0 *Deprecated* # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) # @option arguments [Boolean] :realtime Specify whether to perform the operation in realtime or search mode # @option arguments [Boolean] :refresh Refresh the shard containing the document before performing the operation # @option arguments [String] :routing Specific routing value # @option arguments [List] :_source True or false to return the _source field or not, or a list of fields to return # @option arguments [List] :_source_excludes A list of fields to exclude from the returned _source field # @option arguments [List] :_source_includes A list of fields to extract and return from the _source field # @option arguments [Number] :version Explicit version number for concurrency control # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte, force) # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-get.html # def get_source(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_GET path = if _index && _type && _id "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/#{Utils.__listify(_id)}/_source" else "#{Utils.__listify(_index)}/_source/#{Utils.__listify(_id)}" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_source, [ :preference, :realtime, :refresh, :routing, :_source, :_source_excludes, :_source_includes, :version, :version_type ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/index.rb000066400000000000000000000113171462737751600322510ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Creates or updates a document in an index. # # @option arguments [String] :id Document ID # @option arguments [String] :index The name of the index # @option arguments [String] :type The type of the document *Deprecated* # @option arguments [String] :wait_for_active_shards Sets the number of shard copies that must be active before proceeding with the index operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1) # @option arguments [String] :op_type Explicit operation type. Defaults to `index` for requests with an explicit document ID, and to `create`for requests without an explicit document ID (options: index, create) # @option arguments [String] :refresh If `true` then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` (the default) then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [String] :routing Specific routing value # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Number] :version Explicit version number for concurrency control # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte) # @option arguments [Number] :if_seq_no only perform the index operation if the last operation that has changed the document has the specified sequence number # @option arguments [Number] :if_primary_term only perform the index operation if the last operation that has changed the document has the specified primary term # @option arguments [String] :pipeline The pipeline id to preprocess incoming documents with # @option arguments [Boolean] :require_alias When true, requires destination to be an alias. Default is false # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The document (*Required*) # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-index_.html # def index(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) _index = arguments.delete(:index) _type = arguments.delete(:type) method = _id ? Elasticsearch::API::HTTP_PUT : Elasticsearch::API::HTTP_POST path = if _index && _type && _id "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/#{Utils.__listify(_id)}" elsif _index && _id "#{Utils.__listify(_index)}/_doc/#{Utils.__listify(_id)}" elsif _index && _type "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}" else "#{Utils.__listify(_index)}/_doc" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:index, [ :wait_for_active_shards, :op_type, :refresh, :routing, :timeout, :version, :version_type, :if_seq_no, :if_primary_term, :pipeline, :require_alias ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices/000077500000000000000000000000001462737751600322305ustar00rootroot00000000000000add_block.rb000066400000000000000000000057721462737751600344130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Adds a block to an index. # # @option arguments [List] :index A comma separated list of indices to add a block to # @option arguments [String] :block The block to add (one of read, write, read_only or metadata) # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/index-modules-blocks.html # def add_block(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'block' missing" unless arguments[:block] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _block = arguments.delete(:block) method = Elasticsearch::API::HTTP_PUT path = "#{Utils.__listify(_index)}/_block/#{Utils.__listify(_block)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:add_block, [ :timeout, :master_timeout, :ignore_unavailable, :allow_no_indices, :expand_wildcards ].freeze) end end end end analyze.rb000066400000000000000000000044201462737751600341410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Performs the analysis process on a text and return the tokens breakdown of the text. # # @option arguments [String] :index The name of the index to scope the operation # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Define analyzer/tokenizer parameters and the text on which the analysis should be performed # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-analyze.html # def analyze(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _index "#{Utils.__listify(_index)}/_analyze" else "_analyze" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:analyze, [ :index ].freeze) end end end end clear_cache.rb000066400000000000000000000060151462737751600347110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Clears all or specific caches for one or more indices. # # @option arguments [List] :index A comma-separated list of index name to limit the operation # @option arguments [Boolean] :fielddata Clear field data # @option arguments [List] :fields A comma-separated list of fields to clear when using the `fielddata` parameter (default: all) # @option arguments [Boolean] :query Clear query caches # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :request Clear request cache # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-clearcache.html # def clear_cache(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = if _index "#{Utils.__listify(_index)}/_cache/clear" else "_cache/clear" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:clear_cache, [ :fielddata, :fields, :query, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :index, :request ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices/clone.rb000066400000000000000000000052121462737751600336550ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Clones an index # # @option arguments [String] :index The name of the source index to clone # @option arguments [String] :target The name of the target index to clone into # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [String] :wait_for_active_shards Set the number of active shards to wait for on the cloned index before the operation returns. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The configuration for the target index (`settings` and `aliases`) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-clone-index.html # def clone(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'target' missing" unless arguments[:target] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _target = arguments.delete(:target) method = Elasticsearch::API::HTTP_PUT path = "#{Utils.__listify(_index)}/_clone/#{Utils.__listify(_target)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:clone, [ :timeout, :master_timeout, :wait_for_active_shards ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices/close.rb000066400000000000000000000060421462737751600336640ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Closes an index. # # @option arguments [List] :index A comma separated list of indices to close # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [String] :wait_for_active_shards Sets the number of active shards to wait for before the operation returns. Set to `index-setting` to wait according to the index setting `index.write.wait_for_active_shards`, or `all` to wait for all shards, or an integer. Defaults to `0`. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-open-close.html # def close(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = "#{Utils.__listify(_index)}/_close" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:close, [ :timeout, :master_timeout, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :wait_for_active_shards ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices/create.rb000066400000000000000000000050271462737751600340240ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Creates an index with optional settings and mappings. # # @option arguments [String] :index The name of the index # @option arguments [Boolean] :include_type_name Whether a type should be expected in the body of the mappings. # @option arguments [String] :wait_for_active_shards Set the number of active shards to wait for before the operation returns. # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The configuration for the index (`settings` and `mappings`) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-create-index.html # def create(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_PUT path = "#{Utils.__listify(_index)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:create, [ :include_type_name, :wait_for_active_shards, :timeout, :master_timeout ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices/delete.rb000066400000000000000000000055021462737751600340210ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Deletes an index. # # @option arguments [List] :index A comma-separated list of indices to delete; use `_all` or `*` string to delete all indices # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Boolean] :ignore_unavailable Ignore unavailable indexes (default: false) # @option arguments [Boolean] :allow_no_indices Ignore if a wildcard expression resolves to no concrete indices (default: false) # @option arguments [String] :expand_wildcards Whether wildcard expressions should get expanded to open, closed, or hidden indices (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-delete-index.html # def delete(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_DELETE path = "#{Utils.__listify(_index)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil if Array(arguments[:ignore]).include?(404) Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete, [ :timeout, :master_timeout, :ignore_unavailable, :allow_no_indices, :expand_wildcards ].freeze) end end end end delete_alias.rb000066400000000000000000000050411462737751600351110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Deletes an alias. # # @option arguments [List] :index A comma-separated list of index names (supports wildcards); use `_all` for all indices # @option arguments [List] :name A comma-separated list of aliases to delete (supports wildcards); use `_all` to delete all aliases for the specified indices. # @option arguments [Time] :timeout Explicit timestamp for the document # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-aliases.html # def delete_alias(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_DELETE path = if _index && _name "#{Utils.__listify(_index)}/_aliases/#{Utils.__listify(_name)}" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_alias, [ :timeout, :master_timeout ].freeze) end end end end delete_index_template.rb000066400000000000000000000044611462737751600370270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Deletes an index template. # # @option arguments [String] :name The name of the template # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-templates.html # def delete_index_template(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_DELETE path = "_index_template/#{Utils.__listify(_name)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil if Array(arguments[:ignore]).include?(404) Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_index_template, [ :timeout, :master_timeout ].freeze) end end end end delete_template.rb000066400000000000000000000044371462737751600356430ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Deletes an index template. # # @option arguments [String] :name The name of the template # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-templates.html # def delete_template(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_DELETE path = "_template/#{Utils.__listify(_name)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil if Array(arguments[:ignore]).include?(404) Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_template, [ :timeout, :master_timeout ].freeze) end end end end disk_usage.rb000066400000000000000000000062621462737751600346220ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Analyzes the disk usage of each field of an index or data stream # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :index Comma-separated list of indices or data streams to analyze the disk usage # @option arguments [Boolean] :run_expensive_tasks Must be set to [true] in order for the task to be performed. Defaults to false. # @option arguments [Boolean] :flush Whether flush or not before analyzing the index disk usage. Defaults to true # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-disk-usage.html # def disk_usage(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = "#{Utils.__listify(_index)}/_disk_usage" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:disk_usage, [ :run_expensive_tasks, :flush, :ignore_unavailable, :allow_no_indices, :expand_wildcards ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices/exists.rb000066400000000000000000000057141462737751600341030ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns information about whether a particular index exists. # # @option arguments [List] :index A comma-separated list of index names # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Boolean] :ignore_unavailable Ignore unavailable indexes (default: false) # @option arguments [Boolean] :allow_no_indices Ignore if a wildcard expression resolves to no concrete indices (default: false) # @option arguments [String] :expand_wildcards Whether wildcard expressions should get expanded to open or closed indices (default: open) (options: open, closed, hidden, none, all) # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false) # @option arguments [Boolean] :include_defaults Whether to return all default setting for each of the indices. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-exists.html # def exists(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_HEAD path = "#{Utils.__listify(_index)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil Utils.__rescue_from_not_found do perform_request(method, path, params, body, headers).status == 200 ? true : false end end alias_method :exists?, :exists # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:exists, [ :local, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :flat_settings, :include_defaults ].freeze) end end end end exists_alias.rb000066400000000000000000000062141462737751600351710ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns information about whether a particular alias exists. # # @option arguments [List] :name A comma-separated list of alias names to return # @option arguments [List] :index A comma-separated list of index names to filter aliases # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-aliases.html # def exists_alias(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_HEAD path = if _index && _name "#{Utils.__listify(_index)}/_alias/#{Utils.__listify(_name)}" else "_alias/#{Utils.__listify(_name)}" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil Utils.__rescue_from_not_found do perform_request(method, path, params, body, headers).status == 200 ? true : false end end alias_method :exists_alias?, :exists_alias # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:exists_alias, [ :ignore_unavailable, :allow_no_indices, :expand_wildcards, :local ].freeze) end end end end exists_index_template.rb000066400000000000000000000050011462737751600370730ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns information about whether a particular index template exists. # # @option arguments [String] :name The name of the template # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-templates.html # def exists_index_template(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_HEAD path = "_index_template/#{Utils.__listify(_name)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil Utils.__rescue_from_not_found do perform_request(method, path, params, body, headers).status == 200 ? true : false end end alias_method :exists_index_template?, :exists_index_template # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:exists_index_template, [ :flat_settings, :master_timeout, :local ].freeze) end end end end exists_template.rb000066400000000000000000000047711462737751600357210ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns information about whether a particular index template exists. # # @option arguments [List] :name The comma separated names of the index templates # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-templates.html # def exists_template(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_HEAD path = "_template/#{Utils.__listify(_name)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil Utils.__rescue_from_not_found do perform_request(method, path, params, body, headers).status == 200 ? true : false end end alias_method :exists_template?, :exists_template # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:exists_template, [ :flat_settings, :master_timeout, :local ].freeze) end end end end exists_type.rb000066400000000000000000000062231462737751600350610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns information about whether a particular document type exists. (DEPRECATED) # # @option arguments [List] :index A comma-separated list of index names; use `_all` to check the types across all indices # @option arguments [List] :type A comma-separated list of document types to check # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-types-exists.html # def exists_type(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'type' missing" unless arguments[:type] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_HEAD path = "#{Utils.__listify(_index)}/_mapping/#{Utils.__listify(_type)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil Utils.__rescue_from_not_found do perform_request(method, path, params, body, headers).status == 200 ? true : false end end alias_method :exists_type?, :exists_type # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:exists_type, [ :ignore_unavailable, :allow_no_indices, :expand_wildcards, :local ].freeze) end end end end field_usage_stats.rb000066400000000000000000000061401462737751600361640ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns the field usage stats for each field of an index # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :index A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices # @option arguments [List] :fields A comma-separated list of fields to include in the stats if only a subset of fields should be returned (supports wildcards) # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/field-usage-stats.html # def field_usage_stats(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = "#{Utils.__listify(_index)}/_field_usage_stats" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:field_usage_stats, [ :fields, :ignore_unavailable, :allow_no_indices, :expand_wildcards ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices/flush.rb000066400000000000000000000063451462737751600337060ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Performs the flush operation on one or more indices. # # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string for all indices # @option arguments [Boolean] :force Whether a flush should be forced even if it is not necessarily needed ie. if no changes will be committed to the index. This is useful if transaction log IDs should be incremented even if no uncommitted changes are present. (This setting can be considered as internal) # @option arguments [Boolean] :wait_if_ongoing If set to true the flush operation will block until the flush can be executed if another flush operation is already executing. The default is true. If set to false the flush will be skipped iff if another flush operation is already running. # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-flush.html # def flush(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = if _index "#{Utils.__listify(_index)}/_flush" else "_flush" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:flush, [ :force, :wait_if_ongoing, :ignore_unavailable, :allow_no_indices, :expand_wildcards ].freeze) end end end end flush_synced.rb000066400000000000000000000060571462737751600351740ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Performs a synced flush operation on one or more indices. Synced flush is deprecated and will be removed in 8.0. Use flush instead # # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string for all indices # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # Synced flush is deprecated and will be removed in 8.0. Use flush instead. # Deprecated since version 7.6.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-synced-flush-api.html # def flush_synced(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = if _index "#{Utils.__listify(_index)}/_flush/synced" else "_flush/synced" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil if Array(arguments[:ignore]).include?(404) Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:flush_synced, [ :ignore_unavailable, :allow_no_indices, :expand_wildcards ].freeze) end end end end forcemerge.rb000066400000000000000000000061451462737751600346220ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Performs the force merge operation on one or more indices. # # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices # @option arguments [Boolean] :flush Specify whether the index should be flushed after performing the operation (default: true) # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Number] :max_num_segments The number of segments the index should be merged into (default: dynamic) # @option arguments [Boolean] :only_expunge_deletes Specify whether the operation should only expunge deleted documents # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-forcemerge.html # def forcemerge(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = if _index "#{Utils.__listify(_index)}/_forcemerge" else "_forcemerge" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:forcemerge, [ :flush, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :max_num_segments, :only_expunge_deletes ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices/get.rb000066400000000000000000000061121462737751600333340ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns information about one or more indices. # # @option arguments [List] :index A comma-separated list of index names # @option arguments [Boolean] :include_type_name Whether to add the type name to the response (default: false) # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Boolean] :ignore_unavailable Ignore unavailable indexes (default: false) # @option arguments [Boolean] :allow_no_indices Ignore if a wildcard expression resolves to no concrete indices (default: false) # @option arguments [String] :expand_wildcards Whether wildcard expressions should get expanded to open or closed indices (default: open) (options: open, closed, hidden, none, all) # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false) # @option arguments [Boolean] :include_defaults Whether to return all default setting for each of the indices. # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-get-index.html # def get(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = "#{Utils.__listify(_index)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get, [ :include_type_name, :local, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :flat_settings, :include_defaults, :master_timeout ].freeze) end end end end get_alias.rb000066400000000000000000000060151462737751600344300ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns an alias. # # @option arguments [List] :name A comma-separated list of alias names to return # @option arguments [List] :index A comma-separated list of index names to filter aliases # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-aliases.html # def get_alias(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _index && _name "#{Utils.__listify(_index)}/_alias/#{Utils.__listify(_name)}" elsif _index "#{Utils.__listify(_index)}/_alias" elsif _name "_alias/#{Utils.__listify(_name)}" else "_alias" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_alias, [ :ignore_unavailable, :allow_no_indices, :expand_wildcards, :local ].freeze) end end end end get_field_mapping.rb000066400000000000000000000076101462737751600361370ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns mapping for one or more fields. # # @option arguments [List] :fields A comma-separated list of fields # @option arguments [List] :index A comma-separated list of index names # @option arguments [List] :type A comma-separated list of document types *Deprecated* # @option arguments [Boolean] :include_type_name Whether a type should be returned in the body of the mappings. # @option arguments [Boolean] :include_defaults Whether the default mapping values should be returned as well # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-get-field-mapping.html # def get_field_mapping(arguments = {}) _fields = arguments.delete(:field) || arguments.delete(:fields) raise ArgumentError, "Required argument 'field' missing" unless _fields headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_GET path = if _index && _type && _fields "#{Utils.__listify(_index)}/_mapping/#{Utils.__listify(_type)}/field/#{Utils.__listify(_fields)}" elsif _index && _fields "#{Utils.__listify(_index)}/_mapping/field/#{Utils.__listify(_fields)}" elsif _type && _fields "_mapping/#{Utils.__listify(_type)}/field/#{Utils.__listify(_fields)}" else "_mapping/field/#{Utils.__listify(_fields)}" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_field_mapping, [ :include_type_name, :include_defaults, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :local ].freeze) end end end end get_index_template.rb000066400000000000000000000045471462737751600363510ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns an index template. # # @option arguments [String] :name A pattern that returned template names must match # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-templates.html # def get_index_template(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = if _name "_index_template/#{Utils.__listify(_name)}" else "_index_template" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_index_template, [ :flat_settings, :master_timeout, :local ].freeze) end end end end get_mapping.rb000066400000000000000000000067261462737751600350030ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns mappings for one or more indices. # # @option arguments [List] :index A comma-separated list of index names # @option arguments [List] :type A comma-separated list of document types *Deprecated* # @option arguments [Boolean] :include_type_name Whether to add the type name to the response (default: false) # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) *Deprecated* # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-get-mapping.html # def get_mapping(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_GET path = if _index && _type "#{Utils.__listify(_index)}/_mapping/#{Utils.__listify(_type)}" elsif _index "#{Utils.__listify(_index)}/_mapping" elsif _type "_mapping/#{Utils.__listify(_type)}" else "_mapping" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_mapping, [ :include_type_name, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :master_timeout, :local ].freeze) end end end end get_settings.rb000066400000000000000000000067711462737751600352100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns settings for one or more indices. # # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices # @option arguments [List] :name The name of the settings that should be included # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false) # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Boolean] :include_defaults Whether to return all default setting for each of the indices. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-get-settings.html # def get_settings(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = if _index && _name "#{Utils.__listify(_index)}/_settings/#{Utils.__listify(_name)}" elsif _index "#{Utils.__listify(_index)}/_settings" elsif _name "_settings/#{Utils.__listify(_name)}" else "_settings" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_settings, [ :master_timeout, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :flat_settings, :local, :include_defaults ].freeze) end end end end get_template.rb000066400000000000000000000047421462737751600351570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns an index template. # # @option arguments [List] :name The comma separated names of the index templates # @option arguments [Boolean] :include_type_name Whether a type should be returned in the body of the mappings. # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-templates.html # def get_template(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = if _name "_template/#{Utils.__listify(_name)}" else "_template" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_template, [ :include_type_name, :flat_settings, :master_timeout, :local ].freeze) end end end end get_upgrade.rb000066400000000000000000000054761462737751600350000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # DEPRECATED Returns a progress status of current upgrade. # # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # The _upgrade API is no longer useful and will be removed. Instead, see _reindex API. # Deprecated since version 8.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-upgrade.html # def get_upgrade(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _index "#{Utils.__listify(_index)}/_upgrade" else "_upgrade" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_upgrade, [ :ignore_unavailable, :allow_no_indices, :expand_wildcards ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices/open.rb000066400000000000000000000055701462737751600335250ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Opens an index. # # @option arguments [List] :index A comma separated list of indices to open # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [String] :wait_for_active_shards Sets the number of active shards to wait for before the operation returns. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-open-close.html # def open(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = "#{Utils.__listify(_index)}/_open" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:open, [ :timeout, :master_timeout, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :wait_for_active_shards ].freeze) end end end end params_registry.rb000066400000000000000000000037011462737751600357120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 6.1.1 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 6.1.1 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 6.1.1 def get(action) PARAMS.fetch(action, []) end end end end end end put_alias.rb000066400000000000000000000051711462737751600344630ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Creates or updates an alias. # # @option arguments [List] :index A comma-separated list of index names the alias should point to (supports wildcards); use `_all` to perform the operation on all indices. # @option arguments [String] :name The name of the alias to be created or updated # @option arguments [Time] :timeout Explicit timestamp for the document # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The settings for the alias, such as `routing` or `filter` # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-aliases.html # def put_alias(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_PUT path = if _index && _name "#{Utils.__listify(_index)}/_aliases/#{Utils.__listify(_name)}" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_alias, [ :timeout, :master_timeout ].freeze) end end end end put_index_template.rb000066400000000000000000000047501462737751600363760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Creates or updates an index template. # # @option arguments [String] :name The name of the template # @option arguments [Boolean] :create Whether the index template should only be added if new or can also replace an existing one # @option arguments [String] :cause User defined reason for creating/updating the index template # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The template definition (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-templates.html # def put_index_template(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_PUT path = "_index_template/#{Utils.__listify(_name)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_index_template, [ :create, :cause, :master_timeout ].freeze) end end end end put_mapping.rb000066400000000000000000000074101462737751600350230ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Updates the index mappings. # # @option arguments [List] :index A comma-separated list of index names the mapping should be added to (supports wildcards); use `_all` or omit to add the mapping on all indices. # @option arguments [String] :type The name of the document type *Deprecated* # @option arguments [Boolean] :include_type_name Whether a type should be expected in the body of the mappings. # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :write_index_only When true, applies mappings only to the write index of an alias or data stream # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The mapping definition (*Required*) # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-put-mapping.html # def put_mapping(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_PUT path = if _index && _type "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/_mappings" elsif _index "#{Utils.__listify(_index)}/_mappings" elsif _type "_mappings/#{Utils.__listify(_type)}" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_mapping, [ :include_type_name, :timeout, :master_timeout, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :write_index_only ].freeze) end end end end put_settings.rb000066400000000000000000000065251462737751600352360ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Updates the index settings. # # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Boolean] :preserve_existing Whether to update existing settings. If set to `true` existing settings on an index remain unchanged, the default is `false` # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The index settings to be updated (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-update-settings.html # def put_settings(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_PUT path = if _index "#{Utils.__listify(_index)}/_settings" else "_settings" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_settings, [ :master_timeout, :timeout, :preserve_existing, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :flat_settings ].freeze) end end end end put_template.rb000066400000000000000000000052571462737751600352120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Creates or updates an index template. # # @option arguments [String] :name The name of the template # @option arguments [Boolean] :include_type_name Whether a type should be returned in the body of the mappings. # @option arguments [Number] :order The order for this template when merging multiple matching ones (higher numbers are merged later, overriding the lower numbers) # @option arguments [Boolean] :create Whether the index template should only be added if new or can also replace an existing one # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The template definition (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-templates.html # def put_template(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_PUT path = "_template/#{Utils.__listify(_name)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_template, [ :include_type_name, :order, :create, :master_timeout ].freeze) end end end end recovery.rb000066400000000000000000000044141462737751600343370ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns information about ongoing index shard recoveries. # # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices # @option arguments [Boolean] :detailed Whether to display detailed information about shard recovery # @option arguments [Boolean] :active_only Display only those recoveries that are currently on-going # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-recovery.html # def recovery(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _index "#{Utils.__listify(_index)}/_recovery" else "_recovery" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:recovery, [ :detailed, :active_only ].freeze) end end end end refresh.rb000066400000000000000000000051711462737751600341400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Performs the refresh operation in one or more indices. # # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-refresh.html # def refresh(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = if _index "#{Utils.__listify(_index)}/_refresh" else "_refresh" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:refresh, [ :ignore_unavailable, :allow_no_indices, :expand_wildcards ].freeze) end end end end resolve_index.rb000066400000000000000000000042751462737751600353540ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Returns information about any matching indices, aliases, and data streams # # @option arguments [List] :name A comma-separated list of names or wildcard expressions # @option arguments [String] :expand_wildcards Whether wildcard expressions should get expanded to open or closed indices (default: open) (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-resolve-index-api.html # def resolve_index(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = "_resolve/index/#{Utils.__listify(_name)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:resolve_index, [ :expand_wildcards ].freeze) end end end end rollover.rb000066400000000000000000000062331462737751600343460ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Updates an alias to point to a new index when the existing index # is considered to be too large or too old. # # @option arguments [String] :alias The name of the alias to rollover # @option arguments [String] :new_index The name of the rollover index # @option arguments [Boolean] :include_type_name Whether a type should be included in the body of the mappings. # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Boolean] :dry_run If set to true the rollover action will only be validated but not actually performed even if a condition matches. The default is false # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [String] :wait_for_active_shards Set the number of active shards to wait for on the newly created rollover index before the operation returns. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The conditions that needs to be met for executing rollover # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-rollover-index.html # def rollover(arguments = {}) raise ArgumentError, "Required argument 'alias' missing" unless arguments[:alias] headers = arguments.delete(:headers) || {} arguments = arguments.clone _alias = arguments.delete(:alias) _new_index = arguments.delete(:new_index) method = Elasticsearch::API::HTTP_POST path = if _alias && _new_index "#{Utils.__listify(_alias)}/_rollover/#{Utils.__listify(_new_index)}" else "#{Utils.__listify(_alias)}/_rollover" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:rollover, [ :include_type_name, :timeout, :dry_run, :master_timeout, :wait_for_active_shards ].freeze) end end end end segments.rb000066400000000000000000000053641462737751600343330ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Provides low-level information about segments in a Lucene index. # # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :verbose Includes detailed memory usage by Lucene. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-segments.html # def segments(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _index "#{Utils.__listify(_index)}/_segments" else "_segments" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:segments, [ :ignore_unavailable, :allow_no_indices, :expand_wildcards, :verbose ].freeze) end end end end shard_stores.rb000066400000000000000000000055151462737751600352040ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Provides store information for shard copies of indices. # # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices # @option arguments [List] :status A comma-separated list of statuses used to filter on shards to get store information for (options: green, yellow, red, all) # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-shards-stores.html # def shard_stores(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _index "#{Utils.__listify(_index)}/_shard_stores" else "_shard_stores" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:shard_stores, [ :status, :ignore_unavailable, :allow_no_indices, :expand_wildcards ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices/shrink.rb000066400000000000000000000055511462737751600340610ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Allow to shrink an existing index into a new index with fewer primary shards. # # @option arguments [String] :index The name of the source index to shrink # @option arguments [String] :target The name of the target index to shrink into # @option arguments [Boolean] :copy_settings whether or not to copy settings from the source index (defaults to false) # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [String] :wait_for_active_shards Set the number of active shards to wait for on the shrunken index before the operation returns. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The configuration for the target index (`settings` and `aliases`) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-shrink-index.html # def shrink(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'target' missing" unless arguments[:target] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _target = arguments.delete(:target) method = Elasticsearch::API::HTTP_PUT path = "#{Utils.__listify(_index)}/_shrink/#{Utils.__listify(_target)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:shrink, [ :copy_settings, :timeout, :master_timeout, :wait_for_active_shards ].freeze) end end end end simulate_index_template.rb000066400000000000000000000051751462737751600374130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Simulate matching the given index name against the index templates in the system # # @option arguments [String] :name The name of the index (it must be a concrete index name) # @option arguments [Boolean] :create Whether the index template we optionally defined in the body should only be dry-run added if new or can also replace an existing one # @option arguments [String] :cause User defined reason for dry-run creating the new template for simulation purposes # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body New index template definition, which will be included in the simulation, as if it already exists in the system # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-templates.html # def simulate_index_template(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_POST path = "_index_template/_simulate_index/#{Utils.__listify(_name)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:simulate_index_template, [ :create, :cause, :master_timeout ].freeze) end end end end simulate_template.rb000066400000000000000000000050751462737751600362230ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Simulate resolving the given template name or body # # @option arguments [String] :name The name of the index template # @option arguments [Boolean] :create Whether the index template we optionally defined in the body should only be dry-run added if new or can also replace an existing one # @option arguments [String] :cause User defined reason for dry-run creating the new template for simulation purposes # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body New index template definition to be simulated, if no index template name is specified # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-templates.html # def simulate_template(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_POST path = if _name "_index_template/_simulate/#{Utils.__listify(_name)}" else "_index_template/_simulate" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:simulate_template, [ :create, :cause, :master_timeout ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices/split.rb000066400000000000000000000055461462737751600337220ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Allows you to split an existing index into a new index with more primary shards. # # @option arguments [String] :index The name of the source index to split # @option arguments [String] :target The name of the target index to split into # @option arguments [Boolean] :copy_settings whether or not to copy settings from the source index (defaults to false) # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [String] :wait_for_active_shards Set the number of active shards to wait for on the shrunken index before the operation returns. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The configuration for the target index (`settings` and `aliases`) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-split-index.html # def split(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'target' missing" unless arguments[:target] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _target = arguments.delete(:target) method = Elasticsearch::API::HTTP_PUT path = "#{Utils.__listify(_index)}/_split/#{Utils.__listify(_target)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:split, [ :copy_settings, :timeout, :master_timeout, :wait_for_active_shards ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices/stats.rb000066400000000000000000000110231462737751600337100ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Provides statistics on operations happening in an index. # # @option arguments [List] :metric Limit the information returned the specific metrics. (options: _all, completion, docs, fielddata, query_cache, flush, get, indexing, merge, request_cache, refresh, search, segments, store, warmer, suggest) # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices # @option arguments [List] :completion_fields A comma-separated list of fields for `fielddata` and `suggest` index metric (supports wildcards) # @option arguments [List] :fielddata_fields A comma-separated list of fields for `fielddata` index metric (supports wildcards) # @option arguments [List] :fields A comma-separated list of fields for `fielddata` and `completion` index metric (supports wildcards) # @option arguments [List] :groups A comma-separated list of search groups for `search` index metric # @option arguments [String] :level Return stats aggregated at cluster, index or shard level (options: cluster, indices, shards) # @option arguments [List] :types A comma-separated list of document types for the `indexing` index metric # @option arguments [Boolean] :include_segment_file_sizes Whether to report the aggregated disk usage of each one of the Lucene index files (only applies if segment stats are requested) # @option arguments [Boolean] :include_unloaded_segments If set to true segment stats will include stats for segments that are not currently loaded into memory # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :forbid_closed_indices If set to false stats will also collected from closed indices if explicitly specified or if expand_wildcards expands to closed indices # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-stats.html # def stats(arguments = {}) headers = arguments.delete(:headers) || {} method = HTTP_GET parts = Utils.__extract_parts arguments, ParamsRegistry.get(:stats_parts) path = Utils.__pathify Utils.__listify(arguments[:index]), '_stats', Utils.__listify(parts) params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(:stats_params) params[:fields] = Utils.__listify(params[:fields], :escape => false) if params[:fields] params[:groups] = Utils.__listify(params[:groups], :escape => false) if params[:groups] body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:stats_params, [ :completion_fields, :fielddata_fields, :fields, :groups, :level, :types, :include_segment_file_sizes, :include_unloaded_segments, :expand_wildcards, :forbid_closed_indices ].freeze) ParamsRegistry.register(:stats_parts, [ :_all, :completion, :docs, :fielddata, :query_cache, :flush, :get, :indexing, :merge, :request_cache, :refresh, :search, :segments, :store, :warmer, :suggest, :metric ].freeze) end end end end update_aliases.rb000066400000000000000000000040561462737751600354660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Updates index aliases. # # @option arguments [Time] :timeout Request timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The definition of `actions` to perform (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-aliases.html # def update_aliases(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_aliases" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:update_aliases, [ :timeout, :master_timeout ].freeze) end end end end upgrade.rb000066400000000000000000000062341462737751600341320ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # DEPRECATED Upgrades to the current version of Lucene. # # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :wait_for_completion Specify whether the request should block until the all segments are upgraded (default: false) # @option arguments [Boolean] :only_ancient_segments If true, only ancient (an older Lucene major release) segments will be upgraded # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # The _upgrade API is no longer useful and will be removed. Instead, see _reindex API. # Deprecated since version 8.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-upgrade.html # def upgrade(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = if _index "#{Utils.__listify(_index)}/_upgrade" else "_upgrade" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:upgrade, [ :allow_no_indices, :expand_wildcards, :ignore_unavailable, :wait_for_completion, :only_ancient_segments ].freeze) end end end end validate_query.rb000066400000000000000000000112111462737751600355100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions # Allows a user to validate a potentially expensive query without executing it. # # @option arguments [List] :index A comma-separated list of index names to restrict the operation; use `_all` or empty string to perform the operation on all indices # @option arguments [List] :type A comma-separated list of document types to restrict the operation; leave empty to perform the operation on all types *Deprecated* # @option arguments [Boolean] :explain Return detailed information about the error # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [String] :q Query in the Lucene query string syntax # @option arguments [String] :analyzer The analyzer to use for the query string # @option arguments [Boolean] :analyze_wildcard Specify whether wildcard and prefix queries should be analyzed (default: false) # @option arguments [String] :default_operator The default operator for query string query (AND or OR) (options: AND, OR) # @option arguments [String] :df The field to use as default where no field prefix is given in the query string # @option arguments [Boolean] :lenient Specify whether format-based query failures (such as providing text to a numeric field) should be ignored # @option arguments [Boolean] :rewrite Provide a more detailed explanation showing the actual Lucene query that will be executed. # @option arguments [Boolean] :all_shards Execute validation on all shards instead of one random shard per index # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The query definition specified with the Query DSL # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-validate.html # def validate_query(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _index && _type "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/_validate/query" elsif _index "#{Utils.__listify(_index)}/_validate/query" else "_validate/query" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:validate_query, [ :explain, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :q, :analyzer, :analyze_wildcard, :default_operator, :df, :lenient, :rewrite, :all_shards ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/info.rb000066400000000000000000000025351462737751600320770ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns basic information about the cluster. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/index.html # def info(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/ingest/000077500000000000000000000000001462737751600321035ustar00rootroot00000000000000delete_pipeline.rb000066400000000000000000000041331462737751600355010ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/ingest# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Ingest module Actions # Deletes a pipeline. # # @option arguments [String] :id Pipeline ID # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/delete-pipeline-api.html # def delete_pipeline(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_DELETE path = "_ingest/pipeline/#{Utils.__listify(_id)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_pipeline, [ :master_timeout, :timeout ].freeze) end end end end geo_ip_stats.rb000066400000000000000000000027071462737751600350370ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/ingest# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Ingest module Actions # Returns statistical information about geoip databases # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/geoip-stats-api.html # def geo_ip_stats(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_ingest/geoip/stats" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end get_pipeline.rb000066400000000000000000000042751462737751600350250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/ingest# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Ingest module Actions # Returns a pipeline. # # @option arguments [String] :id Comma separated list of pipeline ids. Wildcards supported # @option arguments [Boolean] :summary Return pipelines without their definitions (default: false) # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-pipeline-api.html # def get_pipeline(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = if _id "_ingest/pipeline/#{Utils.__listify(_id)}" else "_ingest/pipeline" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_pipeline, [ :summary, :master_timeout ].freeze) end end end end params_registry.rb000066400000000000000000000037001462737751600355640ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/ingest# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Ingest module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 6.1.1 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 6.1.1 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 6.1.1 def get(action) PARAMS.fetch(action, []) end end end end end end processor_grok.rb000066400000000000000000000027261462737751600354210ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/ingest# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Ingest module Actions # Returns a list of the built-in patterns. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/grok-processor.html#grok-processor-rest-get # def processor_grok(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_ingest/processor/grok" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end put_pipeline.rb000066400000000000000000000046371462737751600350600ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/ingest# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Ingest module Actions # Creates or updates a pipeline. # # @option arguments [String] :id Pipeline ID # @option arguments [Integer] :if_version Required version for optimistic concurrency control for pipeline updates # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The ingest definition (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/put-pipeline-api.html # def put_pipeline(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_PUT path = "_ingest/pipeline/#{Utils.__listify(_id)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_pipeline, [ :if_version, :master_timeout, :timeout ].freeze) end end end end simulate.rb000066400000000000000000000044001462737751600341720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/ingest# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Ingest module Actions # Allows to simulate a pipeline with example documents. # # @option arguments [String] :id Pipeline ID # @option arguments [Boolean] :verbose Verbose mode. Display data output for each processor in executed pipeline # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The simulate definition (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/simulate-pipeline-api.html # def simulate(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_POST path = if _id "_ingest/pipeline/#{Utils.__listify(_id)}/_simulate" else "_ingest/pipeline/_simulate" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:simulate, [ :verbose ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/mget.rb000066400000000000000000000070051462737751600320750ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Allows to get multiple documents in one request. # # @option arguments [String] :index The name of the index # @option arguments [String] :type The type of the document *Deprecated* # @option arguments [List] :stored_fields A comma-separated list of stored fields to return in the response # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) # @option arguments [Boolean] :realtime Specify whether to perform the operation in realtime or search mode # @option arguments [Boolean] :refresh Refresh the shard containing the document before performing the operation # @option arguments [String] :routing Specific routing value # @option arguments [List] :_source True or false to return the _source field or not, or a list of fields to return # @option arguments [List] :_source_excludes A list of fields to exclude from the returned _source field # @option arguments [List] :_source_includes A list of fields to extract and return from the _source field # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Document identifiers; can be either `docs` (containing full document information) or `ids` (when index and type is provided in the URL. (*Required*) # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-multi-get.html # def mget(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_POST path = if _index && _type "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/_mget" elsif _index "#{Utils.__listify(_index)}/_mget" else "_mget" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:mget, [ :stored_fields, :preference, :realtime, :refresh, :routing, :_source, :_source_excludes, :_source_includes ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/msearch.rb000066400000000000000000000120171462737751600325620ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Allows to execute several search operations in one request. # # @option arguments [List] :index A comma-separated list of index names to use as default # @option arguments [List] :type A comma-separated list of document types to use as default # @option arguments [String] :search_type Search operation type (options: query_then_fetch, dfs_query_then_fetch) # @option arguments [Number] :max_concurrent_searches Controls the maximum number of concurrent searches the multi search api will execute # @option arguments [Boolean] :typed_keys Specify whether aggregation and suggester names should be prefixed by their respective types in the response # @option arguments [Number] :pre_filter_shard_size A threshold that enforces a pre-filter roundtrip to prefilter search shards based on query rewriting if the number of shards the search request expands to exceeds the threshold. This filter roundtrip can limit the number of shards significantly if for instance a shard can not match any documents based on its rewrite method ie. if date filters are mandatory to match but the shard bounds and the query are disjoint. # @option arguments [Number] :max_concurrent_shard_requests The number of concurrent shard requests each sub search executes concurrently per node. This value should be used to limit the impact of the search on the cluster in order to limit the number of concurrent shard requests # @option arguments [Boolean] :rest_total_hits_as_int Indicates whether hits.total should be rendered as an integer or an object in the rest search response # @option arguments [Boolean] :ccs_minimize_roundtrips Indicates whether network round-trips should be minimized as part of cross-cluster search requests execution # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The request definitions (metadata-search request definition pairs), separated by newlines (*Required*) # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-multi-search.html # def msearch(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_POST path = if _index && _type "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/_msearch" elsif _index "#{Utils.__listify(_index)}/_msearch" else "_msearch" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] case when body.is_a?(Array) && body.any? { |d| d.has_key? :search } payload = body .inject([]) do |sum, item| meta = item data = meta.delete(:search) sum << meta sum << data sum end .map { |item| Elasticsearch::API.serializer.dump(item) } payload << "" unless payload.empty? payload = payload.join("\n") when body.is_a?(Array) payload = body.map { |d| d.is_a?(String) ? d : Elasticsearch::API.serializer.dump(d) } payload << "" unless payload.empty? payload = payload.join("\n") else payload = body end headers = Utils.ndjson_headers(headers) perform_request(method, path, params, payload, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:msearch, [ :search_type, :max_concurrent_searches, :typed_keys, :pre_filter_shard_size, :max_concurrent_shard_requests, :rest_total_hits_as_int, :ccs_minimize_roundtrips ].freeze) end end end msearch_template.rb000066400000000000000000000074051462737751600344030ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Allows to execute several search template operations in one request. # # @option arguments [List] :index A comma-separated list of index names to use as default # @option arguments [List] :type A comma-separated list of document types to use as default # @option arguments [String] :search_type Search operation type (options: query_then_fetch, dfs_query_then_fetch) # @option arguments [Boolean] :typed_keys Specify whether aggregation and suggester names should be prefixed by their respective types in the response # @option arguments [Number] :max_concurrent_searches Controls the maximum number of concurrent searches the multi search api will execute # @option arguments [Boolean] :rest_total_hits_as_int Indicates whether hits.total should be rendered as an integer or an object in the rest search response # @option arguments [Boolean] :ccs_minimize_roundtrips Indicates whether network round-trips should be minimized as part of cross-cluster search requests execution # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The request definitions (metadata-search request definition pairs), separated by newlines (*Required*) # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-multi-search.html # def msearch_template(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_POST path = if _index && _type "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/_msearch/template" elsif _index "#{Utils.__listify(_index)}/_msearch/template" else "_msearch/template" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] case when body.is_a?(Array) payload = body.map { |d| d.is_a?(String) ? d : Elasticsearch::API.serializer.dump(d) } payload << "" unless payload.empty? payload = payload.join(" ") else payload = body end headers = Utils.ndjson_headers(headers) perform_request(method, path, params, payload, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:msearch_template, [ :search_type, :typed_keys, :max_concurrent_searches, :rest_total_hits_as_int, :ccs_minimize_roundtrips ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/mtermvectors.rb000066400000000000000000000116541462737751600337000ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns multiple termvectors in one request. # # @option arguments [String] :index The index in which the document resides. # @option arguments [String] :type The type of the document. # @option arguments [List] :ids A comma-separated list of documents ids. You must define ids as parameter or set "ids" or "docs" in the request body # @option arguments [Boolean] :term_statistics Specifies if total term frequency and document frequency should be returned. Applies to all returned documents unless otherwise specified in body "params" or "docs". # @option arguments [Boolean] :field_statistics Specifies if document count, sum of document frequencies and sum of total term frequencies should be returned. Applies to all returned documents unless otherwise specified in body "params" or "docs". # @option arguments [List] :fields A comma-separated list of fields to return. Applies to all returned documents unless otherwise specified in body "params" or "docs". # @option arguments [Boolean] :offsets Specifies if term offsets should be returned. Applies to all returned documents unless otherwise specified in body "params" or "docs". # @option arguments [Boolean] :positions Specifies if term positions should be returned. Applies to all returned documents unless otherwise specified in body "params" or "docs". # @option arguments [Boolean] :payloads Specifies if term payloads should be returned. Applies to all returned documents unless otherwise specified in body "params" or "docs". # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) .Applies to all returned documents unless otherwise specified in body "params" or "docs". # @option arguments [String] :routing Specific routing value. Applies to all returned documents unless otherwise specified in body "params" or "docs". # @option arguments [Boolean] :realtime Specifies if requests are real-time as opposed to near-real-time (default: true). # @option arguments [Number] :version Explicit version number for concurrency control # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte, force) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Define ids, documents, parameters or a list of parameters per document here. You must at least provide a list of document ids. See documentation. # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-multi-termvectors.html # def mtermvectors(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone ids = arguments.delete(:ids) _index = arguments.delete(:index) _type = arguments.delete(:type) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _index && _type "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/_mtermvectors" elsif _index "#{Utils.__listify(_index)}/_mtermvectors" else "_mtermvectors" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) if ids body = { :ids => ids } else body = arguments[:body] end perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:mtermvectors, [ :ids, :term_statistics, :field_statistics, :fields, :offsets, :positions, :payloads, :preference, :routing, :realtime, :version, :version_type ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/nodes/000077500000000000000000000000001462737751600317225ustar00rootroot00000000000000clear_repositories_metering_archive.rb000066400000000000000000000047071462737751600414700ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/nodes# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Nodes module Actions # Removes the archived repositories metering information present in the cluster. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [List] :node_id Comma-separated list of node IDs or names used to limit returned information. # @option arguments [Long] :max_archive_version Specifies the maximum archive_version to be cleared from the archive. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/clear-repositories-metering-archive-api.html # def clear_repositories_metering_archive(arguments = {}) raise ArgumentError, "Required argument 'node_id' missing" unless arguments[:node_id] raise ArgumentError, "Required argument 'max_archive_version' missing" unless arguments[:max_archive_version] headers = arguments.delete(:headers) || {} arguments = arguments.clone _node_id = arguments.delete(:node_id) _max_archive_version = arguments.delete(:max_archive_version) method = Elasticsearch::API::HTTP_DELETE path = "_nodes/#{Utils.__listify(_node_id)}/_repositories_metering/#{Utils.__listify(_max_archive_version)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end get_repositories_metering_info.rb000066400000000000000000000040621462737751600404650ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/nodes# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Nodes module Actions # Returns cluster repositories metering information. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [List] :node_id A comma-separated list of node IDs or names to limit the returned information. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-repositories-metering-api.html # def get_repositories_metering_info(arguments = {}) raise ArgumentError, "Required argument 'node_id' missing" unless arguments[:node_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _node_id = arguments.delete(:node_id) method = Elasticsearch::API::HTTP_GET path = "_nodes/#{Utils.__listify(_node_id)}/_repositories_metering" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end hot_threads.rb000066400000000000000000000064121462737751600344770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/nodes# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Nodes module Actions # Returns information about hot threads on each node in the cluster. # # @option arguments [List] :node_id A comma-separated list of node IDs or names to limit the returned information; use `_local` to return information from the node you're connecting to, leave empty to get information from all nodes # @option arguments [Time] :interval The interval for the second sampling of threads # @option arguments [Number] :snapshots Number of samples of thread stacktrace (default: 10) # @option arguments [Number] :threads Specify the number of threads to provide information for (default: 3) # @option arguments [Boolean] :ignore_idle_threads Don't show threads that are in known-idle places, such as waiting on a socket select or pulling from an empty task queue (default: true) # @option arguments [String] :type The type to sample (default: cpu) (options: cpu, wait, block, mem) # @option arguments [String] :sort The sort order for 'cpu' type (default: total) (options: cpu, total) # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # The hot accepts /_cluster/nodes as prefix for backwards compatibility reasons # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-nodes-hot-threads.html # def hot_threads(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _node_id = arguments.delete(:node_id) method = Elasticsearch::API::HTTP_GET path = if _node_id "_cluster/nodes/#{Utils.__listify(_node_id)}/hot_threads" else "_cluster/nodes/hot_threads" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:hot_threads, [ :interval, :snapshots, :threads, :ignore_idle_threads, :type, :sort, :timeout ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/nodes/info.rb000066400000000000000000000055771462737751600332200ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Nodes module Actions # Returns information about nodes in the cluster. # # @option arguments [List] :node_id A comma-separated list of node IDs or names to limit the returned information; use `_local` to return information from the node you're connecting to, leave empty to get information from all nodes # @option arguments [List] :metric A comma-separated list of metrics you wish returned. Use `_all` to retrieve all metrics and `_none` to retrieve the node identity without any additional metrics. (options: settings, os, process, jvm, thread_pool, transport, http, plugins, ingest, indices, aggregations, _all, _none) # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false) # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-nodes-info.html # def info(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _node_id = arguments.delete(:node_id) _metric = arguments.delete(:metric) method = Elasticsearch::API::HTTP_GET path = if _node_id && _metric "_nodes/#{Utils.__listify(_node_id)}/#{Utils.__listify(_metric)}" elsif _node_id "_nodes/#{Utils.__listify(_node_id)}" elsif _metric "_nodes/#{Utils.__listify(_metric)}" else "_nodes" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:info, [ :flat_settings, :timeout ].freeze) end end end end params_registry.rb000066400000000000000000000036771462737751600354200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/nodes# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Nodes module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 6.1.1 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 6.1.1 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 6.1.1 def get(action) PARAMS.fetch(action, []) end end end end end end reload_secure_settings.rb000066400000000000000000000044761462737751600367370ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/nodes# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Nodes module Actions # Reloads secure settings. # # @option arguments [List] :node_id A comma-separated list of node IDs to span the reload/reinit call. Should stay empty because reloading usually involves all cluster nodes. # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body An object containing the password for the elasticsearch keystore # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/secure-settings.html#reloadable-secure-settings # def reload_secure_settings(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _node_id = arguments.delete(:node_id) method = Elasticsearch::API::HTTP_POST path = if _node_id "_nodes/#{Utils.__listify(_node_id)}/reload_secure_settings" else "_nodes/reload_secure_settings" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:reload_secure_settings, [ :timeout ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/nodes/stats.rb000066400000000000000000000114011462737751600334020ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Nodes module Actions # Returns statistical information about nodes in the cluster. # # @option arguments [List] :node_id A comma-separated list of node IDs or names to limit the returned information; use `_local` to return information from the node you're connecting to, leave empty to get information from all nodes # @option arguments [List] :metric Limit the information returned to the specified metrics (options: _all, breaker, fs, http, indices, jvm, os, process, thread_pool, transport, discovery, indexing_pressure) # @option arguments [List] :index_metric Limit the information returned for `indices` metric to the specific index metrics. Isn't used if `indices` (or `all`) metric isn't specified. (options: _all, completion, docs, fielddata, query_cache, flush, get, indexing, merge, request_cache, refresh, search, segments, store, warmer, suggest, shard_stats) # @option arguments [List] :completion_fields A comma-separated list of fields for `fielddata` and `suggest` index metric (supports wildcards) # @option arguments [List] :fielddata_fields A comma-separated list of fields for `fielddata` index metric (supports wildcards) # @option arguments [List] :fields A comma-separated list of fields for `fielddata` and `completion` index metric (supports wildcards) # @option arguments [Boolean] :groups A comma-separated list of search groups for `search` index metric # @option arguments [String] :level Return indices stats aggregated at index, node or shard level (options: indices, node, shards) # @option arguments [List] :types A comma-separated list of document types for the `indexing` index metric # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Boolean] :include_segment_file_sizes Whether to report the aggregated disk usage of each one of the Lucene index files (only applies if segment stats are requested) # @option arguments [Boolean] :include_unloaded_segments If set to true segment stats will include stats for segments that are not currently loaded into memory # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-nodes-stats.html # def stats(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _node_id = arguments.delete(:node_id) _metric = arguments.delete(:metric) _index_metric = arguments.delete(:index_metric) method = Elasticsearch::API::HTTP_GET path = if _node_id && _metric && _index_metric "_nodes/#{Utils.__listify(_node_id)}/stats/#{Utils.__listify(_metric)}/#{Utils.__listify(_index_metric)}" elsif _metric && _index_metric "_nodes/stats/#{Utils.__listify(_metric)}/#{Utils.__listify(_index_metric)}" elsif _node_id && _metric "_nodes/#{Utils.__listify(_node_id)}/stats/#{Utils.__listify(_metric)}" elsif _node_id "_nodes/#{Utils.__listify(_node_id)}/stats" elsif _metric "_nodes/stats/#{Utils.__listify(_metric)}" else "_nodes/stats" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:stats, [ :completion_fields, :fielddata_fields, :fields, :groups, :level, :types, :timeout, :include_segment_file_sizes, :include_unloaded_segments ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/nodes/usage.rb000066400000000000000000000051471462737751600333620ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Nodes module Actions # Returns low-level information about REST actions usage on nodes. # # @option arguments [List] :node_id A comma-separated list of node IDs or names to limit the returned information; use `_local` to return information from the node you're connecting to, leave empty to get information from all nodes # @option arguments [List] :metric Limit the information returned to the specified metrics (options: _all, rest_actions) # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-nodes-usage.html # def usage(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _node_id = arguments.delete(:node_id) _metric = arguments.delete(:metric) method = Elasticsearch::API::HTTP_GET path = if _node_id && _metric "_nodes/#{Utils.__listify(_node_id)}/usage/#{Utils.__listify(_metric)}" elsif _node_id "_nodes/#{Utils.__listify(_node_id)}/usage" elsif _metric "_nodes/usage/#{Utils.__listify(_metric)}" else "_nodes/usage" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:usage, [ :timeout ].freeze) end end end end open_point_in_time.rb000066400000000000000000000052761462737751600347500ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Open a point in time that can be used in subsequent searches # # @option arguments [List] :index A comma-separated list of index names to open point in time; use `_all` or empty string to perform the operation on all indices # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) # @option arguments [String] :routing Specific routing value # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [String] :keep_alive Specific the time to live for the point in time (*Required*) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/point-in-time-api.html # def open_point_in_time(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = "#{Utils.__listify(_index)}/_pit" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:open_point_in_time, [ :preference, :routing, :ignore_unavailable, :expand_wildcards, :keep_alive ].freeze) end end end params_registry.rb000066400000000000000000000035421462737751600342770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 6.1.1 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 6.1.1 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 6.1.1 def get(action) PARAMS.fetch(action, []) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/ping.rb000066400000000000000000000031321462737751600320730ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns whether the cluster is running. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/index.html # def ping(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_HEAD path = "" params = {} body = nil begin perform_request(method, path, params, body, headers).status == 200 ? true : false rescue Exception => e if e.class.to_s =~ /NotFound|ConnectionFailed/ || e.message =~ /Not *Found|404|ConnectionFailed/i false else raise e end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/put_script.rb000066400000000000000000000046551462737751600333450ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Creates or updates a script. # # @option arguments [String] :id Script ID # @option arguments [String] :context Script context # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The document (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-scripting.html # def put_script(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) _context = arguments.delete(:context) method = Elasticsearch::API::HTTP_PUT path = if _id && _context "_scripts/#{Utils.__listify(_id)}/#{Utils.__listify(_context)}" else "_scripts/#{Utils.__listify(_id)}" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_script, [ :timeout, :master_timeout, :context ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/rank_eval.rb000066400000000000000000000057601462737751600331110ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Allows to evaluate the quality of ranked search results over a set of typical search queries # # @option arguments [List] :index A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [String] :search_type Search operation type (options: query_then_fetch, dfs_query_then_fetch) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The ranking evaluation search definition, including search requests, document ratings and ranking metric definition. (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-rank-eval.html # def rank_eval(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = if _index "#{Utils.__listify(_index)}/_rank_eval" else "_rank_eval" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:rank_eval, [ :ignore_unavailable, :allow_no_indices, :expand_wildcards, :search_type ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/reindex.rb000066400000000000000000000065621462737751600326060ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Allows to copy documents from one index to another, optionally filtering the source # documents by a query, changing the destination index settings, or fetching the # documents from a remote cluster. # # @option arguments [Boolean] :refresh Should the affected indexes be refreshed? # @option arguments [Time] :timeout Time each individual bulk request should wait for shards that are unavailable. # @option arguments [String] :wait_for_active_shards Sets the number of shard copies that must be active before proceeding with the reindex operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1) # @option arguments [Boolean] :wait_for_completion Should the request should block until the reindex is complete. # @option arguments [Number] :requests_per_second The throttle to set on this request in sub-requests per second. -1 means no throttle. # @option arguments [Time] :scroll Control how long to keep the search context alive # @option arguments [Number|string] :slices The number of slices this task should be divided into. Defaults to 1, meaning the task isn't sliced into subtasks. Can be set to `auto`. # @option arguments [Number] :max_docs Maximum number of documents to process (default: all documents) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The search definition using the Query DSL and the prototype for the index request. (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-reindex.html # def reindex(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_reindex" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:reindex, [ :refresh, :timeout, :wait_for_active_shards, :wait_for_completion, :requests_per_second, :scroll, :slices, :max_docs ].freeze) end end end reindex_rethrottle.rb000066400000000000000000000041321462737751600347720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Changes the number of requests per second for a particular Reindex operation. # # @option arguments [String] :task_id The task id to rethrottle # @option arguments [Number] :requests_per_second The throttle to set on this request in floating sub-requests per second. -1 means set no throttle. (*Required*) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-reindex.html # def reindex_rethrottle(arguments = {}) raise ArgumentError, "Required argument 'task_id' missing" unless arguments[:task_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _task_id = arguments.delete(:task_id) method = Elasticsearch::API::HTTP_POST path = "_reindex/#{Utils.__listify(_task_id)}/_rethrottle" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:reindex_rethrottle, [ :requests_per_second ].freeze) end end end render_search_template.rb000066400000000000000000000036101462737751600355570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Allows to use the Mustache language to pre-render a search definition. # # @option arguments [String] :id The id of the stored search template # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The search definition template and its params # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/render-search-template-api.html # def render_search_template(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _id "_render/template/#{Utils.__listify(_id)}" else "_render/template" end params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end scripts_painless_execute.rb000066400000000000000000000036231462737751600361730ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Allows an arbitrary script to be executed and a result to be returned # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The script to execute # # @see https://www.elastic.co/guide/en/elasticsearch/painless/7.17/painless-execute-api.html # def scripts_painless_execute(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = "_scripts/painless/_execute" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/scroll.rb000066400000000000000000000052611462737751600324410ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Allows to retrieve a large numbers of results from a single search request. # # @option arguments [String] :scroll_id The scroll ID *Deprecated* # @option arguments [Time] :scroll Specify how long a consistent view of the index should be maintained for scrolled search # @option arguments [Boolean] :rest_total_hits_as_int Indicates whether hits.total should be rendered as an integer or an object in the rest search response # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The scroll ID if not passed by URL or query parameter. # # *Deprecation notice*: # A scroll id can be quite large and should be specified as part of the body # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-request-body.html#request-body-search-scroll # def scroll(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _scroll_id = arguments.delete(:scroll_id) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _scroll_id "_search/scroll/#{Utils.__listify(_scroll_id)}" else "_search/scroll" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:scroll, [ :scroll, :scroll_id, :rest_total_hits_as_int ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/search.rb000066400000000000000000000231731462737751600324120ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns results matching a query. # # @option arguments [List] :index A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices # @option arguments [List] :type A comma-separated list of document types to search; leave empty to perform the operation on all types # @option arguments [String] :analyzer The analyzer to use for the query string # @option arguments [Boolean] :analyze_wildcard Specify whether wildcard and prefix queries should be analyzed (default: false) # @option arguments [Boolean] :ccs_minimize_roundtrips Indicates whether network round-trips should be minimized as part of cross-cluster search requests execution # @option arguments [String] :default_operator The default operator for query string query (AND or OR) (options: AND, OR) # @option arguments [String] :df The field to use as default where no field prefix is given in the query string # @option arguments [Boolean] :explain Specify whether to return detailed information about score computation as part of a hit # @option arguments [List] :stored_fields A comma-separated list of stored fields to return as part of a hit # @option arguments [List] :docvalue_fields A comma-separated list of fields to return as the docvalue representation of a field for each hit # @option arguments [Number] :from Starting offset (default: 0) # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :ignore_throttled Whether specified concrete, expanded or aliased indices should be ignored when throttled # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :lenient Specify whether format-based query failures (such as providing text to a numeric field) should be ignored # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) # @option arguments [String] :q Query in the Lucene query string syntax # @option arguments [List] :routing A comma-separated list of specific routing values # @option arguments [Time] :scroll Specify how long a consistent view of the index should be maintained for scrolled search # @option arguments [String] :search_type Search operation type (options: query_then_fetch, dfs_query_then_fetch) # @option arguments [Number] :size Number of hits to return (default: 10) # @option arguments [List] :sort A comma-separated list of : pairs # @option arguments [List] :_source True or false to return the _source field or not, or a list of fields to return # @option arguments [List] :_source_excludes A list of fields to exclude from the returned _source field # @option arguments [List] :_source_includes A list of fields to extract and return from the _source field # @option arguments [Number] :terminate_after The maximum number of documents to collect for each shard, upon reaching which the query execution will terminate early. # @option arguments [List] :stats Specific 'tag' of the request for logging and statistical purposes # @option arguments [String] :suggest_field Specify which field to use for suggestions # @option arguments [String] :suggest_mode Specify suggest mode (options: missing, popular, always) # @option arguments [Number] :suggest_size How many suggestions to return in response # @option arguments [String] :suggest_text The source text for which the suggestions should be returned # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Boolean] :track_scores Whether to calculate and return scores even if they are not used for sorting # @option arguments [Boolean] :track_total_hits Indicate if the number of documents that match the query should be tracked # @option arguments [Boolean] :allow_partial_search_results Indicate if an error should be returned if there is a partial search failure or timeout # @option arguments [Boolean] :typed_keys Specify whether aggregation and suggester names should be prefixed by their respective types in the response # @option arguments [Boolean] :version Specify whether to return document version as part of a hit # @option arguments [Boolean] :seq_no_primary_term Specify whether to return sequence number and primary term of the last modification of each hit # @option arguments [Boolean] :request_cache Specify if request cache should be used for this request or not, defaults to index level setting # @option arguments [Number] :batched_reduce_size The number of shard results that should be reduced at once on the coordinating node. This value should be used as a protection mechanism to reduce the memory overhead per search request if the potential number of shards in the request can be large. # @option arguments [Number] :max_concurrent_shard_requests The number of concurrent shard requests per node this search executes concurrently. This value should be used to limit the impact of the search on the cluster in order to limit the number of concurrent shard requests # @option arguments [Number] :pre_filter_shard_size A threshold that enforces a pre-filter roundtrip to prefilter search shards based on query rewriting if the number of shards the search request expands to exceeds the threshold. This filter roundtrip can limit the number of shards significantly if for instance a shard can not match any documents based on its rewrite method ie. if date filters are mandatory to match but the shard bounds and the query are disjoint. # @option arguments [Boolean] :rest_total_hits_as_int Indicates whether hits.total should be rendered as an integer or an object in the rest search response # @option arguments [String] :min_compatible_shard_node The minimum compatible version that all shards involved in search should have for this request to be successful # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The search definition using the Query DSL # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-search.html # def search(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone arguments[:index] = UNDERSCORE_ALL if !arguments[:index] && arguments[:type] _index = arguments.delete(:index) _type = arguments.delete(:type) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _index && _type "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/_search" elsif _index "#{Utils.__listify(_index)}/_search" else "_search" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:search, [ :analyzer, :analyze_wildcard, :ccs_minimize_roundtrips, :default_operator, :df, :explain, :stored_fields, :docvalue_fields, :from, :ignore_unavailable, :ignore_throttled, :allow_no_indices, :expand_wildcards, :lenient, :preference, :q, :routing, :scroll, :search_type, :size, :sort, :_source, :_source_excludes, :_source_includes, :terminate_after, :stats, :suggest_field, :suggest_mode, :suggest_size, :suggest_text, :timeout, :track_scores, :track_total_hits, :allow_partial_search_results, :typed_keys, :version, :seq_no_primary_term, :request_cache, :batched_reduce_size, :max_concurrent_shard_requests, :pre_filter_shard_size, :rest_total_hits_as_int, :min_compatible_shard_node ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/search_mvt.rb000066400000000000000000000102561462737751600332760ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Searches a vector tile for geospatial values. Returns results as a binary Mapbox vector tile. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [List] :index Comma-separated list of data streams, indices, or aliases to search # @option arguments [String] :field Field containing geospatial data to return # @option arguments [Integer] :zoom Zoom level for the vector tile to search # @option arguments [Integer] :x X coordinate for the vector tile to search # @option arguments [Integer] :y Y coordinate for the vector tile to search # @option arguments [Boolean] :exact_bounds If false, the meta layer's feature is the bounding box of the tile. If true, the meta layer's feature is a bounding box resulting from a `geo_bounds` aggregation. # @option arguments [Integer] :extent Size, in pixels, of a side of the vector tile. # @option arguments [Integer] :grid_precision Additional zoom levels available through the aggs layer. Accepts 0-8. # @option arguments [String] :grid_type Determines the geometry type for features in the aggs layer. (options: grid, point, centroid) # @option arguments [Integer] :size Maximum number of features to return in the hits layer. Accepts 0-10000. # @option arguments [Boolean|long] :track_total_hits Indicate if the number of documents that match the query should be tracked. A number can also be specified, to accurately track the total hit count up to the number. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Search request body. # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-vector-tile-api.html # def search_mvt(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'field' missing" unless arguments[:field] raise ArgumentError, "Required argument 'zoom' missing" unless arguments[:zoom] raise ArgumentError, "Required argument 'x' missing" unless arguments[:x] raise ArgumentError, "Required argument 'y' missing" unless arguments[:y] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _field = arguments.delete(:field) _zoom = arguments.delete(:zoom) _x = arguments.delete(:x) _y = arguments.delete(:y) method = Elasticsearch::API::HTTP_POST path = "#{Utils.__listify(_index)}/_mvt/#{Utils.__listify(_field)}/#{Utils.__listify(_zoom)}/#{Utils.__listify(_x)}/#{Utils.__listify(_y)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:search_mvt, [ :exact_bounds, :extent, :grid_precision, :grid_type, :size, :track_total_hits ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/search_shards.rb000066400000000000000000000057371462737751600337640ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns information about the indices and shards that a search request would be executed against. # # @option arguments [List] :index A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) # @option arguments [String] :routing Specific routing value # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-shards.html # def search_shards(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _index "#{Utils.__listify(_index)}/_search_shards" else "_search_shards" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:search_shards, [ :preference, :routing, :local, :ignore_unavailable, :allow_no_indices, :expand_wildcards ].freeze) end end end search_template.rb000066400000000000000000000113631462737751600342240ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Allows to use the Mustache language to pre-render a search definition. # # @option arguments [List] :index A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices # @option arguments [List] :type A comma-separated list of document types to search; leave empty to perform the operation on all types # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :ignore_throttled Whether specified concrete, expanded or aliased indices should be ignored when throttled # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) # @option arguments [List] :routing A comma-separated list of specific routing values # @option arguments [Time] :scroll Specify how long a consistent view of the index should be maintained for scrolled search # @option arguments [String] :search_type Search operation type (options: query_then_fetch, dfs_query_then_fetch) # @option arguments [Boolean] :explain Specify whether to return detailed information about score computation as part of a hit # @option arguments [Boolean] :profile Specify whether to profile the query execution # @option arguments [Boolean] :typed_keys Specify whether aggregation and suggester names should be prefixed by their respective types in the response # @option arguments [Boolean] :rest_total_hits_as_int Indicates whether hits.total should be rendered as an integer or an object in the rest search response # @option arguments [Boolean] :ccs_minimize_roundtrips Indicates whether network round-trips should be minimized as part of cross-cluster search requests execution # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The search definition template and its params (*Required*) # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-template.html # def search_template(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_POST path = if _index && _type "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/_search/template" elsif _index "#{Utils.__listify(_index)}/_search/template" else "_search/template" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:search_template, [ :ignore_unavailable, :ignore_throttled, :allow_no_indices, :expand_wildcards, :preference, :routing, :scroll, :search_type, :explain, :profile, :typed_keys, :rest_total_hits_as_int, :ccs_minimize_roundtrips ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/shutdown/000077500000000000000000000000001462737751600324655ustar00rootroot00000000000000delete_node.rb000066400000000000000000000034101462737751600352000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/shutdown# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Shutdown module Actions # Removes a node from the shutdown list. Designed for indirect use by ECE/ESS and ECK. Direct use is not supported. # # @option arguments [String] :node_id The node id of node to be removed from the shutdown state # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current # def delete_node(arguments = {}) raise ArgumentError, "Required argument 'node_id' missing" unless arguments[:node_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _node_id = arguments.delete(:node_id) method = Elasticsearch::API::HTTP_DELETE path = "_nodes/#{Utils.__listify(_node_id)}/shutdown" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end get_node.rb000066400000000000000000000034731462737751600345260ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/shutdown# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Shutdown module Actions # Retrieve status of a node or nodes that are currently marked as shutting down. Designed for indirect use by ECE/ESS and ECK. Direct use is not supported. # # @option arguments [String] :node_id Which node for which to retrieve the shutdown status # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current # def get_node(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _node_id = arguments.delete(:node_id) method = Elasticsearch::API::HTTP_GET path = if _node_id "_nodes/#{Utils.__listify(_node_id)}/shutdown" else "_nodes/shutdown" end params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end params_registry.rb000066400000000000000000000037021462737751600361500ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/shutdown# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Shutdown module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 6.1.1 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 6.1.1 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 6.1.1 def get(action) PARAMS.fetch(action, []) end end end end end end put_node.rb000066400000000000000000000036501462737751600345540ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/shutdown# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Shutdown module Actions # Adds a node to be shut down. Designed for indirect use by ECE/ESS and ECK. Direct use is not supported. # # @option arguments [String] :node_id The node id of node to be shut down # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The shutdown type definition to register (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current # def put_node(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'node_id' missing" unless arguments[:node_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _node_id = arguments.delete(:node_id) method = Elasticsearch::API::HTTP_PUT path = "_nodes/#{Utils.__listify(_node_id)}/shutdown" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/snapshot/000077500000000000000000000000001462737751600324515ustar00rootroot00000000000000cleanup_repository.rb000066400000000000000000000042601462737751600366470ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Snapshot module Actions # Removes stale data from repository. # # @option arguments [String] :repository A repository name # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/clean-up-snapshot-repo-api.html # def cleanup_repository(arguments = {}) raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository] headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) method = Elasticsearch::API::HTTP_POST path = "_snapshot/#{Utils.__listify(_repository)}/_cleanup" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:cleanup_repository, [ :master_timeout, :timeout ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/snapshot/clone.rb000066400000000000000000000055241462737751600341040ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Snapshot module Actions # Clones indices from one snapshot into another snapshot in the same repository. # # @option arguments [String] :repository A repository name # @option arguments [String] :snapshot The name of the snapshot to clone from # @option arguments [String] :target_snapshot The name of the cloned snapshot to create # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The snapshot clone definition (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-snapshots.html # def clone(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository] raise ArgumentError, "Required argument 'snapshot' missing" unless arguments[:snapshot] raise ArgumentError, "Required argument 'target_snapshot' missing" unless arguments[:target_snapshot] headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) _snapshot = arguments.delete(:snapshot) _target_snapshot = arguments.delete(:target_snapshot) method = Elasticsearch::API::HTTP_PUT path = "_snapshot/#{Utils.__listify(_repository)}/#{Utils.__listify(_snapshot)}/_clone/#{Utils.__listify(_target_snapshot)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:clone, [ :master_timeout ].freeze) end end end end create.rb000066400000000000000000000050211462737751600341600ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Snapshot module Actions # Creates a snapshot in a repository. # # @option arguments [String] :repository A repository name # @option arguments [String] :snapshot A snapshot name # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Boolean] :wait_for_completion Should this request wait until the operation has completed before returning # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The snapshot definition # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-snapshots.html # def create(arguments = {}) raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository] raise ArgumentError, "Required argument 'snapshot' missing" unless arguments[:snapshot] headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) _snapshot = arguments.delete(:snapshot) method = Elasticsearch::API::HTTP_PUT path = "_snapshot/#{Utils.__listify(_repository)}/#{Utils.__listify(_snapshot)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:create, [ :master_timeout, :wait_for_completion ].freeze) end end end end create_repository.rb000066400000000000000000000046651462737751600364740ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Snapshot module Actions # Creates a repository. # # @option arguments [String] :repository A repository name # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Boolean] :verify Whether to verify the repository after creation # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The repository definition (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-snapshots.html # def create_repository(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository] headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) method = Elasticsearch::API::HTTP_PUT path = "_snapshot/#{Utils.__listify(_repository)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:create_repository, [ :master_timeout, :timeout, :verify ].freeze) end end end end delete.rb000066400000000000000000000047131462737751600341660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Snapshot module Actions # Deletes a snapshot. # # @option arguments [String] :repository A repository name # @option arguments [String] :snapshot A snapshot name # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-snapshots.html # def delete(arguments = {}) raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository] raise ArgumentError, "Required argument 'snapshot' missing" unless arguments[:snapshot] headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) _snapshot = arguments.delete(:snapshot) method = Elasticsearch::API::HTTP_DELETE path = "_snapshot/#{Utils.__listify(_repository)}/#{Utils.__listify(_snapshot)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil if Array(arguments[:ignore]).include?(404) Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete, [ :master_timeout ].freeze) end end end end delete_repository.rb000066400000000000000000000046161462737751600364670ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Snapshot module Actions # Deletes a repository. # # @option arguments [List] :repository Name of the snapshot repository to unregister. Wildcard (`*`) patterns are supported. # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-snapshots.html # def delete_repository(arguments = {}) raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository] headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) method = Elasticsearch::API::HTTP_DELETE path = "_snapshot/#{Utils.__listify(_repository)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil if Array(arguments[:ignore]).include?(404) Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_repository, [ :master_timeout, :timeout ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/snapshot/get.rb000066400000000000000000000105651462737751600335640ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Snapshot module Actions # Returns information about a snapshot. # # @option arguments [String] :repository A repository name # @option arguments [List] :snapshot A comma-separated list of snapshot names # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Boolean] :ignore_unavailable Whether to ignore unavailable snapshots, defaults to false which means a SnapshotMissingException is thrown # @option arguments [Boolean] :index_details Whether to include details of each index in the snapshot, if those details are available. Defaults to false. # @option arguments [Boolean] :include_repository Whether to include the repository name in the snapshot info. Defaults to true. # @option arguments [String] :sort Allows setting a sort order for the result. Defaults to start_time (options: start_time, duration, name, repository, index_count, shard_count, failed_shard_count) # @option arguments [Integer] :size Maximum number of snapshots to return. Defaults to 0 which means return all that match without limit. # @option arguments [String] :order Sort order (options: asc, desc) # @option arguments [String] :from_sort_value Value of the current sort column at which to start retrieval. # @option arguments [String] :after Offset identifier to start pagination from as returned by the 'next' field in the response body. # @option arguments [Integer] :offset Numeric offset to start pagination based on the snapshots matching the request. Defaults to 0 # @option arguments [String] :slm_policy_filter Filter snapshots by a comma-separated list of SLM policy names that snapshots belong to. Accepts wildcards. Use the special pattern '_none' to match snapshots without an SLM policy # @option arguments [Boolean] :verbose Whether to show verbose snapshot info or only show the basic info found in the repository index blob # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-snapshots.html # def get(arguments = {}) raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository] raise ArgumentError, "Required argument 'snapshot' missing" unless arguments[:snapshot] headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) _snapshot = arguments.delete(:snapshot) method = Elasticsearch::API::HTTP_GET path = "_snapshot/#{Utils.__listify(_repository)}/#{Utils.__listify(_snapshot)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil if Array(arguments[:ignore]).include?(404) Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get, [ :master_timeout, :ignore_unavailable, :index_details, :include_repository, :sort, :size, :order, :from_sort_value, :after, :offset, :slm_policy_filter, :verbose ].freeze) end end end end get_repository.rb000066400000000000000000000046631462737751600360060ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Snapshot module Actions # Returns information about a repository. # # @option arguments [List] :repository A comma-separated list of repository names # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-snapshots.html # def get_repository(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) method = Elasticsearch::API::HTTP_GET path = if _repository "_snapshot/#{Utils.__listify(_repository)}" else "_snapshot" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil if Array(arguments[:ignore]).include?(404) Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_repository, [ :master_timeout, :local ].freeze) end end end end params_registry.rb000066400000000000000000000037021462737751600361340ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Snapshot module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 6.1.1 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 6.1.1 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 6.1.1 def get(action) PARAMS.fetch(action, []) end end end end end end repository_analyze.rb000066400000000000000000000074701462737751600366710ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Snapshot module Actions # Analyzes a repository for correctness and performance # # @option arguments [String] :repository A repository name # @option arguments [Number] :blob_count Number of blobs to create during the test. Defaults to 100. # @option arguments [Number] :concurrency Number of operations to run concurrently during the test. Defaults to 10. # @option arguments [Number] :read_node_count Number of nodes on which to read a blob after writing. Defaults to 10. # @option arguments [Number] :early_read_node_count Number of nodes on which to perform an early read on a blob, i.e. before writing has completed. Early reads are rare actions so the 'rare_action_probability' parameter is also relevant. Defaults to 2. # @option arguments [Number] :seed Seed for the random number generator used to create the test workload. Defaults to a random value. # @option arguments [Number] :rare_action_probability Probability of taking a rare action such as an early read or an overwrite. Defaults to 0.02. # @option arguments [String] :max_blob_size Maximum size of a blob to create during the test, e.g '1gb' or '100mb'. Defaults to '10mb'. # @option arguments [String] :max_total_data_size Maximum total size of all blobs to create during the test, e.g '1tb' or '100gb'. Defaults to '1gb'. # @option arguments [Time] :timeout Explicit operation timeout. Defaults to '30s'. # @option arguments [Boolean] :detailed Whether to return detailed results or a summary. Defaults to 'false' so that only the summary is returned. # @option arguments [Boolean] :rarely_abort_writes Whether to rarely abort writes before they complete. Defaults to 'true'. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-snapshots.html # def repository_analyze(arguments = {}) raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository] headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) method = Elasticsearch::API::HTTP_POST path = "_snapshot/#{Utils.__listify(_repository)}/_analyze" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:repository_analyze, [ :blob_count, :concurrency, :read_node_count, :early_read_node_count, :seed, :rare_action_probability, :max_blob_size, :max_total_data_size, :timeout, :detailed, :rarely_abort_writes ].freeze) end end end end restore.rb000066400000000000000000000050211462737751600344000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Snapshot module Actions # Restores a snapshot. # # @option arguments [String] :repository A repository name # @option arguments [String] :snapshot A snapshot name # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Boolean] :wait_for_completion Should this request wait until the operation has completed before returning # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Details of what to restore # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-snapshots.html # def restore(arguments = {}) raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository] raise ArgumentError, "Required argument 'snapshot' missing" unless arguments[:snapshot] headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) _snapshot = arguments.delete(:snapshot) method = Elasticsearch::API::HTTP_POST path = "_snapshot/#{Utils.__listify(_repository)}/#{Utils.__listify(_snapshot)}/_restore" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:restore, [ :master_timeout, :wait_for_completion ].freeze) end end end end status.rb000066400000000000000000000053721462737751600342510ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Snapshot module Actions # Returns information about the status of a snapshot. # # @option arguments [String] :repository A repository name # @option arguments [List] :snapshot A comma-separated list of snapshot names # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Boolean] :ignore_unavailable Whether to ignore unavailable snapshots, defaults to false which means a SnapshotMissingException is thrown # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-snapshots.html # def status(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) _snapshot = arguments.delete(:snapshot) method = Elasticsearch::API::HTTP_GET path = if _repository && _snapshot "_snapshot/#{Utils.__listify(_repository)}/#{Utils.__listify(_snapshot)}/_status" elsif _repository "_snapshot/#{Utils.__listify(_repository)}/_status" else "_snapshot/_status" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil if Array(arguments[:ignore]).include?(404) Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:status, [ :master_timeout, :ignore_unavailable ].freeze) end end end end verify_repository.rb000066400000000000000000000042271462737751600365270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Snapshot module Actions # Verifies a repository. # # @option arguments [String] :repository A repository name # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-snapshots.html # def verify_repository(arguments = {}) raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository] headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) method = Elasticsearch::API::HTTP_POST path = "_snapshot/#{Utils.__listify(_repository)}/_verify" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:verify_repository, [ :master_timeout, :timeout ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/tasks/000077500000000000000000000000001462737751600317375ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/tasks/cancel.rb000066400000000000000000000060101462737751600335060ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Tasks module Actions # Cancels a task, if it can be cancelled through an API. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :task_id Cancel the task with specified task id (node_id:task_number) # @option arguments [List] :nodes A comma-separated list of node IDs or names to limit the returned information; use `_local` to return information from the node you're connecting to, leave empty to get information from all nodes # @option arguments [List] :actions A comma-separated list of actions that should be cancelled. Leave empty to cancel all. # @option arguments [String] :parent_task_id Cancel tasks with specified parent task id (node_id:task_number). Set to -1 to cancel all. # @option arguments [Boolean] :wait_for_completion Should the request block until the cancellation of the task and its descendant tasks is completed. Defaults to false # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/tasks.html # def cancel(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _task_id = arguments.delete(:task_id) method = Elasticsearch::API::HTTP_POST path = if _task_id "_tasks/#{Utils.__listify(_task_id)}/_cancel" else "_tasks/_cancel" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:cancel, [ :nodes, :actions, :parent_task_id, :wait_for_completion ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/tasks/get.rb000066400000000000000000000045061462737751600330500ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Tasks module Actions # Returns information about a task. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :task_id Return the task with specified id (node_id:task_number) # @option arguments [Boolean] :wait_for_completion Wait for the matching tasks to complete (default: false) # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/tasks.html # def get(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _task_id = arguments.delete(:task_id) method = Elasticsearch::API::HTTP_GET path = "_tasks/#{Utils.__listify(_task_id)}" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get, [ :wait_for_completion, :timeout ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/tasks/list.rb000066400000000000000000000057321462737751600332460ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Tasks module Actions # Returns a list of tasks. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [List] :nodes A comma-separated list of node IDs or names to limit the returned information; use `_local` to return information from the node you're connecting to, leave empty to get information from all nodes # @option arguments [List] :actions A comma-separated list of actions that should be returned. Leave empty to return all. # @option arguments [Boolean] :detailed Return detailed task information (default: false) # @option arguments [String] :parent_task_id Return tasks with specified parent task id (node_id:task_number). Set to -1 to return all. # @option arguments [Boolean] :wait_for_completion Wait for the matching tasks to complete (default: false) # @option arguments [String] :group_by Group tasks by nodes or parent/child relationships (options: nodes, parents, none) # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/tasks.html # def list(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_tasks" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:list, [ :nodes, :actions, :detailed, :parent_task_id, :wait_for_completion, :group_by, :timeout ].freeze) end end end end params_registry.rb000066400000000000000000000036771462737751600354350ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/tasks# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Tasks module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 6.1.1 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 6.1.1 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 6.1.1 def get(action) PARAMS.fetch(action, []) end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/termvectors.rb000066400000000000000000000111601462737751600335130ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Returns information and statistics about terms in the fields of a particular document. # # @option arguments [String] :index The index in which the document resides. (*Required*) # @option arguments [String] :id The id of the document, when not specified a doc param should be supplied. # @option arguments [String] :type The type of the document. # @option arguments [Boolean] :term_statistics Specifies if total term frequency and document frequency should be returned. # @option arguments [Boolean] :field_statistics Specifies if document count, sum of document frequencies and sum of total term frequencies should be returned. # @option arguments [List] :fields A comma-separated list of fields to return. # @option arguments [Boolean] :offsets Specifies if term offsets should be returned. # @option arguments [Boolean] :positions Specifies if term positions should be returned. # @option arguments [Boolean] :payloads Specifies if term payloads should be returned. # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random). # @option arguments [String] :routing Specific routing value. # @option arguments [Boolean] :realtime Specifies if request is real-time as opposed to near-real-time (default: true). # @option arguments [Number] :version Explicit version number for concurrency control # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte, force) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Define parameters and or supply a document to get termvectors for. See documentation. # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-termvectors.html # def termvectors(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _id = arguments.delete(:id) _type = arguments.delete(:type) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end endpoint = arguments.delete(:endpoint) || '_termvectors' path = if _index && _type && _id "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/#{Utils.__listify(_id)}/#{endpoint}" elsif _index && _type "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/#{endpoint}" elsif _index && _id "#{Utils.__listify(_index)}/#{endpoint}/#{Utils.__listify(_id)}" else "#{Utils.__listify(_index)}/#{endpoint}" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Deprecated: Use the plural version, {#termvectors} # def termvector(arguments = {}) termvectors(arguments.merge endpoint: '_termvector') end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:termvectors, [ :term_statistics, :field_statistics, :fields, :offsets, :positions, :payloads, :preference, :routing, :realtime, :version, :version_type ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions/update.rb000066400000000000000000000116111462737751600324210ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Updates a document with a script or partial document. # # @option arguments [String] :id Document ID # @option arguments [String] :index The name of the index # @option arguments [String] :type The type of the document *Deprecated* # @option arguments [String] :wait_for_active_shards Sets the number of shard copies that must be active before proceeding with the update operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1) # @option arguments [List] :_source True or false to return the _source field or not, or a list of fields to return # @option arguments [List] :_source_excludes A list of fields to exclude from the returned _source field # @option arguments [List] :_source_includes A list of fields to extract and return from the _source field # @option arguments [String] :lang The script language (default: painless) # @option arguments [String] :refresh If `true` then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` (the default) then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Number] :retry_on_conflict Specify how many times should the operation be retried when a conflict occurs (default: 0) # @option arguments [String] :routing Specific routing value # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Number] :if_seq_no only perform the update operation if the last operation that has changed the document has the specified sequence number # @option arguments [Number] :if_primary_term only perform the update operation if the last operation that has changed the document has the specified primary term # @option arguments [Boolean] :require_alias When true, requires destination is an alias. Default is false # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The request definition requires either `script` or partial `doc` (*Required*) # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-update.html # def update(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_POST path = if _index && _type && _id "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/#{Utils.__listify(_id)}/_update" else "#{Utils.__listify(_index)}/_update/#{Utils.__listify(_id)}" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] if Array(arguments[:ignore]).include?(404) Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:update, [ :wait_for_active_shards, :_source, :_source_excludes, :_source_includes, :lang, :refresh, :retry_on_conflict, :routing, :timeout, :if_seq_no, :if_primary_term, :require_alias ].freeze) end end end update_by_query.rb000066400000000000000000000166501462737751600342710ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Performs an update on every document in the index without changing the source, # for example to pick up a mapping change. # # @option arguments [List] :index A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices (*Required*) # @option arguments [List] :type A comma-separated list of document types to search; leave empty to perform the operation on all types # @option arguments [String] :analyzer The analyzer to use for the query string # @option arguments [Boolean] :analyze_wildcard Specify whether wildcard and prefix queries should be analyzed (default: false) # @option arguments [String] :default_operator The default operator for query string query (AND or OR) (options: AND, OR) # @option arguments [String] :df The field to use as default where no field prefix is given in the query string # @option arguments [Number] :from Starting offset (default: 0) # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :conflicts What to do when the update by query hits version conflicts? (options: abort, proceed) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :lenient Specify whether format-based query failures (such as providing text to a numeric field) should be ignored # @option arguments [String] :pipeline Ingest pipeline to set on index requests made by this action. (default: none) # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) # @option arguments [String] :q Query in the Lucene query string syntax # @option arguments [List] :routing A comma-separated list of specific routing values # @option arguments [Time] :scroll Specify how long a consistent view of the index should be maintained for scrolled search # @option arguments [String] :search_type Search operation type (options: query_then_fetch, dfs_query_then_fetch) # @option arguments [Time] :search_timeout Explicit timeout for each search request. Defaults to no timeout. # @option arguments [Number] :size Deprecated, please use `max_docs` instead # @option arguments [Number] :max_docs Maximum number of documents to process (default: all documents) # @option arguments [List] :sort A comma-separated list of : pairs # @option arguments [Number] :terminate_after The maximum number of documents to collect for each shard, upon reaching which the query execution will terminate early. # @option arguments [List] :stats Specific 'tag' of the request for logging and statistical purposes # @option arguments [Boolean] :version Specify whether to return document version as part of a hit # @option arguments [Boolean] :version_type Should the document increment the version number (internal) on hit or not (reindex) # @option arguments [Boolean] :request_cache Specify if request cache should be used for this request or not, defaults to index level setting # @option arguments [Boolean] :refresh Should the affected indexes be refreshed? # @option arguments [Time] :timeout Time each individual bulk request should wait for shards that are unavailable. # @option arguments [String] :wait_for_active_shards Sets the number of shard copies that must be active before proceeding with the update by query operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1) # @option arguments [Number] :scroll_size Size on the scroll request powering the update by query # @option arguments [Boolean] :wait_for_completion Should the request should block until the update by query operation is complete. # @option arguments [Number] :requests_per_second The throttle to set on this request in sub-requests per second. -1 means no throttle. # @option arguments [Number|string] :slices The number of slices this task should be divided into. Defaults to 1, meaning the task isn't sliced into subtasks. Can be set to `auto`. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The search definition using the Query DSL # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-update-by-query.html # def update_by_query(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_POST path = if _index && _type "#{Utils.__listify(_index)}/#{Utils.__listify(_type)}/_update_by_query" else "#{Utils.__listify(_index)}/_update_by_query" end params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:update_by_query, [ :analyzer, :analyze_wildcard, :default_operator, :df, :from, :ignore_unavailable, :allow_no_indices, :conflicts, :expand_wildcards, :lenient, :pipeline, :preference, :q, :routing, :scroll, :search_type, :search_timeout, :size, :max_docs, :sort, :terminate_after, :stats, :version, :version_type, :request_cache, :refresh, :timeout, :wait_for_active_shards, :scroll_size, :wait_for_completion, :requests_per_second, :slices ].freeze) end end end update_by_query_rethrottle.rb000066400000000000000000000042021462737751600365330ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Actions # Changes the number of requests per second for a particular Update By Query operation. # # @option arguments [String] :task_id The task id to rethrottle # @option arguments [Number] :requests_per_second The throttle to set on this request in floating sub-requests per second. -1 means set no throttle. (*Required*) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-update-by-query.html # def update_by_query_rethrottle(arguments = {}) raise ArgumentError, "Required argument 'task_id' missing" unless arguments[:task_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _task_id = arguments.delete(:task_id) method = Elasticsearch::API::HTTP_POST path = "_update_by_query/#{Utils.__listify(_task_id)}/_rethrottle" params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:update_by_query_rethrottle, [ :requests_per_second ].freeze) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/namespace/000077500000000000000000000000001462737751600311065ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/namespace/cat.rb000066400000000000000000000022541462737751600322050ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cat module Actions; end # Client for the "cat" namespace (includes the {Cat::Actions} methods) # class CatClient include Common::Client, Common::Client::Base, Cat::Actions end # Proxy method for {CatClient}, available in the receiving object # def cat @cat ||= CatClient.new(self) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/namespace/cluster.rb000066400000000000000000000023211462737751600331120ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Cluster module Actions; end # Client for the "cluster" namespace (includes the {Cluster::Actions} methods) # class ClusterClient include Common::Client, Common::Client::Base, Cluster::Actions end # Proxy method for {ClusterClient}, available in the receiving object # def cluster @cluster ||= ClusterClient.new(self) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/namespace/common.rb000066400000000000000000000024531462737751600327270ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Common module Actions; end module Client # Base client wrapper # module Base attr_reader :client def initialize(client) @client = client end end # Delegates the `perform_request` method to the wrapped client # def perform_request(method, path, params={}, body=nil, headers=nil) client.perform_request method, path, params, body, headers end end end end end dangling_indices.rb000066400000000000000000000024321462737751600346360ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module DanglingIndices module Actions; end # Client for the "dangling_indices" namespace (includes the {DanglingIndices::Actions} methods) # class DanglingIndicesClient include Common::Client, Common::Client::Base, DanglingIndices::Actions end # Proxy method for {DanglingIndicesClient}, available in the receiving object # def dangling_indices @dangling_indices ||= DanglingIndicesClient.new(self) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/namespace/features.rb000066400000000000000000000023311462737751600332500ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Features module Actions; end # Client for the "features" namespace (includes the {Features::Actions} methods) # class FeaturesClient include Common::Client, Common::Client::Base, Features::Actions end # Proxy method for {FeaturesClient}, available in the receiving object # def features @features ||= FeaturesClient.new(self) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/namespace/indices.rb000066400000000000000000000023211462737751600330470ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Indices module Actions; end # Client for the "indices" namespace (includes the {Indices::Actions} methods) # class IndicesClient include Common::Client, Common::Client::Base, Indices::Actions end # Proxy method for {IndicesClient}, available in the receiving object # def indices @indices ||= IndicesClient.new(self) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/namespace/ingest.rb000066400000000000000000000023101462737751600327200ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Ingest module Actions; end # Client for the "ingest" namespace (includes the {Ingest::Actions} methods) # class IngestClient include Common::Client, Common::Client::Base, Ingest::Actions end # Proxy method for {IngestClient}, available in the receiving object # def ingest @ingest ||= IngestClient.new(self) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/namespace/nodes.rb000066400000000000000000000022771462737751600325530ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Nodes module Actions; end # Client for the "nodes" namespace (includes the {Nodes::Actions} methods) # class NodesClient include Common::Client, Common::Client::Base, Nodes::Actions end # Proxy method for {NodesClient}, available in the receiving object # def nodes @nodes ||= NodesClient.new(self) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/namespace/remote.rb000066400000000000000000000023101462737751600327220ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Remote module Actions; end # Client for the "remote" namespace (includes the {Remote::Actions} methods) # class RemoteClient include Common::Client, Common::Client::Base, Remote::Actions end # Proxy method for {RemoteClient}, available in the receiving object # def remote @remote ||= RemoteClient.new(self) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/namespace/security.rb000066400000000000000000000023311462737751600333010ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Security module Actions; end # Client for the "security" namespace (includes the {Security::Actions} methods) # class SecurityClient include Common::Client, Common::Client::Base, Security::Actions end # Proxy method for {SecurityClient}, available in the receiving object # def security @security ||= SecurityClient.new(self) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/namespace/shutdown.rb000066400000000000000000000023321462737751600333060ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Shutdown module Actions; end # Client for the "shutdown" namespace (includes the {Shutdown::Actions} methods) # class ShutdownClient include Common::Client, Common::Client::Base, Shutdown::Actions end # Proxy method for {ShutdownClient}, available in the receiving object # def shutdown @shutdown ||= ShutdownClient.new(self) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/namespace/snapshot.rb000066400000000000000000000023321462737751600332720ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Snapshot module Actions; end # Client for the "snapshot" namespace (includes the {Snapshot::Actions} methods) # class SnapshotClient include Common::Client, Common::Client::Base, Snapshot::Actions end # Proxy method for {SnapshotClient}, available in the receiving object # def snapshot @snapshot ||= SnapshotClient.new(self) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/namespace/tasks.rb000066400000000000000000000022771462737751600325700ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API module Tasks module Actions; end # Client for the "tasks" namespace (includes the {Tasks::Actions} methods) # class TasksClient include Common::Client, Common::Client::Base, Tasks::Actions end # Proxy method for {TasksClient}, available in the receiving object # def tasks @tasks ||= TasksClient.new(self) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/utils.rb000066400000000000000000000247071462737751600306510ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'erb' module Elasticsearch module API # Generic utility methods # module Utils # URL-escape a string # # @example # __escape('foo/bar') # => 'foo%2Fbar' # __escape('bar^bam') # => 'bar%5Ebam' # # @api private def __escape(string) return string if string == '*' ERB::Util.url_encode(string.to_s) end # Create a "list" of values from arguments, ignoring nil values and encoding special characters. # # @example Create a list from array # __listify(['A','B']) # => 'A,B' # # @example Create a list from arguments # __listify('A','B') # => 'A,B' # # @example Escape values # __listify('foo','bar^bam') # => 'foo,bar%5Ebam' # # @example Do not escape the values # __listify('foo','bar^bam', escape: false) # => 'foo,bar^bam' # # @api private def __listify(*list) options = list.last.is_a?(Hash) ? list.pop : {} escape = options[:escape] Array(list). flat_map { |e| e.respond_to?(:split) ? e.split(',') : e }. flatten. compact. map { |e| escape == false ? e : __escape(e) }. join(',') end # Create a path (URL part) from arguments, ignoring nil values and empty strings. # # @example Create a path from array # __pathify(['foo', '', nil, 'bar']) # => 'foo/bar' # # @example Create a path from arguments # __pathify('foo', '', nil, 'bar') # => 'foo/bar' # # # @example Encode special characters # __pathify(['foo', 'bar^bam']) # => 'foo/bar%5Ebam' # # @api private def __pathify(*segments) Array(segments).flatten. compact. reject { |s| s.to_s.strip.empty? }. join('/'). squeeze('/') end # Convert an array of payloads into Elasticsearch `header\ndata` format # # Supports various different formats of the payload: Array of Strings, Header/Data pairs, # or the conveniency "combined" format where data is passed along with the header # in a single item. # # Elasticsearch::API::Utils.__bulkify [ # { :index => { :_index => 'myindexA', :_type => 'mytype', :_id => '1', :data => { :title => 'Test' } } }, # { :update => { :_index => 'myindexB', :_type => 'mytype', :_id => '2', :data => { :doc => { :title => 'Update' } } } } # ] # # # => {"index":{"_index":"myindexA","_type":"mytype","_id":"1"}} # # => {"title":"Test"} # # => {"update":{"_index":"myindexB","_type":"mytype","_id":"2"}} # # => {"doc":{"title":"Update"}} # def __bulkify(payload) operations = %w[index create delete update] case # Hashes with `:data` when payload.any? { |d| d.is_a?(Hash) && d.values.first.is_a?(Hash) && operations.include?(d.keys.first.to_s) && (d.values.first[:data] || d.values.first['data']) } payload = payload. inject([]) do |sum, item| operation, meta = item.to_a.first meta = meta.clone data = meta.delete(:data) || meta.delete('data') sum << { operation => meta } sum << data if data sum end. map { |item| Elasticsearch::API.serializer.dump(item) } payload << '' unless payload.empty? # Array of strings when payload.all? { |d| d.is_a? String } payload << '' # Header/Data pairs else payload = payload.map { |item| Elasticsearch::API.serializer.dump(item) } payload << '' end payload = payload.join("\n") end # Validates the argument Hash against common and valid API parameters # # @param arguments [Hash] Hash of arguments to verify and extract, **with symbolized keys** # @param valid_params [Array] An array of symbols with valid keys # # @return [Hash] Return whitelisted Hash # @raise [ArgumentError] If the arguments Hash contains invalid keys # # @example Extract parameters # __validate_and_extract_params( { :foo => 'qux' }, [:foo, :bar] ) # # => { :foo => 'qux' } # # @example Raise an exception for invalid parameters # __validate_and_extract_params( { :foo => 'qux', :bam => 'mux' }, [:foo, :bar] ) # # ArgumentError: "URL parameter 'bam' is not supported" # # @example Skip validating parameters # __validate_and_extract_params( { :foo => 'q', :bam => 'm' }, [:foo, :bar], { skip_parameter_validation: true } ) # # => { :foo => "q", :bam => "m" } # # @example Skip validating parameters when the module setting is set # Elasticsearch::API.settings[:skip_parameter_validation] = true # __validate_and_extract_params( { :foo => 'q', :bam => 'm' }, [:foo, :bar] ) # # => { :foo => "q", :bam => "m" } # # @api private # def __validate_and_extract_params(arguments, params=[], options={}) if options[:skip_parameter_validation] || Elasticsearch::API.settings[:skip_parameter_validation] arguments else __validate_params(arguments, params) __extract_params(arguments, params, options.merge(:escape => false)) end end def __validate_params(arguments, valid_params=[]) arguments.each do |k,v| raise ArgumentError, "URL parameter '#{k}' is not supported" \ unless COMMON_PARAMS.include?(k) || COMMON_QUERY_PARAMS.include?(k) || valid_params.include?(k) end end def __extract_params(arguments, params=[], options={}) result = arguments.select { |k,v| COMMON_QUERY_PARAMS.include?(k) || params.include?(k) } result = Hash[result] unless result.is_a?(Hash) # Normalize Ruby 1.8 and Ruby 1.9 Hash#select behaviour result = Hash[result.map { |k,v| v.is_a?(Array) ? [k, __listify(v, options)] : [k,v] }] # Listify Arrays result end # Extracts the valid parts of the URL from the arguments # # @note Mutates the `arguments` argument, to prevent failures in `__validate_and_extract_params`. # # @param arguments [Hash] Hash of arguments to verify and extract, **with symbolized keys** # @param valid_parts [Array] An array of symbol with valid keys # # @return [Array] Valid parts of the URL as an array of strings # # @example Extract parts # __extract_parts { :foo => true }, [:foo, :bar] # # => [:foo] # # # @api private # def __extract_parts(arguments, valid_parts=[]) parts = Hash[arguments.select { |k,v| valid_parts.include?(k) }] parts = parts.reduce([]) { |sum, item| k, v = item; v.is_a?(TrueClass) ? sum << k.to_s : sum << v } arguments.delete_if { |k,v| valid_parts.include? k } return parts end # Calls the given block, rescuing from `StandardError`. # # Primary use case is the `:ignore` parameter for API calls. # # Returns `false` if exception contains NotFound in its class name or message, # else re-raises the exception. # # @yield [block] A block of code to be executed with exception handling. # # @api private # def __rescue_from_not_found(&block) yield rescue StandardError => e if e.class.to_s =~ /NotFound/ || e.message =~ /Not\s*Found/i false else raise e end end def __report_unsupported_parameters(arguments, params=[]) messages = [] unsupported_params = params.select {|d| d.is_a?(Hash) ? arguments.include?(d.keys.first) : arguments.include?(d) } unsupported_params.each do |param| name = case param when Symbol param when Hash param.keys.first else raise ArgumentError, "The param must be a Symbol or a Hash" end explanation = if param.is_a?(Hash) ". #{param.values.first[:explanation]}." else ". This parameter is not supported in the version you're using: #{Elasticsearch::API::VERSION}, and will be removed in the next release." end message = "[!] You are using unsupported parameter [:#{name}]" if source = caller && caller.last message += " in `#{source}`" end message += explanation messages << message end unless messages.empty? messages << "Suppress this warning by the `-WO` command line flag." if STDERR.tty? Kernel.warn messages.map { |m| "\e[31;1m#{m}\e[0m" }.join("\n") else Kernel.warn messages.join("\n") end end end def __report_unsupported_method(name) message = "[!] You are using unsupported method [#{name}]" if source = caller && caller.last message += " in `#{source}`" end message += ". This method is not supported in the version you're using: #{Elasticsearch::API::VERSION}, and will be removed in the next release. Suppress this warning by the `-WO` command line flag." if STDERR.tty? Kernel.warn "\e[31;1m#{message}\e[0m" else Kernel.warn message end end def ndjson_headers(headers) headers.merge!('Content-Type' => 'application/x-ndjson') unless ['1', 'true'].include?(ENV['ELASTIC_CLIENT_APIVERSIONING']) headers end extend self end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/lib/elasticsearch/api/version.rb000066400000000000000000000015231462737751600311650ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API VERSION = '7.17.11'.freeze end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/000077500000000000000000000000001462737751600237535ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/000077500000000000000000000000001462737751600265655ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/000077500000000000000000000000001462737751600273365ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/000077500000000000000000000000001462737751600307765ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/bulk_spec.rb000066400000000000000000000075221462737751600333000ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#bulk' do let(:expected_args) do [ 'POST', url, params, body, headers ] end let(:headers) { { 'Content-Type' => 'application/x-ndjson' } } let(:params) { {} } let(:url) { '_bulk' } let(:body) { '' } context 'when a list of operations is provided' do let(:body) do <<-PAYLOAD.gsub(/^\s+/, '') {"index":{"_index":"myindexA","_type":"mytype","_id":"1"}} {"title":"Test"} {"update":{"_index":"myindexB","_type":"mytype","_id":"2"}} {"doc":{"title":"Update"}} {"delete":{"_index":"myindexC","_type":"mytypeC","_id":"3"}} {"index":{"_index":"myindexD","_type":"mytype","_id":"1"}} {"data":"MYDATA"} PAYLOAD end it 'performs the request' do expect(client_double.bulk(:body => [ { :index => { :_index => 'myindexA', :_type => 'mytype', :_id => '1', :data => { :title => 'Test' } } }, { :update => { :_index => 'myindexB', :_type => 'mytype', :_id => '2', :data => { :doc => { :title => 'Update' } } } }, { :delete => { :_index => 'myindexC', :_type => 'mytypeC', :_id => '3' } }, { :index => { :_index => 'myindexD', :_type => 'mytype', :_id => '1', :data => { :data => 'MYDATA' } } }, ])).to eq({}) end end context 'when an index is specified' do let(:url) { 'myindex/_bulk' } it 'performs the request' do expect(client_double.bulk(index: 'myindex', body: [])).to eq({}) end end context 'when there are data keys in the head/data payloads' do let(:body) do <<-PAYLOAD.gsub(/^\s+/, '') {"update":{"_index":"myindex","_type":"mytype","_id":"1"}} {"doc":{"data":{"title":"Update"}}} PAYLOAD end it 'performs the request' do expect(client_double.bulk(body:[ { :update => { :_index => 'myindex', :_type => 'mytype', :_id => '1' } }, { :doc => { :data => { :title => 'Update' } } } ])).to eq({}) end end context 'when the payload is a string' do let(:body) do 'foo\nbar' end it 'performs the request' do expect(client_double.bulk(body: 'foo\nbar')).to eq({}) end end context 'when the payload is an array of Strings' do let(:body) do "foo\nbar\n" end it 'performs the request' do expect(client_double.bulk(body: ['foo', 'bar'])).to eq({}) end end context 'when there are parameters' do let(:params) do { refresh: true } end it 'performs the request' do expect(client_double.bulk(refresh: true, body: [])).to eq({}) end end context 'when url characters need to be URL-escaped' do let(:url) do 'foo%5Ebar/_bulk' end it 'performs the request' do expect(client_double.bulk(index: 'foo^bar', body: [])).to eq({}) end end context 'when the type is provided' do let(:url) do 'myindex/mytype/_bulk' end it 'performs the request' do expect(client_double.bulk(index: 'myindex', type: 'mytype', body: [])).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat/000077500000000000000000000000001462737751600315455ustar00rootroot00000000000000aliases_spec.rb000066400000000000000000000020211462737751600344410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#aliases' do let(:expected_args) do [ 'GET', '_cat/aliases', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.aliases).to eq({}) end end allocation_spec.rb000066400000000000000000000020321462737751600351470ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#allocation' do let(:expected_args) do [ 'GET', '_cat/allocation', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.allocation).to eq({}) end end count_spec.rb000066400000000000000000000020131462737751600341510ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#count' do let(:expected_args) do [ 'GET', '_cat/count', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.count).to eq({}) end end fielddata_spec.rb000066400000000000000000000025171462737751600347470ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#fielddata' do let(:expected_args) do [ 'GET', '_cat/fielddata', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.fielddata).to eq({}) end context 'when field are specified' do let(:expected_args) do [ 'GET', '_cat/fielddata/foo,bar', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.fielddata(fields: ['foo', 'bar'])).to eq({}) end end end health_spec.rb000066400000000000000000000020161462737751600342710ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#health' do let(:expected_args) do [ 'GET', '_cat/health', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.health).to eq({}) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat/help_spec.rb000066400000000000000000000020031462737751600340270ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#help' do let(:expected_args) do [ 'GET', '_cat', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.help).to eq({}) end end indices_spec.rb000066400000000000000000000020211462737751600344360ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#indices' do let(:expected_args) do [ 'GET', '_cat/indices', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.indices).to eq({}) end end master_spec.rb000066400000000000000000000020161462737751600343170ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#master' do let(:expected_args) do [ 'GET', '_cat/master', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.master).to eq({}) end end nodeattrs_spec.rb000066400000000000000000000020271462737751600350310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#nodeattrs' do let(:expected_args) do [ 'GET', '_cat/nodeattrs', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.nodeattrs).to eq({}) end end nodes_spec.rb000066400000000000000000000020131462737751600341310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#nodes' do let(:expected_args) do [ 'GET', '_cat/nodes', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.nodes).to eq({}) end end pending_tasks_spec.rb000066400000000000000000000020431462737751600356550ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#pending_tasks' do let(:expected_args) do [ 'GET', '_cat/pending_tasks', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.pending_tasks).to eq({}) end end plugins_spec.rb000066400000000000000000000020211462737751600345010ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#plugins' do let(:expected_args) do [ 'GET', '_cat/plugins', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.plugins).to eq({}) end end recovery_spec.rb000066400000000000000000000020241462737751600346610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#recovery' do let(:expected_args) do [ 'GET', '_cat/recovery', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.recovery).to eq({}) end end repositories_spec.rb000066400000000000000000000020401462737751600355500ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#repositories' do let(:expected_args) do [ 'GET', '_cat/repositories', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.repositories).to eq({}) end end segments_spec.rb000066400000000000000000000023641462737751600346570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#segments' do let(:expected_args) do [ 'GET', url, {}, nil, {} ] end let(:url) do '_cat/segments' end it 'performs the request' do expect(client_double.cat.segments).to eq({}) end context 'when index is specified' do let(:url) do '_cat/segments/foo' end it 'performs the request' do expect(client_double.cat.segments(index: 'foo')).to eq({}) end end end shards_spec.rb000066400000000000000000000020161462737751600343100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#shards' do let(:expected_args) do [ 'GET', '_cat/shards', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.shards).to eq({}) end end snapshot_spec.rb000066400000000000000000000020561462737751600346670ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#snapshots' do let(:expected_args) do [ 'GET', '_cat/snapshots/foo', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.snapshots(repository: 'foo')).to eq({}) end end tasks_spec.rb000066400000000000000000000020131462737751600341460ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#tasks' do let(:expected_args) do [ 'GET', '_cat/tasks', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.tasks).to eq({}) end end templates_spec.rb000066400000000000000000000020271462737751600350240ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#templates' do let(:expected_args) do [ 'GET', '_cat/templates', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.templates).to eq({}) end end thread_pool_spec.rb000066400000000000000000000020351462737751600353250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cat#thread_pool' do let(:expected_args) do [ 'GET', '_cat/thread_pool', {}, nil, {} ] end it 'performs the request' do expect(client_double.cat.thread_pool).to eq({}) end end clear_scroll_spec.rb000066400000000000000000000026001462737751600347200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#clear_scroll' do let(:expected_args) do [ 'DELETE', '_search/scroll/abc123', {}, nil, {} ] end it 'performs the request' do expect(client_double.clear_scroll(scroll_id: 'abc123')).to eq({}) end context 'when a list of scroll ids is provided' do let(:expected_args) do [ 'DELETE', '_search/scroll/abc123,def456', {}, nil, {} ] end it 'performs the request' do expect(client_double.clear_scroll(scroll_id: ['abc123', 'def456'])).to eq({}) end end end close_point_in_time_spec.rb000066400000000000000000000020211462737751600362730ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#close_point_in_time' do let(:expected_args) do [ 'DELETE', '_pit', {}, nil, {} ] end it 'performs the request' do expect(client_double.close_point_in_time).to eq({}) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cluster/000077500000000000000000000000001462737751600324575ustar00rootroot00000000000000allocation_explain_spec.rb000066400000000000000000000020761462737751600376110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#allocation_explain' do let(:expected_args) do [ 'GET', '_cluster/allocation/explain', {}, nil, {} ] end it 'performs the request' do expect(client_double.cluster.allocation_explain).to eq({}) end end get_settings_spec.rb000066400000000000000000000020501462737751600364330ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#get_settings' do let(:expected_args) do [ 'GET', '_cluster/settings', {}, nil, {} ] end it 'performs the request' do expect(client_double.cluster.get_settings).to eq({}) end end health_spec.rb000066400000000000000000000032071462737751600352060ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#health' do let(:expected_args) do [ 'GET', '_cluster/health', {}, nil, {} ] end it 'performs the request' do expect(client_double.cluster.health).to eq({}) end context 'when a level is specified' do let(:expected_args) do [ 'GET', '_cluster/health', { level: 'indices' }, nil, {} ] end it 'performs the request' do expect(client_double.cluster.health(level: 'indices')).to eq({}) end end context 'when an index is specified' do let(:expected_args) do [ 'GET', '_cluster/health/foo', {}, nil, {} ] end it 'performs the request' do expect(client_double.cluster.health(index: 'foo')).to eq({}) end end end pending_tasks_spec.rb000066400000000000000000000020571462737751600365740ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#pending_tasks' do let(:expected_args) do [ 'GET', '_cluster/pending_tasks', {}, nil, {} ] end it 'performs the request' do expect(client_double.cluster.pending_tasks).to eq({}) end end put_settings_spec.rb000066400000000000000000000020611462737751600364660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#put_settings' do let(:expected_args) do [ 'PUT', '_cluster/settings', {}, {}, {} ] end it 'performs the request' do expect(client_double.cluster.put_settings(body: {})).to eq({}) end end remote_info_spec.rb000066400000000000000000000020411462737751600362420ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#remote_info' do let(:expected_args) do [ 'GET', '_remote/info', {}, nil, {} ] end it 'performs the request' do expect(client_double.cluster.remote_info).to eq({}) end end reroute_spec.rb000066400000000000000000000026511462737751600354300ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#reroute' do let(:expected_args) do [ 'POST', '_cluster/reroute', {}, {}, {} ] end it 'performs the request' do expect(client_double.cluster.reroute).to eq({}) end context 'when a body is specified' do let(:expected_args) do [ 'POST', '_cluster/reroute', {}, { commands: [ move: { index: 'myindex', shard: 0 }] }, {} ] end it 'performs the request' do expect(client_double.cluster.reroute(body: { commands: [ move: { index: 'myindex', shard: 0 }] })).to eq({}) end end end state_spec.rb000066400000000000000000000025211462737751600350570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#state' do let(:expected_args) do [ 'GET', '_cluster/state', {}, nil, {} ] end it 'performs the request' do expect(client_double.cluster.state).to eq({}) end context 'when a metric is specified' do let(:expected_args) do [ 'GET', '_cluster/state/foo,bar', {}, nil, {} ] end it 'performs the request' do expect(client_double.cluster.state(metric: ['foo', 'bar'])).to eq({}) end end end stats_spec.rb000066400000000000000000000020271462737751600350760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#stats' do let(:expected_args) do [ 'GET', '_cluster/stats', {}, nil, {} ] end it 'performs the request' do expect(client_double.cluster.stats).to eq({}) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/count_spec.rb000066400000000000000000000031571462737751600334730ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#count' do let(:expected_args) do [ 'GET', '_count', {}, nil, {} ] end it 'performs the request' do expect(client_double.count).to eq({}) end context 'when an index and type are specified' do let(:expected_args) do [ 'GET', 'foo,bar/t1,t2/_count', {}, nil, {} ] end it 'performs the request' do expect(client_double.count(index: ['foo','bar'], type: ['t1','t2'])).to eq({}) end end context 'when there is a query provided' do let(:expected_args) do [ 'POST', '_count', {}, { match: { foo: 'bar' } }, {} ] end it 'performs the request' do expect(client_double.count(body: { match: { foo: 'bar' } })).to eq({}) end end end create_document_spec.rb000066400000000000000000000042621462737751600354230ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#create_document' do let(:expected_args) do [ 'PUT', 'foo/bar/123', { op_type: 'create' }, { foo: 'bar' }, {} ] end it 'performs the request' do expect(client_double.create(index: 'foo', type: 'bar', id: '123', body: { foo: 'bar'})).to eq({}) end context 'when the request needs to be URL-escaped' do let(:expected_args) do [ 'PUT', 'foo/bar%2Fbam/123', { op_type: 'create' }, {}, {} ] end it 'performs the request' do expect(client_double.create(index: 'foo', type: 'bar/bam', id: '123', body: {})).to eq({}) end end context 'when an id is provided as an integer' do let(:expected_args) do [ 'PUT', 'foo/bar/1', { op_type: 'create' }, { foo: 'bar' }, {} ] end it 'updates the arguments with the `op_type`' do expect(client_double.create(index: 'foo', type: 'bar', id: 1, body: { foo: 'bar' })).to eq({}) end end context 'when an id is not provided' do let(:expected_args) do [ 'POST', 'foo/bar', { }, { foo: 'bar' }, {} ] end it 'updates the arguments with the `op_type`' do expect(client_double.create(index: 'foo', type: 'bar', body: { foo: 'bar' })).to eq({}) end end end dangling_indices/000077500000000000000000000000001462737751600342005ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actionsdelete_dangling_indices_spec.rb000066400000000000000000000025711462737751600423470ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/dangling_indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'dangling_indices#delete_dangling_index' do let(:expected_args) do [ 'DELETE', '_dangling/foo', {}, nil, {} ] end it 'performs the request' do expect( client_double.dangling_indices.delete_dangling_index(index_uuid: 'foo') ).to eq({}) end context 'when no index_uuid is specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises the exception' do expect do client.dangling_indices.delete_dangling_index end.to raise_exception(ArgumentError) end end end import_dangling_indices_spec.rb000066400000000000000000000025671462737751600424240ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/dangling_indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'dangling_indices#import_dangling_index' do let(:expected_args) do [ 'POST', '_dangling/foo', {}, nil, {} ] end it 'performs the request' do expect( client_double.dangling_indices.import_dangling_index(index_uuid: 'foo') ).to eq({}) end context 'when no index_uuid is specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises the exception' do expect do client.dangling_indices.delete_dangling_index end.to raise_exception(ArgumentError) end end end list_dangling_indices_spec.rb000066400000000000000000000020741462737751600420560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/dangling_indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'dangling_indices#list_dangling_index' do let(:expected_args) do [ 'GET', '_dangling', {}, nil, {} ] end it 'performs the request' do expect( client_double.dangling_indices.list_dangling_indices ).to eq({}) end end delete_by_query_spec.rb000066400000000000000000000040041462737751600354350ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#delete_by_query' do let(:expected_args) do [ 'POST', 'foo/_delete_by_query', {}, { term: {} }, {} ] end it 'requires the :index argument' do expect { Class.new { include Elasticsearch::API }.new.delete_by_query(body: {}) }.to raise_exception(ArgumentError) end it 'performs the request' do expect(client_double.delete_by_query(index: 'foo', body: { term: {} })).to eq({}) end context 'when the type argument is provided' do let(:expected_args) do [ 'POST', 'foo/tweet,post/_delete_by_query', {}, { term: {} }, {} ] end it 'performs the request' do expect(client_double.delete_by_query(index: 'foo', type: ['tweet', 'post'], body: { term: {} })).to eq({}) end end context 'when a query is provided' do let(:expected_args) do [ 'POST', 'foo/_delete_by_query', { q: 'foo:bar' }, { query: 'query' }, {} ] end it 'performs the request' do expect( client_double.delete_by_query( index: 'foo', q: 'foo:bar', body: { query: 'query' } ) ).to eq({}) end end end delete_document_spec.rb000066400000000000000000000053751462737751600354300ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#delete' do let(:expected_args) do [ 'DELETE', 'foo/bar/1', params, nil, {} ] end let(:params) do {} end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :index argument' do expect { client.delete(type: 'bar', id: '1') }.to raise_exception(ArgumentError) end it 'requires the :id argument' do expect { client.delete(index: 'foo', type: 'bar') }.to raise_exception(ArgumentError) end it 'performs the request' do expect(client_double.delete(index: 'foo', type: 'bar', id: '1')).to eq({}) end context 'when url params are provided' do let(:params) do { routing: 'abc123' } end it 'performs the request' do expect(client_double.delete(index: 'foo', type: 'bar', id: '1', routing: 'abc123')).to eq({}) end end context 'when invalid url params are provided' do it 'raises an ArgumentError' do expect { client.delete(index: 'foo', type: 'bar', id: '1', qwertypoiuy: 'asdflkjhg') }.to raise_exception(ArgumentError) end end context 'when the url params need to be escaped' do let(:expected_args) do [ 'DELETE', 'foo%5Ebar/bar%2Fbam/1', params, nil, {} ] end it 'escapes the url params' do expect(client_double.delete(index: 'foo^bar', type: 'bar/bam', id: 1)).to eq({}) end end context 'when the index is not found' do before do expect(client).to receive(:perform_request).and_raise(NotFound) end it 'raises the exception' do expect { client.delete(index: 'foo', type: 'bar', id: 'XXX') }.to raise_exception(NotFound) end context 'when the :ignore option is provided' do it 'does not raise the NotFound exception' do expect(client.delete(index: 'foo', type: 'bar', id: 1, ignore: 404)).to eq(false) end end end end delete_script_spec.rb000066400000000000000000000021641462737751600351070ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#delete_script' do context 'when lang parameter is not provided' do let(:expected_args) do [ 'DELETE', '_scripts/foo', {}, nil, {} ] end it 'performs the request' do expect(client_double.delete_script(id: 'foo')).to eq({}) end end end exists_document_spec.rb000066400000000000000000000060151462737751600354750ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#exists' do let(:expected_args) do [ 'HEAD', url, params, nil, {} ] end let(:params) do {} end let(:url) do 'foo/bar/1' end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :index argument' do expect { client.exists(type: 'bar', id: '1') }.to raise_exception(ArgumentError) end it 'requires the :id argument' do expect { client.exists(index: 'foo', type: 'bar') }.to raise_exception(ArgumentError) end context 'when the type parameter is not provided' do let(:url) do 'foo/_doc/1' end it 'performs the request' do expect(client_double.exists(index: 'foo', id: '1')).to eq(true) end end it 'is aliased to a predicated method' do expect(client_double.exists?(index: 'foo', type: 'bar', id: '1')).to eq(true) end context 'when URL parameters are provided' do let(:params) do { routing: 'abc123' } end it 'passes the parameters' do expect(client_double.exists(index: 'foo', type: 'bar', id: '1', routing: 'abc123')).to eq(true) end end context 'when the request needs to be URL-escaped' do let(:url) do 'foo/bar%2Fbam/1' end it 'URL-escapes the characters' do expect(client_double.exists(index: 'foo', type: 'bar/bam', id: '1')).to eq(true) end end context 'when the response is 404' do before do expect(response_double).to receive(:status).and_return(404) end it 'returns false' do expect(client_double.exists(index: 'foo', type: 'bar', id: '1')).to eq(false) end end context 'when the response is 404 NotFound' do before do expect(response_double).to receive(:status).and_raise(StandardError.new('404 NotFound')) end it 'returns false' do expect(client_double.exists(index: 'foo', type: 'bar', id: '1')).to eq(false) end end context 'when there are other errors' do before do expect(response_double).to receive(:status).and_raise(StandardError) end it 'raises the error' do expect { client_double.exists(index: 'foo', type: 'bar', id: '1') }.to raise_exception(StandardError) end end end explain_document_spec.rb000066400000000000000000000045421462737751600356210ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#explain' do let(:expected_args) do [ method, url, params, body, {} ] end let(:method) { 'POST' } let(:params) do {} end let(:body) do {} end let(:url) do 'foo/bar/1/_explain' end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :index argument' do expect { client.explain(type: 'bar', id: '1') }.to raise_exception(ArgumentError) end it 'requires the :id argument' do expect { client.explain(index: 'foo', type: 'bar') }.to raise_exception(ArgumentError) end it 'performs the request' do expect(client_double.explain(index: 'foo', type: 'bar', id: 1, body: {})).to eq({}) end context 'when a query is provided' do let(:method) { 'GET' } let(:params) do { q: 'abc123' } end let(:body) do nil end it 'passes the query' do expect(client_double.explain(index: 'foo', type: 'bar', id: '1', q: 'abc123')).to eq({}) end end context 'when a query definition is provided' do let(:body) do { query: { match: {} } } end it 'passes the query definition' do expect(client_double.explain(index: 'foo', type: 'bar', id: '1', body: { query: { match: {} } })).to eq({}) end end context 'when the request needs to be URL-escaped' do let(:url) do 'foo%5Ebar/bar%2Fbam/1/_explain' end it 'URL-escapes the parts' do expect(client_double.explain(index: 'foo^bar', type: 'bar/bam', id: '1', body: { })).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/features/000077500000000000000000000000001462737751600326145ustar00rootroot00000000000000get_features_spec.rb000066400000000000000000000020261462737751600365510ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/features# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.featues#get_features' do let(:expected_args) do [ 'GET', '_features', {}, nil, {} ] end it 'performs the request' do expect(client_double.features.get_features).to eq({}) end end reset_features_spec.rb000066400000000000000000000020421462737751600371120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/features# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.featues#reset_features' do let(:expected_args) do [ 'POST', '_features/_reset', {}, nil, {} ] end it 'performs the request' do expect(client_double.features.reset_features).to eq({}) end end field_caps_spec.rb000066400000000000000000000020761462737751600343540ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#field_caps' do let(:expected_args) do [ 'GET', 'foo/_field_caps', { fields: 'bar' }, nil, {} ] end it 'performs the request' do expect(client_double.field_caps(index: 'foo', fields: 'bar')).to eq({}) end end get_document_source_spec.rb000066400000000000000000000046011462737751600363140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#get_source' do let(:expected_args) do [ 'GET', url, params, nil, {} ] end let(:params) do { } end let(:url) do 'foo/bar/1/_source' end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :index argument' do expect { client.get_source(type: 'bar', id: '1') }.to raise_exception(ArgumentError) end it 'requires the :id argument' do expect { client.get_source(index: 'foo', type: 'bar') }.to raise_exception(ArgumentError) end context 'when the type parameter is not provided' do let(:url) do 'foo/_source/1' end it 'performs the request' do expect(client_double.get_source(index: 'foo', id: '1')).to eq({}) end end context 'when URL parameters are provided' do let(:params) do { routing: 'abc123' } end it 'Passes the URL params' do expect(client_double.get_source(index: 'foo', type: 'bar', id: '1', routing: 'abc123')).to eq({}) end end context 'when the request needs to be URL-escaped' do let(:url) do 'foo%5Ebar/bar%2Fbam/1/_source' end it 'URL-escapes the parts' do expect(client_double.get_source(index: 'foo^bar', type: 'bar/bam', id: '1')).to eq({}) end end context 'when the request raises a NotFound error' do before do expect(client).to receive(:perform_request).and_raise(NotFound) end it 'raises the error' do expect { client.get_source(index: 'foo', id: '1') }.to raise_exception(NotFound) end end end get_document_spec.rb000066400000000000000000000055441462737751600347430ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#get' do let(:expected_args) do [ 'GET', url, params, nil, {} ] end let(:params) do { } end let(:url) do 'foo/bar/1' end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :index argument' do expect { client.get(type: 'bar', id: '1') }.to raise_exception(ArgumentError) end it 'requires the :id argument' do expect { client.get(index: 'foo', type: 'bar') }.to raise_exception(ArgumentError) end context 'when the type parameter is not provided' do let(:url) do 'foo/_doc/1' end it 'performs the request' do expect(client_double.get(index: 'foo', id: '1')).to eq({}) end end context 'when URL parameters are provided' do let(:params) do { routing: 'abc123' } end it 'Passes the URL params' do expect(client_double.get(index: 'foo', type: 'bar', id: '1', routing: 'abc123')).to eq({}) end end context 'when invalid URL parameters are provided' do it 'Passes the URL params' do expect { client.get(index: 'foo', type: 'bar', id: '1', qwert: 'abc123') }.to raise_exception(ArgumentError) end end context 'when the request needs to be URL-escaped' do let(:url) do 'foo%5Ebar/bar%2Fbam/1' end it 'URL-escapes the parts' do expect(client_double.get(index: 'foo^bar', type: 'bar/bam', id: '1')).to eq({}) end end context 'when the request raises a NotFound error' do before do expect(client).to receive(:perform_request).and_raise(NotFound) end it 'raises an exception' do expect { client.get(index: 'foo', id: '1') }.to raise_exception(NotFound) end context 'when the ignore option is provided' do context 'when the response is 404' do let(:params) do { ignore: 404 } end it 'returns false' do expect(client.get(index: 'foo', type: 'bar', id: '1', ignore: 404)).to eq(false) end end end end end get_script_spec.rb000066400000000000000000000023631462737751600344250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#get_script' do let(:expected_args) do [ 'GET', url, params, nil, {} ] end let(:params) do { } end let(:url) do '_scripts/foo' end context 'when the `lang` parameter is specificed' do let(:params) do { master_timeout: '1s' } end it 'performs the request' do expect(client_double.get_script(master_timeout: '1s', id: 'foo')).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/hashie_spec.rb000066400000000000000000000051151462737751600336000ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' require 'hashie' describe 'Hashie' do let(:json) do <<-JSON { "took": 14, "timed_out": false, "_shards": { "total": 1, "successful": 1, "failed": 0 }, "hits": { "total": 5, "max_score": 0.51104903, "hits": [ { "_index": "myindex", "_type": "mytype", "_id": "1", "_score": 0.51104903, "_source": { "title": "Test 1", "tags": [ "y", "z" ], "published": true, "published_at": "2013-06-22T21:13:00Z", "counter": 1 } } ] }, "facets": { "tags": { "_type": "terms", "missing": 0, "total": 10, "other": 0, "terms": [ { "term": "z", "count": 4 }, { "term": "y", "count": 3 }, { "term": "x", "count": 3 } ] } } } JSON end let(:response) do Hashie::Mash.new MultiJson.load(json) end it 'wraps the response' do expect(response.hits.hits.first._source.title).to eq('Test 1') expect(response.facets.tags.terms.first.term).to eq('z') end end index_document_spec.rb000066400000000000000000000056421462737751600352720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#index' do let(:expected_args) do [ request_type, url, params, body, {} ] end let(:request_type) do 'POST' end let(:params) do { } end let(:url) do 'foo/bar' end let(:body) do { foo: 'bar' } end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :index argument' do expect { client.index(type: 'bar') }.to raise_exception(ArgumentError) end it 'performs the request' do expect(client_double.index(index: 'foo', type: 'bar', body: body)).to eq({}) end context 'when a specific id is provided' do let(:request_type) do 'PUT' end let(:url) do 'foo/bar/1' end it 'performs the request' do expect(client_double.index(index: 'foo', type: 'bar', id: '1', body: body)).to eq({}) end end context 'when URL parameters are provided' do let(:request_type) do 'POST' end let(:url) do 'foo/bar' end let(:params) do { op_type: 'create' } end it 'passes the URL params' do expect(client_double.index(index: 'foo', type: 'bar', op_type: 'create', body: body)).to eq({}) end context 'when a specific id is provided' do let(:request_type) do 'PUT' end let(:url) do 'foo/bar/1' end let(:params) do { op_type: 'create' } end it 'passes the URL params' do expect(client_double.index(index: 'foo', type: 'bar', id: '1', op_type: 'create', body: body)).to eq({}) end end end context 'when the request needs to be URL-escaped' do let(:request_type) do 'PUT' end let(:url) do 'foo/bar%2Fbam/123' end it 'URL-escapes the parts' do expect(client_double.index(index: 'foo', type: 'bar/bam', id: '123', body: body)).to eq({}) end end context 'when an invalid URL parameter is provided' do it 'raises and ArgumentError' do expect { client.index(index: 'foo', type: 'bar', id: '1', qwerty: 'yuiop') }.to raise_exception(ArgumentError) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices/000077500000000000000000000000001462737751600324145ustar00rootroot00000000000000add_block_spec.rb000066400000000000000000000033201462737751600355740ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#add_block' do let(:expected_args) do [ 'PUT', url, {}, nil, {} ] end let(:url) { "#{index}/_block/#{block}"} let(:index) { 'test_index' } let(:block) { 'test_block' } it 'performs the request' do expect( client_double.indices.add_block(index: index, block: block) ).to eq({}) end context 'when an index is not specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an argument error' do expect do client.indices.add_block(block: block) end.to raise_exception(ArgumentError) end end context 'when a block is not specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an argument error' do expect do client.indices.add_block(index: index) end.to raise_exception(ArgumentError) end end end analyze_spec.rb000066400000000000000000000030611462737751600353370ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#analyze' do let(:expected_args) do [ method, url, params, body, {} ] end let(:method) { 'GET' } let(:body) do nil end let(:url) do '_analyze' end let(:params) do {} end it 'performs the request' do expect(client_double.indices.analyze).to eq({}) end context 'when an index is specified' do let(:url) do 'foo/_analyze' end it 'performs the request' do expect(client_double.indices.analyze(index: 'foo')).to eq({}) end end context 'when a body is specified' do let(:body) do 'foo' end let(:method) { 'POST' } it 'performs the request' do expect(client_double.indices.analyze(body: 'foo')).to eq({}) end end end clear_cache_spec.rb000066400000000000000000000034441462737751600361120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#clear_cache' do let(:expected_args) do [ 'POST', url, params, nil, {} ] end let(:url) do '_cache/clear' end let(:params) do {} end it 'performs the request' do expect(client_double.indices.clear_cache).to eq({}) end context 'when an index is specified' do let(:url) do 'foo/_cache/clear' end it 'performs the request' do expect(client_double.indices.clear_cache(index: 'foo')).to eq({}) end end context 'when params are specified' do let(:params) do { fielddata: true } end it 'performs the request' do expect(client_double.indices.clear_cache(fielddata: true)).to eq({}) end end context 'when the path must be URL-escaped' do let(:url) do 'foo%5Ebar/_cache/clear' end let(:params) do { } end it 'performs the request' do expect(client_double.indices.clear_cache(index: 'foo^bar')).to eq({}) end end end clone_spec.rb000066400000000000000000000063511462737751600350010ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#clone' do let(:expected_args) do [ 'PUT', url, params, body, {} ] end let(:params) do {} end let(:body) do nil end let(:url) do 'my_source_index/_clone/my_target_index' end context 'when there is no index specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect { client.indices.clone(target: 'my_target_index') }.to raise_exception(ArgumentError) end end context 'when there is no index specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect { client.indices.clone(index: 'my_source_index') }.to raise_exception(ArgumentError) end end context 'when an index and target are specified' do it 'performs the request' do expect(client_double.indices.clone(index: 'my_source_index', target: 'my_target_index')).to eq({}) end end context 'when params are provided' do let(:params) do { timeout: '1s', master_timeout: '10s', wait_for_active_shards: 1 } end it 'performs the request' do expect(client_double.indices.clone(index: 'my_source_index', target: 'my_target_index', timeout: '1s', master_timeout: '10s', wait_for_active_shards: 1)).to eq({}) end end context 'when a body is specified' do let(:body) do { settings: { 'index.number_of_shards' => 5 }, aliases: { my_search_indices: {} } } end it 'performs the request' do expect(client_double.indices.clone(index: 'my_source_index', target: 'my_target_index', body: { settings: { 'index.number_of_shards' => 5 }, aliases: { my_search_indices: {} } })).to eq({}) end end end close_spec.rb000066400000000000000000000036171462737751600350100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#close' do let(:expected_args) do [ 'POST', url, params, nil, {} ] end let(:params) do {} end context 'when there is no index specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect { client.indices.close }.to raise_exception(ArgumentError) end end context 'when an index is specified' do let(:url) do 'foo/_close' end it 'performs the request' do expect(client_double.indices.close(index: 'foo')).to eq({}) end end context 'when params are specified' do let(:params) do { timeout: '1s' } end let(:url) do 'foo/_close' end it 'performs the request' do expect(client_double.indices.close(index: 'foo', timeout: '1s')).to eq({}) end end context 'when the path must be URL-escaped' do let(:url) do 'foo%5Ebar/_close' end it 'performs the request' do expect(client_double.indices.close(index: 'foo^bar')).to eq({}) end end end create_spec.rb000066400000000000000000000035761462737751600351520ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#create' do let(:expected_args) do [ 'PUT', url, params, nil, {} ] end let(:params) do {} end context 'when there is no index specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect { client.indices.create }.to raise_exception(ArgumentError) end end context 'when an index is specified' do let(:url) do 'foo' end it 'performs the request' do expect(client_double.indices.create(index: 'foo')).to eq({}) end end context 'when params are specified' do let(:params) do { timeout: '1s' } end let(:url) do 'foo' end it 'performs the request' do expect(client_double.indices.create(index: 'foo', timeout: '1s')).to eq({}) end end context 'when the path must be URL-escaped' do let(:url) do 'foo%5Ebar' end it 'performs the request' do expect(client_double.indices.create(index: 'foo^bar')).to eq({}) end end end delete_alias_spec.rb000066400000000000000000000040011462737751600363020ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#delete_alias' do let(:expected_args) do [ 'DELETE', url, params, nil, {} ] end let(:params) do {} end context 'when there is no index specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect { client.indices.delete_alias(name: 'foo') }.to raise_exception(ArgumentError) end end context 'when there is no name specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect { client.indices.delete_alias(index: 'foo') }.to raise_exception(ArgumentError) end end context 'when an index and name are specified' do let(:url) do 'foo/_aliases/bar' end it 'performs the request' do expect(client_double.indices.delete_alias(index: 'foo', name: 'bar')).to eq({}) end end context 'when the path must be URL-escaped' do let(:url) do 'foo%5Ebar/_aliases/bar%2Fbam' end it 'performs the request' do expect(client_double.indices.delete_alias(index: 'foo^bar', name: 'bar/bam')).to eq({}) end end end delete_spec.rb000066400000000000000000000047171462737751600351470ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#delete' do let(:expected_args) do [ 'DELETE', url, params, nil, {} ] end let(:params) do {} end let(:url) do 'foo' end it 'performs the request' do expect(client_double.indices.delete(index: 'foo')).to eq({}) end context 'when more than one index is specified' do let(:url) do 'foo,bar' end it 'performs the request' do expect(client_double.indices.delete(index: ['foo', 'bar'])).to eq({}) end end context 'when params are specified' do let(:params) do { timeout: '1s' } end it 'performs the request' do expect(client_double.indices.delete(index: 'foo', timeout: '1s')).to eq({}) end end context 'when the path must be URL-escaped' do let(:url) do 'foo%5Ebar' end it 'performs the request' do expect(client_double.indices.delete(index: 'foo^bar')).to eq({}) end end context 'when a NotFound exception is raised by the request' do let(:client) do Class.new { include Elasticsearch::API }.new end before do expect(client).to receive(:perform_request).and_raise(NotFound) end it 'raises the exception' do expect { client.indices.delete(index: 'foo') }.to raise_exception(NotFound) end end context 'when the ignore parameter is specified' do let(:client) do Class.new { include Elasticsearch::API }.new end before do expect(client).to receive(:perform_request).and_raise(NotFound) end it 'ignores the code' do expect(client.indices.delete(index: 'foo', ignore: 404)).to eq(false) end end end delete_template_spec.rb000066400000000000000000000041231462737751600370310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#delete_template' do let(:expected_args) do [ 'DELETE', url, params, nil, {} ] end let(:params) do {} end let(:url) do '_template/foo' end it 'performs the request' do expect(client_double.indices.delete_template(name: 'foo')).to eq({}) end context 'when the path needs to be URL-escaped' do let(:url) do '_template/foo%5Ebar' end it 'performs the request' do expect(client_double.indices.delete_template(name: 'foo^bar')).to eq({}) end end context 'when a NotFound exception is raised by the request' do let(:client) do Class.new { include Elasticsearch::API }.new end before do expect(client).to receive(:perform_request).and_raise(NotFound) end it 'raises the exception' do expect { client.indices.delete_template(name: 'foo') }.to raise_exception(NotFound) end end context 'when the ignore parameter is specified' do let(:client) do Class.new { include Elasticsearch::API }.new end before do expect(client).to receive(:perform_request).and_raise(NotFound) end it 'ignores the code' do expect(client.indices.delete_template(name: 'foo', ignore: 404)).to eq(false) end end end disk_usage_spec.rb000066400000000000000000000025211462737751600360120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#disk_usage' do let(:expected_args) do [ 'POST', "#{index}/_disk_usage", {}, nil, {} ] end let(:index) { 'foo' } it 'performs the request' do expect(client_double.indices.disk_usage(index: index)).to eq({}) end context 'when there is no index specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect do client.indices.disk_usage end.to raise_exception(ArgumentError) end end end exists_alias_spec.rb000066400000000000000000000054241462737751600363710ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#exists_alias' do let(:expected_args) do [ 'HEAD', url, params, nil, {} ] end let(:params) do {} end let(:url) do '_alias/foo' end it 'performs the request' do expect(client_double.indices.exists_alias(name: 'foo')).to eq(true) end it 'aliased to a predicate method' do expect(client_double.indices.exists_alias?(name: 'foo')).to eq(true) end context 'when multiple indices are specified' do let(:url) do 'foo,bar/_alias/bam' end it 'performs the request' do expect(client_double.indices.exists_alias(index: ['foo','bar'], name: 'bam')).to eq(true) end end context 'when the path needs to be URL-escaped' do let(:url) do 'foo%5Ebar/_alias/bar%2Fbam' end it 'performs the request' do expect(client_double.indices.exists_alias(index: 'foo^bar', name: 'bar/bam')).to eq(true) end end context 'when 404 response is received' do let(:response_double) do double('response', status: 404, body: {}, headers: {}) end it 'returns false' do expect(client_double.indices.exists_alias(name: 'foo')).to eq(false) end end context 'when a \'not found\' exception is raised' do let(:client) do Class.new { include Elasticsearch::API }.new.tap do |_client| expect(_client).to receive(:perform_request).with(*expected_args).and_raise(StandardError.new('404 Not Found')) end end it 'returns false' do expect(client.indices.exists_alias(name: 'foo')).to eq(false) end end context 'when a generic exception is raised' do let(:client) do Class.new { include Elasticsearch::API }.new.tap do |_client| expect(_client).to receive(:perform_request).with(*expected_args).and_raise(StandardError.new) end end it 'raises the exception' do expect { client.indices.exists_alias(name: 'foo') }.to raise_exception(StandardError) end end end exists_spec.rb000066400000000000000000000052501462737751600352150ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#exists' do let(:expected_args) do [ 'HEAD', url, params, nil, {} ] end let(:params) do {} end let(:url) do 'foo' end it 'performs the request' do expect(client_double.indices.exists(index: 'foo')).to eq(true) end it 'aliased to a predicate method' do expect(client_double.indices.exists?(index: 'foo')).to eq(true) end context 'when multiple indices are specified' do let(:url) do 'foo,bar' end it 'performs the request' do expect(client_double.indices.exists(index: ['foo','bar'])).to eq(true) end end context 'when the path needs to be URL-escaped' do let(:url) do 'foo%5Ebar' end it 'performs the request' do expect(client_double.indices.exists(index: 'foo^bar')).to eq(true) end end context 'when 404 response is received' do let(:response_double) do double('response', status: 404, body: {}, headers: {}) end it 'returns false' do expect(client_double.indices.exists(index: 'foo')).to eq(false) end end context 'when a \'not found\' exception is raised' do let(:client) do Class.new { include Elasticsearch::API }.new.tap do |_client| expect(_client).to receive(:perform_request).with(*expected_args).and_raise(StandardError.new('404 Not Found')) end end it 'returns false' do expect(client.indices.exists(index: 'foo')).to eq(false) end end context 'when a generic exception is raised' do let(:client) do Class.new { include Elasticsearch::API }.new.tap do |_client| expect(_client).to receive(:perform_request).with(*expected_args).and_raise(StandardError.new) end end it 'raises the exception' do expect { client.indices.exists(index: 'foo') }.to raise_exception(StandardError) end end end exists_template_spec.rb000066400000000000000000000046371462737751600371200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#exists_template' do let(:expected_args) do [ 'HEAD', url, params, nil, {} ] end let(:params) do {} end let(:url) do '_template/foo' end it 'performs the request' do expect(client_double.indices.exists_template(name: 'foo')).to eq(true) end context 'when the path needs to be URL-escaped' do let(:url) do '_template/bar%2Fbam' end it 'performs the request' do expect(client_double.indices.exists_template(name: 'bar/bam')).to eq(true) end end context 'when 404 response is received' do let(:response_double) do double('response', status: 404, body: {}, headers: {}) end it 'returns false' do expect(client_double.indices.exists_template(name: 'foo')).to eq(false) end end context 'when a \'not found\' exception is raised' do let(:client) do Class.new { include Elasticsearch::API }.new.tap do |_client| expect(_client).to receive(:perform_request).with(*expected_args).and_raise(StandardError.new('404 Not Found')) end end it 'returns false' do expect(client.indices.exists_template(name: 'foo')).to eq(false) end end context 'when a generic exception is raised' do let(:client) do Class.new { include Elasticsearch::API }.new.tap do |_client| expect(_client).to receive(:perform_request).with(*expected_args).and_raise(StandardError.new) end end it 'raises the exception' do expect { client.indices.exists_template(name: 'foo') }.to raise_exception(StandardError) end end end exists_type_spec.rb000066400000000000000000000055341462737751600362630ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#exists_type' do let(:expected_args) do [ 'HEAD', url, params, nil, {} ] end let(:params) do {} end let(:url) do 'foo/_mapping/bar' end it 'performs the request' do expect(client_double.indices.exists_type(index: 'foo', type: 'bar')).to eq(true) end it 'aliased to a predicate method' do expect(client_double.indices.exists_type?(index: 'foo', type: 'bar')).to eq(true) end context 'when multiple indices are specified' do let(:url) do 'foo,bar/_mapping/bam' end it 'performs the request' do expect(client_double.indices.exists_type(index: ['foo','bar'], type: 'bam')).to eq(true) end end context 'when the path needs to be URL-escaped' do let(:url) do 'foo%5Ebar/_mapping/bar%2Fbam' end it 'performs the request' do expect(client_double.indices.exists_type(index: 'foo^bar', type: 'bar/bam')).to eq(true) end end context 'when 404 response is received' do let(:response_double) do double('response', status: 404, body: {}, headers: {}) end it 'returns false' do expect(client_double.indices.exists_type(index: 'foo', type: 'bar')).to eq(false) end end context 'when a \'not found\' exception is raised' do let(:client) do Class.new { include Elasticsearch::API }.new.tap do |_client| expect(_client).to receive(:perform_request).with(*expected_args).and_raise(StandardError.new('404 Not Found')) end end it 'returns false' do expect(client.indices.exists_type(index: 'foo', type: 'bar')).to eq(false) end end context 'when a generic exception is raised' do let(:client) do Class.new { include Elasticsearch::API }.new.tap do |_client| expect(_client).to receive(:perform_request).with(*expected_args).and_raise(StandardError.new) end end it 'raises the exception' do expect { client.indices.exists_type(index: 'foo', type: 'bar') }.to raise_exception(StandardError) end end end field_usage_stats_spec.rb000066400000000000000000000025131462737751600373620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#field_usage_stats' do let(:expected_args) do [ 'GET', 'foo/_field_usage_stats', {}, nil, {} ] end it 'performs the request' do expect(client_double.indices.field_usage_stats(index: 'foo')).to eq({}) end context 'when there is no index specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect { client.indices.field_usage_stats }.to raise_exception(ArgumentError) end end end flush_spec.rb000066400000000000000000000040051462737751600350140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#flush' do let(:expected_args) do [ 'POST', url, params, nil, {} ] end let(:params) do {} end let(:url) do '_flush' end it 'performs the request' do expect(client_double.indices.flush).to eq({}) end context 'when an index is specified' do let(:url) do 'foo/_flush' end it 'performs the request' do expect(client_double.indices.flush(index: 'foo')).to eq({}) end end context 'when multiple indices are specified' do let(:url) do 'foo,bar/_flush' end it 'performs the request' do expect(client_double.indices.flush(index: ['foo','bar'])).to eq({}) end end context 'when the path needs to be URL-escaped' do let(:url) do 'foo%5Ebar/_flush' end it 'performs the request' do expect(client_double.indices.flush(index: 'foo^bar')).to eq({}) end end context 'when URL parameters are specified' do let(:url) do 'foo/_flush' end let(:params) do { ignore_unavailable: true } end it 'performs the request' do expect(client_double.indices.flush(index: 'foo', ignore_unavailable: true)).to eq({}) end end end flush_synced_spec.rb000066400000000000000000000046001462737751600363620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#flush_synced' do let(:expected_args) do [ 'POST', url, params, nil, {} ] end let(:params) do {} end let(:url) do 'foo/_flush/synced' end it 'performs the request' do expect(client_double.indices.flush_synced(index: 'foo')).to eq({}) end context 'when a \'not found\' exception is raised' do let(:client) do Class.new { include Elasticsearch::API }.new.tap do |_client| expect(_client).to receive(:perform_request).with(*expected_args).and_raise(NotFound) end end it 'raises the exception' do expect { client.indices.flush_synced(index: 'foo') }.to raise_exception(NotFound) end end context 'when a \'not found\' exception is raised' do let(:client) do Class.new { include Elasticsearch::API }.new.tap do |_client| expect(_client).to receive(:perform_request).with(*expected_args).and_raise(NotFound) end end it 'raises the exception' do expect { client.indices.flush_synced(index: 'foo') }.to raise_exception(NotFound) end end context 'when the ignore parameter is specified' do let(:client) do Class.new { include Elasticsearch::API }.new.tap do |_client| expect(_client).to receive(:perform_request).with(*expected_args).and_raise(StandardError.new('404 Not Found')) end end let(:params) do { ignore: 404 } end it 'does not raise the exception' do expect(client.indices.flush_synced(index: 'foo', ignore: 404)).to eq(false) end end end forcemerge_spec.rb000066400000000000000000000020371462737751600360140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#forcemerge' do let(:expected_args) do [ 'POST', '_forcemerge', {}, nil, {} ] end it 'performs the request' do expect(client_double.indices.forcemerge).to eq({}) end end get_alias_spec.rb000066400000000000000000000030701462737751600356240ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#get_alias' do let(:expected_args) do [ 'GET', url, {}, nil, {} ] end let(:url) do '_alias/foo' end it 'performs the request' do expect(client_double.indices.get_alias(name: 'foo')).to eq({}) end context 'when multiple indices are specified' do let(:url) do 'foo,bar/_alias/bam' end it 'performs the request' do expect(client_double.indices.get_alias(index: ['foo','bar'], name: 'bam')).to eq({}) end end context 'when the path needs to be URL-escaped' do let(:url) do 'foo%5Ebar/_alias/bar%2Fbam' end it 'performs the request' do expect(client_double.indices.get_alias(index: 'foo^bar', name: 'bar/bam')).to eq({}) end end end get_field_mapping_spec.rb000066400000000000000000000031161462737751600373320ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#get_field_mapping' do let(:expected_args) do [ 'GET', url, {}, nil, {} ] end let(:url) do '_mapping/field/foo' end it 'performs the request' do expect(client_double.indices.get_field_mapping(field: 'foo')).to eq({}) end context 'when an index is specified' do let(:url) do 'foo/_mapping/field/bam' end it 'performs the request' do expect(client_double.indices.get_field_mapping(index: 'foo', field: 'bam')).to eq({}) end end context 'when a type is specified' do let(:url) do 'foo/_mapping/bar/field/bam' end it 'performs the request' do expect(client_double.indices.get_field_mapping(index: 'foo', type: 'bar', field: 'bam')).to eq({}) end end end get_mapping_spec.rb000066400000000000000000000040101462737751600361610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#get_mapping' do let(:expected_args) do [ 'GET', url, {}, nil, {} ] end let(:url) do '_mapping' end it 'performs the request' do expect(client_double.indices.get_mapping).to eq({}) end context 'when an index is specified' do let(:url) do 'foo/_mapping' end it 'performs the request' do expect(client_double.indices.get_mapping(index: 'foo')).to eq({}) end end context 'when an index and type are specified' do let(:url) do 'foo/_mapping/bar' end it 'performs the request' do expect(client_double.indices.get_mapping(index: 'foo', type: 'bar')).to eq({}) end end context 'when multiple indices and types are specified' do let(:url) do 'foo,bar/_mapping/bam,baz' end it 'performs the request' do expect(client_double.indices.get_mapping(index: ['foo', 'bar'], type: ['bam', 'baz'])).to eq({}) end end context 'when the path must be URL-escaped' do let(:url) do 'foo%5Ebar/_mapping/bar%2Fbam' end it 'performs the request' do expect(client_double.indices.get_mapping(index: 'foo^bar', type: 'bar/bam')).to eq({}) end end end get_settings_spec.rb000066400000000000000000000033421462737751600363750ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#get_settings' do let(:expected_args) do [ 'GET', url, {}, nil, {} ] end let(:url) do '_settings' end it 'performs the request' do expect(client_double.indices.get_settings).to eq({}) end context 'when an index is specified' do let(:url) do 'foo/_settings' end it 'performs the request' do expect(client_double.indices.get_settings(index: 'foo')).to eq({}) end end context 'when a name is specified' do let(:url) do 'foo/_settings/foo.bar' end it 'performs the request' do expect(client_double.indices.get_settings(index: 'foo', name: 'foo.bar')).to eq({}) end end context 'when the path must be URL-escaped' do let(:url) do 'foo%5Ebar/_settings' end it 'performs the request' do expect(client_double.indices.get_settings(index: 'foo^bar')).to eq({}) end end end get_spec.rb000066400000000000000000000025121462737751600344530ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#get' do let(:expected_args) do [ 'GET', url, params, nil, {} ] end let(:params) do {} end let(:url) do 'foo' end it 'performs the request' do expect(client_double.indices.get(index: 'foo')).to eq({}) end context 'when parameters are specified' do let(:params) do { ignore_unavailable: 1 } end it 'performs the request' do expect(client_double.indices.get(index: 'foo', ignore_unavailable: 1)).to eq({}) end end end open_spec.rb000066400000000000000000000030351462737751600346360ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#open' do let(:expected_args) do [ 'POST', url, params, nil, {} ] end let(:params) do {} end let(:url) do 'foo/_open' end it 'performs the request' do expect(client_double.indices.open(index: 'foo')).to eq({}) end context 'when parameters are specified' do let(:params) do { timeout: '1s' } end it 'performs the request' do expect(client_double.indices.open(index: 'foo', timeout: '1s')).to eq({}) end end context 'when the path must be URL-escaped' do let(:url) do 'foo%5Ebar/_open' end it 'performs the request' do expect(client_double.indices.open(index: 'foo^bar')).to eq({}) end end end put_alias_spec.rb000066400000000000000000000041761462737751600356650ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#put_alias' do let(:expected_args) do [ 'PUT', url, {}, body, {} ] end let(:url) do 'foo/_aliases/bar' end let(:body) do nil end it 'performs the request' do expect(client_double.indices.put_alias(index: 'foo', name: 'bar')).to eq({}) end context 'when there is no name specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect { client.indices.put_alias(name: 'foo') }.to raise_exception(ArgumentError) end end context 'when a body is specified' do let(:body) do { filter: 'foo' } end it 'performs the request' do expect(client_double.indices.put_alias(index: 'foo', name: 'bar', body: { filter: 'foo' })).to eq({}) end end context 'when multiple indices are specified' do let(:url) do 'foo,bar/_aliases/bam' end it 'performs the request' do expect(client_double.indices.put_alias(index: ['foo','bar'], name: 'bam')).to eq({}) end end context 'when the path needs to be URL-escaped' do let(:url) do 'foo%5Ebar/_aliases/bar%2Fbam' end it 'performs the request' do expect(client_double.indices.put_alias(index: 'foo^bar', name: 'bar/bam')).to eq({}) end end end put_mapping_spec.rb000066400000000000000000000047201462737751600362220ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#put_mapping' do let(:expected_args) do [ 'PUT', url, {}, body, {} ] end let(:url) do 'foo/bar/_mappings' end let(:body) do {} end it 'performs the request' do expect(client_double.indices.put_mapping(index: 'foo', type: 'bar', body: {})).to eq({}) end context 'when there is no type specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect { client.indices.put_mapping(type: 'foo') }.to raise_exception(ArgumentError) end end context 'when there is no body specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect { client.indices.put_mapping(index: 'foo', type: 'bar') }.to raise_exception(ArgumentError) end end context 'when a body is specified' do let(:body) do { filter: 'foo' } end it 'performs the request' do expect(client_double.indices.put_mapping(index: 'foo', type: 'bar', body: { filter: 'foo' })).to eq({}) end end context 'when multiple indices are specified' do let(:url) do 'foo,bar/bam/_mappings' end it 'performs the request' do expect(client_double.indices.put_mapping(index: ['foo','bar'], type: 'bam', body: {})).to eq({}) end end context 'when the path needs to be URL-escaped' do let(:url) do 'foo%5Ebar/bar%2Fbam/_mappings' end it 'performs the request' do expect(client_double.indices.put_mapping(index: 'foo^bar', type: 'bar/bam', body: {})).to eq({}) end end end put_settings_spec.rb000066400000000000000000000046141462737751600364310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#put_settings' do let(:expected_args) do [ 'PUT', url, params, body, {} ] end let(:url) do '_settings' end let(:body) do {} end let(:params) do {} end it 'performs the request' do expect(client_double.indices.put_settings(body: {})).to eq({}) end context 'when there is no body specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect { client.indices.put_settings }.to raise_exception(ArgumentError) end end context 'when parameters are specified' do let(:params) do { flat_settings: true } end let(:url) do 'foo/_settings' end it 'performs the request' do expect(client_double.indices.put_settings(index: 'foo', flat_settings: true, body: {})).to eq({}) end end context 'when an index is specified' do let(:url) do 'foo/_settings' end it 'performs the request' do expect(client_double.indices.put_settings(index: 'foo', body: {})).to eq({}) end end context 'when multiple indices are specified' do let(:url) do 'foo,bar/_settings' end it 'performs the request' do expect(client_double.indices.put_settings(index: ['foo','bar'], body: {})).to eq({}) end end context 'when the path needs to be URL-escaped' do let(:url) do 'foo%5Ebar/_settings' end it 'performs the request' do expect(client_double.indices.put_settings(index: 'foo^bar', body: {})).to eq({}) end end end put_template_spec.rb000066400000000000000000000045011462737751600363770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#put_template' do let(:expected_args) do [ 'PUT', url, params, body, {} ] end let(:url) do '_template/foo' end let(:body) do { template: 'bar' } end let(:params) do {} end it 'performs the request' do expect(client_double.indices.put_template(name: 'foo', body: { template: 'bar' })).to eq({}) end context 'when there is no name specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect { client.indices.put_template(body: {}) }.to raise_exception(ArgumentError) end end context 'when there is no body specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect { client.indices.put_template(name: 'foo') }.to raise_exception(ArgumentError) end end context 'when parameters are specified' do let(:params) do { order: 3 } end let(:url) do '_template/foo' end let(:body) do {} end it 'performs the request' do expect(client_double.indices.put_template(name: 'foo', order: 3, body: {})).to eq({}) end end context 'when the path needs to be URL-escaped' do let(:url) do '_template/foo%5Ebar' end let(:body) do {} end it 'performs the request' do expect(client_double.indices.put_template(name: 'foo^bar', body: {})).to eq({}) end end end recovery_spec.rb000066400000000000000000000020521462737751600355310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#recovery' do let(:expected_args) do [ 'GET', 'foo/_recovery', {}, nil, {} ] end it 'performs the request' do expect(client_double.indices.recovery(index: 'foo')).to eq({}) end end refresh_spec.rb000066400000000000000000000040041462737751600353300ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#refresh' do let(:expected_args) do [ 'POST', url, params, body, {} ] end let(:url) do '_refresh' end let(:body) do nil end let(:params) do {} end it 'performs the request' do expect(client_double.indices.refresh).to eq({}) end context 'when an index is specified' do let(:url) do 'foo/_refresh' end it 'performs the request' do expect(client_double.indices.refresh(index: 'foo')).to eq({}) end end context 'when multiple indicies are specified as a list' do let(:url) do 'foo,bar/_refresh' end it 'performs the request' do expect(client_double.indices.refresh(index: ['foo', 'bar'])).to eq({}) end end context 'when multiple indicies are specified as a string' do let(:url) do 'foo,bar/_refresh' end it 'performs the request' do expect(client_double.indices.refresh(index: 'foo,bar')).to eq({}) end end context 'when the path needs to be URL-escaped' do let(:url) do 'foo%5Ebar/_refresh' end it 'performs the request' do expect(client_double.indices.refresh(index: 'foo^bar')).to eq({}) end end end rollover_spec.rb000066400000000000000000000025631462737751600355460ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#rollover' do let(:expected_args) do [ 'POST', url, params, body, {} ] end let(:url) do 'foo/_rollover' end let(:body) do nil end let(:params) do {} end it 'performs the request' do expect(client_double.indices.rollover(alias: 'foo')).to eq({}) end context 'when an index is specified' do let(:url) do 'foo/_rollover/bar' end it 'performs the request' do expect(client_double.indices.rollover(alias: 'foo', new_index: 'bar')).to eq({}) end end end segments_spec.rb000066400000000000000000000040161462737751600355220ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#segments' do let(:expected_args) do [ 'GET', url, params, body, {} ] end let(:url) do '_segments' end let(:body) do nil end let(:params) do {} end it 'performs the request' do expect(client_double.indices.segments).to eq({}) end context 'when an index is specified' do let(:url) do 'foo/_segments' end it 'performs the request' do expect(client_double.indices.segments(index: 'foo')).to eq({}) end end context 'when multiple indicies are specified as a list' do let(:url) do 'foo,bar/_segments' end it 'performs the request' do expect(client_double.indices.segments(index: ['foo', 'bar'])).to eq({}) end end context 'when multiple indicies are specified as a string' do let(:url) do 'foo,bar/_segments' end it 'performs the request' do expect(client_double.indices.segments(index: 'foo,bar')).to eq({}) end end context 'when the path needs to be URL-escaped' do let(:url) do 'foo%5Ebar/_segments' end it 'performs the request' do expect(client_double.indices.segments(index: 'foo^bar')).to eq({}) end end end shard_stores_spec.rb000066400000000000000000000020441462737751600363740ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#shard_stores' do let(:expected_args) do [ 'GET', '_shard_stores', {}, nil, {} ] end it 'performs the request' do expect(client_double.indices.shard_stores).to eq({}) end end shrink_spec.rb000066400000000000000000000024311462737751600351720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#shrink' do let(:expected_args) do [ 'PUT', 'foo/_shrink/bar', {}, nil, {} ] end it 'performs the request' do expect(client_double.indices.shrink(index: 'foo', target: 'bar')).to eq({}) end it 'does not mutate the arguments' do arguments = { index: 'foo', target: 'bar' } client_double.indices.shrink(arguments) expect(arguments[:index]).to eq('foo') expect(arguments[:target]).to eq('bar') end end split_spec.rb000066400000000000000000000020641462737751600350310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#split' do let(:expected_args) do [ 'PUT', 'foo/_split/bar', {}, nil, {} ] end it 'performs the request' do expect(client_double.indices.split(index: 'foo', target: 'bar')).to eq({}) end end stats_spec.rb000066400000000000000000000052761462737751600350440ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#stats' do let(:expected_args) do [ 'GET', url, params, body, {} ] end let(:url) do '_stats' end let(:body) do nil end let(:params) do {} end it 'performs the request' do expect(client_double.indices.stats).to eq({}) end context 'when an index is specified' do let(:url) do 'foo/_stats' end it 'performs the request' do expect(client_double.indices.stats(index: 'foo')).to eq({}) end end context 'when multiple indicies are specified as a list' do let(:url) do 'foo,bar/_stats' end it 'performs the request' do expect(client_double.indices.stats(index: ['foo', 'bar'])).to eq({}) end end context 'when multiple indicies are specified as a string' do let(:url) do 'foo,bar/_stats' end it 'performs the request' do expect(client_double.indices.stats(index: 'foo,bar')).to eq({}) end end context 'when parameters are specified' do let(:params) do { expand_wildcards: true } end let(:url) do 'foo/_stats' end it 'performs the request' do expect(client_double.indices.stats(index: 'foo', expand_wildcards: true)).to eq({}) end end context 'when the fields parameter is specified as a list' do let(:params) do { fields: 'foo,bar' } end let(:url) do 'foo/_stats/fielddata' end it 'performs the request' do expect(client_double.indices.stats(index: 'foo', fielddata: true, fields: [ 'foo', 'bar'])).to eq({}) end end context 'when the groups parameter is specified as a list' do let(:params) do { groups: 'groupA,groupB' } end let(:url) do '_stats/search' end it 'performs the request' do expect(client_double.indices.stats(search: true, groups: [ 'groupA', 'groupB'])).to eq({}) end end end update_aliases_spec.rb000066400000000000000000000032141462737751600366570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#update_aliases' do let(:expected_args) do [ 'POST', '_aliases', params, body, {} ] end let(:body) do { actions: [] } end let(:params) do {} end it 'performs the request' do expect(client_double.indices.update_aliases(body: { actions: [] })).to eq({}) end context 'when a body is not specified' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an exception' do expect { client.indices.update_aliases }.to raise_exception(ArgumentError) end end context 'when parameters are specified' do let(:params) do { timeout: '1s' } end it 'performs the request' do expect(client_double.indices.update_aliases(timeout: '1s', body: { actions: [] })).to eq({}) end end end upgrade_spec.rb000066400000000000000000000020261462737751600353230ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#upgrade' do let(:expected_args) do [ 'POST', '_upgrade', {}, nil, {} ] end it 'performs the request' do expect(client_double.indices.upgrade).to eq({}) end end validate_query_spec.rb000066400000000000000000000055571462737751600367260ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.cluster#validate_query' do let(:expected_args) do [ method, url, params, body, {} ] end let(:method) { 'GET' } let(:url) do '_validate/query' end let(:body) do nil end let(:params) do {} end it 'performs the request' do expect(client_double.indices.validate_query).to eq({}) end context 'when an index is specified' do let(:url) do 'foo/_validate/query' end it 'performs the request' do expect(client_double.indices.validate_query(index: 'foo')).to eq({}) end end context 'when a type and index are specified' do let(:url) do 'foo/bar/_validate/query' end it 'performs the request' do expect(client_double.indices.validate_query(index: 'foo', type: 'bar')).to eq({}) end end context 'when multiple indicies are specified as a list' do let(:url) do 'foo,bar/_validate/query' end it 'performs the request' do expect(client_double.indices.validate_query(index: ['foo', 'bar'])).to eq({}) end end context 'when multiple indicies are specified as a string' do let(:url) do 'foo,bar/_validate/query' end it 'performs the request' do expect(client_double.indices.validate_query(index: 'foo,bar')).to eq({}) end end context 'when parameters are specified' do let(:params) do { explain: true, q: 'foo' } end let(:url) do '_validate/query' end it 'performs the request' do expect(client_double.indices.validate_query(explain: true, q: 'foo')).to eq({}) end end context 'when a body is specified' do let(:body) do { filtered: {} } end let(:method) { 'POST' } it 'performs the request' do expect(client_double.indices.validate_query(body: { filtered: {} })).to eq({}) end end context 'when the path needs to be URL-escaped' do let(:url) do 'foo%5Ebar/_validate/query' end it 'performs the request' do expect(client_double.indices.validate_query(index: 'foo^bar')).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/info_spec.rb000066400000000000000000000017701462737751600332750ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#info' do let(:expected_args) do [ 'GET', '', { }, nil, {} ] end it 'performs the request' do expect(client_double.info).to eq({}) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/ingest/000077500000000000000000000000001462737751600322675ustar00rootroot00000000000000delete_pipeline_spec.rb000066400000000000000000000030241462737751600366750ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/ingest# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.ingest#delete_pipeline' do let(:expected_args) do [ 'DELETE', url, {}, nil, {} ] end let(:url) do '_ingest/pipeline/foo' end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :id argument' do expect { client.ingest.delete_pipeline }.to raise_exception(ArgumentError) end it 'performs the request' do expect(client_double.ingest.delete_pipeline(id: 'foo')).to eq({}) end context 'when the path must be URL-escaped' do let(:url) do '_ingest/pipeline/foo%5Ebar' end it 'performs the request' do expect(client_double.ingest.delete_pipeline(id: 'foo^bar')).to eq({}) end end end geo_ip_stats_spec.rb000066400000000000000000000020351462737751600362270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/ingest# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.ingest#geo_ip_stats' do let(:expected_args) do [ 'GET', '_ingest/geoip/stats', {}, nil, {} ] end it 'performs the request' do expect(client_double.ingest.geo_ip_stats).to eq({}) end end get_pipeline_spec.rb000066400000000000000000000024721462737751600362200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/ingest# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.ingest#get_pipeline' do let(:expected_args) do [ 'GET', url, {}, nil, {} ] end let(:url) do '_ingest/pipeline/foo' end it 'performs the request' do expect(client_double.ingest.get_pipeline(id: 'foo')).to eq({}) end context 'when the path must be URL-escaped' do let(:url) do '_ingest/pipeline/foo%5Ebar' end it 'performs the request' do expect(client_double.ingest.get_pipeline(id: 'foo^bar')).to eq({}) end end end put_pipeline_spec.rb000066400000000000000000000030301462737751600362400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/ingest# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.ingest#put_pipeline' do let(:expected_args) do [ 'PUT', url, {}, {}, {} ] end let(:url) do '_ingest/pipeline/foo' end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :id argument' do expect { client.ingest.put_pipeline }.to raise_exception(ArgumentError) end it 'performs the request' do expect(client_double.ingest.put_pipeline(id: 'foo', body: {})).to eq({}) end context 'when the path must be URL-escaped' do let(:url) do '_ingest/pipeline/foo%5Ebar' end it 'performs the request' do expect(client_double.ingest.put_pipeline(id: 'foo^bar', body: {})).to eq({}) end end end simulate_spec.rb000066400000000000000000000025101462737751600353700ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/ingest# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.ingest#simulate' do let(:expected_args) do [ method, url, {}, {}, {} ] end let(:method) { 'POST' } let(:url) do '_ingest/pipeline/_simulate' end it 'performs the request' do expect(client_double.ingest.simulate(body: {})).to eq({}) end context 'when a pipeline id is provided' do let(:url) do '_ingest/pipeline/foo/_simulate' end it 'performs the request' do expect(client_double.ingest.simulate(id: 'foo', body: {})).to eq({}) end end end json_builders_spec.rb000066400000000000000000000035021462737751600351200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'JSON builders' do context 'JBuilder' do let(:expected_args) do [ 'POST', '_search', {}, body, {} ] end let(:json) do Jbuilder.encode do |json| json.query do json.match do json.title do json.query 'test' end end end end end let(:body) do json end it 'properly builds the json' do expect(client_double.search(body: json)).to eq({}) end end context 'Jsonify' do let(:expected_args) do [ 'POST', '_search', {}, body, {} ] end let(:json) do Jsonify::Builder.compile do |json| json.query do json.match do json.title do json.query 'test' end end end end end let(:body) do json end it 'properly builds the json' do expect(client_double.search(body: json)).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/mget_spec.rb000066400000000000000000000042651462737751600333000ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#mget' do let(:expected_args) do [ 'POST', url, params, body, {} ] end let(:body) do { docs: [] } end let(:url) do '_mget' end let(:params) do {} end it 'performs the request' do expect(client_double.mget(body: { :docs => [] })).to eq({}) end context 'when an index is specified' do let(:url) do 'foo/_mget' end it 'performs the request' do expect(client_double.mget(index: 'foo', body: { :docs => [] })).to eq({}) end end context 'when a type is specified' do let(:url) do 'foo/bar/_mget' end let(:body) do { ids: [ '1', '2' ]} end it 'performs the request' do expect(client_double.mget(index: 'foo', type: 'bar', body: { :ids => [ '1', '2'] })).to eq({}) end end context 'when url parameters are provided' do let(:params) do { refresh: true } end let(:body) do {} end it 'performs the request' do expect(client_double.mget(body: {}, refresh: true)).to eq({}) end end context 'when the request needs to be URL-escaped' do let(:url) do 'foo%5Ebar/bar%2Fbam/_mget' end let(:body) do { ids: [ '1', '2' ]} end it 'performs the request' do expect(client_double.mget(index: 'foo^bar', type: 'bar/bam', body: { :ids => [ '1', '2'] })).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/msearch_spec.rb000066400000000000000000000063661462737751600337720ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#msearch' do let(:expected_args) do [ 'POST', url, params, body, headers ] end let(:body) do nil end let(:url) do '_msearch' end let(:params) do {} end let(:headers) do { 'Content-Type' => 'application/x-ndjson' } end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :body argument' do expect do client.msearch end.to raise_exception(ArgumentError) end context 'when the body is an object' do let(:body) do <<-PAYLOAD.gsub(/^\s+/, '') {"index":"foo"} {"query":{"match_all":{}}} {"index":"bar"} {"query":{"match":{"foo":"bar"}}} {"search_type":"count"} {"facets":{"tags":{}}} PAYLOAD end it 'performs the request' do expect( client_double.msearch( body: [ { index: 'foo', search: { query: { match_all: {} } } }, { index: 'bar', search: { query: { match: { foo: 'bar' } } } }, { search_type: 'count', search: { facets: { tags: {} } } } ] ) ) end end context 'when the body is a string' do let(:body) do %Q|{"foo":"bar"}\n{"moo":"lam"}| end it 'performs the request' do expect(client_double.msearch(body: %Q|{"foo":"bar"}\n{"moo":"lam"}|)).to eq({}) end end context 'when an index is specified' do let(:url) do 'foo/_msearch' end let(:body) do '' end it 'performs the request' do expect(client_double.msearch(index: 'foo', body: [])) end end context 'when multiple indices are specified' do let(:url) do 'foo,bar/_msearch' end let(:body) do '' end it 'performs the request' do expect(client_double.msearch(index: ['foo', 'bar'], body: [])) end end context 'when the request needs to be URL-escaped' do let(:url) do 'foo%5Ebar/_msearch' end let(:body) do '' end it 'performs the request' do expect(client_double.msearch(index: 'foo^bar', body: [])).to eq({}) end end context 'when the URL params need to be URL-encoded' do let(:url) do '_msearch' end let(:body) do '' end let(:params) do { search_type: 'scroll' } end it 'performs the request' do expect(client_double.msearch(body: [], search_type: 'scroll')).to eq({}) end end end msearch_template_spec.rb000066400000000000000000000043421462737751600355760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#msearch_template' do let(:expected_args) do [ 'POST', url, params, body, headers ] end let(:body) do nil end let(:params) do {} end let(:headers) do { 'Content-Type' => 'application/x-ndjson' } end let(:url) do '_msearch/template' end context 'when a body is provided as a document' do let(:body) do <<-PAYLOAD.gsub(/^\s+/, '') {"index":"foo"} {"inline":{"query":{"match":{"foo":"{{q}}"}}},"params":{"q":"foo"}} {"index":"bar"} {"id":"query_foo","params":{"q":"foo"}} PAYLOAD end it 'performs the request' do expect(client_double.msearch_template(body: [ { index: 'foo' }, { inline: { query: { match: { foo: '{{q}}' } } }, params: { q: 'foo' } }, { index: 'bar' }, { id: 'query_foo', params: { q: 'foo' } } ])).to eq({}) end end context 'when a body is provided as a string' do let(:body) do %Q|{"foo":"bar"}\n{"moo":"lam"}| end it 'performs the request' do expect(client_double.msearch_template(body: %Q|{"foo":"bar"}\n{"moo":"lam"}|)).to eq({}) end end context 'when an index is provided' do let(:url) do 'foo/_msearch/template' end let(:body) do '' end it 'performs the request' do expect(client_double.msearch_template(index: 'foo', body: [])) end end end mtermvectors_spec.rb000066400000000000000000000026221462737751600350120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#mtermvectors' do let(:expected_args) do [ method, 'my-index/my-type/_mtermvectors', {}, body, {} ] end let(:method) { 'POST' } let(:body) do { ids: [1, 2, 3] } end it 'performs the request' do expect(client_double.mtermvectors(index: 'my-index', type: 'my-type', body: { ids: [1, 2, 3] })).to eq({}) end context 'when a list of ids is passed instead of a body' do let(:method) { 'GET' } it 'performs the request' do expect(client_double.mtermvectors(index: 'my-index', type: 'my-type', ids: [1, 2, 3])).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/nodes/000077500000000000000000000000001462737751600321065ustar00rootroot00000000000000clear_repositories_metering_archive_spec.rb000066400000000000000000000031241462737751600426560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/nodes# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.nodes#clear_metering_archive' do let(:expected_args) do [ 'DELETE', '_nodes/foo/_repositories_metering/bar', {}, nil, {} ] end it 'performs the request' do expect(client_double.nodes.clear_repositories_metering_archive(node_id: 'foo', max_archive_version: 'bar')).to eq({}) end let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an error if no node_id is provided' do expect do client.nodes.clear_repositories_metering_archive(max_archive_version: 'bar') end.to raise_exception(ArgumentError) end it 'raises an error if no max_archive_version is provided' do expect do client.nodes.clear_repositories_metering_archive(node_id: 'foo') end.to raise_exception(ArgumentError) end end get_repositories_metering_info_spec.rb000066400000000000000000000025331462737751600416640ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/nodes# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.nodes#get_metering_info' do let(:expected_args) do [ 'GET', '_nodes/foo/_repositories_metering', {}, nil, {} ] end it 'performs the request' do expect(client_double.nodes.get_repositories_metering_info(node_id: 'foo', max_archive_version: 'bar')).to eq({}) end let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an error if no node_id is provided' do expect do client.nodes.get_repositories_metering_info end.to raise_exception(ArgumentError) end end hot_threads_spec.rb000066400000000000000000000030451462737751600356740ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/nodes# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.nodes#hot_threads' do let(:expected_args) do [ 'GET', url, {}, nil, {} ] end let(:url) do '_cluster/nodes/hot_threads' end it 'performs the request' do expect(client_double.nodes.hot_threads).to eq({}) end context 'when the node id is specified' do let(:url) do '_cluster/nodes/foo/hot_threads' end it 'performs the request' do expect(client_double.nodes.hot_threads(node_id: 'foo')).to eq({}) end end context 'when the path must be URL-escaped' do let(:url) do '_cluster/nodes/foo%5Ebar/hot_threads' end it 'performs the request' do expect(client_double.nodes.hot_threads(node_id: 'foo^bar')).to eq({}) end end end info_spec.rb000066400000000000000000000043001462737751600343160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/nodes# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.nodes#info' do let(:expected_args) do [ 'GET', url, params, nil, {} ] end let(:url) do '_nodes' end it 'performs the request' do expect(client_double.nodes.info).to eq({}) end let(:params) do {} end context 'when the node id is specified' do let(:url) do '_nodes/foo' end it 'performs the request' do expect(client_double.nodes.info(node_id: 'foo')).to eq({}) end end context 'when multiple node ids are specified as a list' do let(:url) do '_nodes/A,B,C' end it 'performs the request' do expect(client_double.nodes.info(node_id: ['A', 'B', 'C'])).to eq({}) end end context 'when multiple node ids are specified as a String' do let(:url) do '_nodes/A,B,C' end it 'performs the request' do expect(client_double.nodes.info(node_id: 'A,B,C')).to eq({}) end end context 'when URL params are specified' do let(:url) do '_nodes' end let(:params) do { format: 'yaml' } end it 'performs the request' do expect(client_double.nodes.info(format: 'yaml')).to eq({}) end end context 'when metrics are specified' do let(:url) do '_nodes/http,network' end it 'performs the request' do expect(client_double.nodes.info(metric: ['http', 'network'])).to eq({}) end end end reload_secure_settings_spec.rb000066400000000000000000000043711462737751600401270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/nodes# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#reload_secure_settings' do let(:expected_args) do [ 'POST', url, params, body, {} ] end let(:params) { {} } let(:url) { '_nodes/reload_secure_settings' } let(:body) { nil } it 'performs the request' do expect(client_double.nodes.reload_secure_settings()).to eq({}) end context 'when a node id is specified' do let(:url) do '_nodes/foo/reload_secure_settings' end it 'performs the request' do expect(client_double.nodes.reload_secure_settings(node_id: 'foo')).to eq({}) end end context 'when more than one node id is specified as a string' do let(:body){ { foo: 'bar' } } let(:url) do '_nodes/foo,bar/reload_secure_settings' end it 'performs the request' do expect(client_double.nodes.reload_secure_settings(node_id: 'foo,bar', body: { foo: 'bar' })).to eq({}) end end context 'when more than one node id is specified as a list' do let(:body){ { foo: 'bar' } } let(:url) do '_nodes/foo,bar/reload_secure_settings' end it 'performs the request' do expect(client_double.nodes.reload_secure_settings(node_id: ['foo', 'bar'], body: { foo: 'bar' })).to eq({}) end end context 'when a timeout param is specified' do let(:params) do { timeout: '30s'} end it 'performs the request' do expect(client_double.nodes.reload_secure_settings(timeout: '30s')).to eq({}) end end end stats_spec.rb000066400000000000000000000034041462737751600345250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/nodes# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.nodes#stats' do let(:expected_args) do [ 'GET', url, params, nil, {} ] end let(:url) do '_nodes/stats' end it 'performs the request' do expect(client_double.nodes.stats).to eq({}) end let(:params) do {} end context 'when the node id is specified' do let(:url) do '_nodes/foo/stats' end it 'performs the request' do expect(client_double.nodes.stats(node_id: 'foo')).to eq({}) end end context 'when metrics are specified' do let(:url) do '_nodes/stats/http,fs' end it 'performs the request' do expect(client_double.nodes.stats(metric: [:http, :fs])).to eq({}) end end context 'when index metric is specified' do let(:url) do '_nodes/stats/indices/filter_cache' end it 'performs the request' do expect(client_double.nodes.stats(metric: :indices, index_metric: :filter_cache)).to eq({}) end end end open_point_in_time_spec.rb000066400000000000000000000020371462737751600361360ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#open_point_in_time' do let(:expected_args) do [ 'POST', 'foo/_pit', {}, nil, {} ] end it 'performs the request' do expect(client_double.open_point_in_time(index: 'foo')).to eq({}) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/ping_spec.rb000066400000000000000000000036111462737751600332730ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#ping' do let(:expected_args) do [ 'HEAD', '', {}, nil, {} ] end it 'performs the request' do expect(client_double.ping).to eq(true) end context 'when the response is a 404' do let(:response_double) do double('response', status: 404, body: {}, headers: {}) end it 'returns false' do expect(client_double.ping).to eq(false) end end context 'when a 404 \'not found\' exception is raised' do before do allow(client).to receive(:perform_request).and_raise(StandardError.new('404 NotFound')) end let(:client) do Class.new { include Elasticsearch::API }.new end it 'returns false' do expect(client.ping).to eq(false) end end context 'when \'connection failed\' exception is raised' do before do allow(client).to receive(:perform_request).and_raise(StandardError.new('ConnectionFailed')) end let(:client) do Class.new { include Elasticsearch::API }.new end it 'returns false' do expect(client.ping).to eq(false) end end end put_script_spec.rb000066400000000000000000000030031462737751600344460ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#put_script' do let(:url) do '_scripts/foo' end context 'when the lang parameter is provided' do let(:expected_args) do [ 'PUT', url, {}, { script: 'bar', lang: 'groovy' }, {} ] end it 'performs the request' do expect(client_double.put_script(id: 'foo', body: { script: 'bar', lang: 'groovy' })).to eq({}) end end context 'when the lang parameter is not provided' do let(:expected_args) do [ 'PUT', url, {}, { script: 'bar' }, {} ] end it 'performs the request' do expect(client_double.put_script(id: 'foo', body: { script: 'bar' })).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/reindex_spec.rb000066400000000000000000000020171462737751600337730ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#reindex' do let(:expected_args) do [ 'POST', '_reindex', {}, {}, {} ] end it 'performs the request' do expect(client_double.reindex(body: {})).to eq({}) end end render_search_template_spec.rb000066400000000000000000000027141462737751600367610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#render_search_template' do context 'when no id is specified' do let(:expected_args) do [ 'POST', '_render/template', {}, { foo: 'bar' }, {} ] end it 'performs the request' do expect(client_double.render_search_template(body: { foo: 'bar' })).to eq({}) end end context 'when id is specified' do let(:expected_args) do [ 'POST', '_render/template/foo', {}, { foo: 'bar' }, {} ] end it 'performs the request' do expect(client_double.render_search_template(id: 'foo', body: { foo: 'bar' })).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/scroll_spec.rb000066400000000000000000000026511462737751600336370ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#scroll' do context 'with scroll_id as a param' do let(:expected_args) do [ 'GET', '_search/scroll/cXVlcn...', {}, nil, {} ] end it 'performs the request' do expect(client_double.scroll(scroll_id: 'cXVlcn...')).to eq({}) end end context 'with scroll_id in the body' do let(:expected_args) do [ 'POST', '_search/scroll', {}, { scroll_id: 'cXVlcn...' }, {} ] end it 'performs the request' do expect(client_double.scroll(body: { scroll_id: 'cXVlcn...' })).to eq({}) end end end search_mvt_spec.rb000066400000000000000000000027201462737751600344120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#search_mvt' do let(:expected_args) do [ 'POST', url, params, body, {} ] end context 'with right parameters' do let(:url) { 'foo/_mvt/field/10/57.2127/6.2348' } let(:params) { {} } let(:body) { nil } it 'performs the request' do expect(client_double.search_mvt(index: 'foo', field: 'field', zoom: 10, x: 57.2127, y: 6.2348)).to eq({}) end end context 'when a param is missing' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an ArgumentError' do expect{ client.search_mvt }.to raise_exception(ArgumentError) end end end search_shards_spec.rb000066400000000000000000000020271462737751600350700ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#search_shards' do let(:expected_args) do [ 'GET', '_search_shards', {}, nil, {} ] end it 'performs the request' do expect(client_double.search_shards).to eq({}) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/search_spec.rb000066400000000000000000000054641462737751600336130ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#search' do let(:expected_args) do [ method, url, params, body, {} ] end let(:method) { 'GET' } let(:body) do nil end let(:params) do {} end let(:url) do '_all/foo/_search' end it 'has a default value for index' do expect(client_double.search(type: 'foo')) end context 'when a request definition is specified' do let(:body) do { query: { match: {} } } end let(:method) { 'POST' } let(:url) do '_search' end it 'performs the request' do expect(client_double.search(body: { query: { match: {} } })) end end context 'when an index is specified' do let(:url) do 'foo/_search' end it 'performs the request' do expect(client_double.search(index: 'foo')) end end context 'when an index and type are specified' do let(:url) do 'foo/bar/_search' end it 'performs the request' do expect(client_double.search(index: 'foo', type: 'bar')) end end context 'when multiple indices are specified' do let(:url) do 'foo,bar/_search' end it 'performs the request' do expect(client_double.search(index: ['foo', 'bar'])) end end context 'when multiple indices and types are specified' do let(:url) do 'foo,bar/lam,bam/_search' end it 'performs the request' do expect(client_double.search(index: ['foo', 'bar'], type: ['lam', 'bam'])) end end context 'when there are URL params' do let(:url) do '_search' end let(:params) do { search_type: 'count' } end it 'performs the request' do expect(client_double.search(search_type: 'count')) end end context 'when there are invalid URL params' do let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an ArgumentError' do expect{ client.search(search_type: 'count', qwertypoiuy: 'asdflkjhg') }.to raise_exception(ArgumentError) end end end search_template_spec.rb000066400000000000000000000021071462737751600354160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#search_template' do let(:expected_args) do [ 'POST', 'foo/_search/template', { }, { foo: 'bar' }, {} ] end it 'performs the request' do expect(client_double.search_template(index: 'foo', body: { foo: 'bar' })).to eq({}) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/shutdown/000077500000000000000000000000001462737751600326515ustar00rootroot00000000000000delete_node_spec.rb000066400000000000000000000024141462737751600364010ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/shutdown# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.shutdown#delete_node' do let(:expected_args) do [ 'DELETE', '_nodes/id/shutdown', {}, nil, {} ] end it 'performs the request' do expect(client_double.shutdown.delete_node(node_id: 'id')).to eq({}) end let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an error if no node_id is provided' do expect { client.shutdown.delete_node }.to raise_exception(ArgumentError) end end get_node_spec.rb000066400000000000000000000024401462737751600357150ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/shutdown# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.shutdown#get_node' do let(:expected_args) do [ 'GET', url, {}, nil, {} ] end context 'when id is provided' do let(:url) { '_nodes/id/shutdown' } it 'performs the request' do expect(client_double.shutdown.get_node(node_id: 'id')).to eq({}) end end context 'when no id is provided' do let(:url) { '_nodes/shutdown' } it 'performs the request' do expect(client_double.shutdown.get_node).to eq({}) end end end put_node_spec.rb000066400000000000000000000026561462737751600357570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/shutdown# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.shutdown#put_node' do let(:expected_args) do [ 'PUT', '_nodes/id/shutdown', {}, {}, {} ] end it 'performs the request' do expect(client_double.shutdown.put_node(body: {}, node_id: 'id')).to eq({}) end let(:client) do Class.new { include Elasticsearch::API }.new end it 'raises an error if no node_id is provided' do expect { client.shutdown.put_node(body: {}) }.to raise_exception(ArgumentError) end it 'raises an error if no body is provided' do expect { client.shutdown.put_node(node_id: 'id') }.to raise_exception(ArgumentError) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/snapshot/000077500000000000000000000000001462737751600326355ustar00rootroot00000000000000clone_spec.rb000066400000000000000000000036041462737751600352200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.snapshot#clone' do let(:expected_args) do [ 'PUT', '_snapshot/foo/bar/_clone/snapshot', {}, {}, {} ] end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :body argument' do expect { client.snapshot.clone(snapshot: 'bar') }.to raise_exception(ArgumentError) end it 'requires the :repository argument' do expect { client.snapshot.clone(snapshot: 'foo', body: {}) }.to raise_exception(ArgumentError) end it 'requires the :snapshot argument' do expect { client.snapshot.clone(repository: 'foo', body: {}) }.to raise_exception(ArgumentError) end it 'requires the :target_snapshot argument' do expect { client.snapshot.clone(repository: 'foo', body: {}, snapshot: 'bar') }.to raise_exception(ArgumentError) end it 'performs the request' do expect(client_double.snapshot.clone( repository: 'foo', snapshot: 'bar', body: {}, target_snapshot: 'snapshot' )).to eq({}) end end create_repository_spec.rb000066400000000000000000000027151462737751600376640ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.snapshot#create_repository' do let(:expected_args) do [ 'PUT', '_snapshot/foo', {}, {}, {} ] end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :body argument' do expect { client.snapshot.create_repository(repository: 'foo') }.to raise_exception(ArgumentError) end it 'requires the :repository argument' do expect { client.snapshot.create_repository(body: {}) }.to raise_exception(ArgumentError) end it 'performs the request' do expect(client_double.snapshot.create_repository(repository: 'foo', body: {})).to eq({}) end end create_spec.rb000066400000000000000000000027251462737751600353660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.snapshot#create' do let(:expected_args) do [ 'PUT', '_snapshot/foo/bar', {}, {}, {} ] end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :repository argument' do expect { client.snapshot.create(snapshot: 'bar', body: {}) }.to raise_exception(ArgumentError) end it 'requires the :snapshot argument' do expect { client.snapshot.create(repository: 'foo', body: {}) }.to raise_exception(ArgumentError) end it 'performs the request' do expect(client_double.snapshot.create(repository: 'foo', snapshot: 'bar', body: {})).to eq({}) end end delete_repository_spec.rb000066400000000000000000000025301462737751600376560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.snapshot#delete_repository' do let(:expected_args) do [ 'DELETE', url, {}, nil, {} ] end let(:url) do '_snapshot/foo' end it 'performs the request' do expect(client_double.snapshot.delete_repository(repository: 'foo')).to eq({}) end context 'when multiple indices are specified' do let(:url) do '_snapshot/foo,bar' end it 'performs the request' do expect(client_double.snapshot.delete_repository(repository: ['foo','bar'])).to eq({}) end end end delete_spec.rb000066400000000000000000000026731462737751600353670ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.snapshot#delete' do let(:expected_args) do [ 'DELETE', '_snapshot/foo/bar', {}, nil, {} ] end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :snapshot argument' do expect { client.snapshot.delete(repository: 'foo') }.to raise_exception(ArgumentError) end it 'requires the :repository argument' do expect { client.snapshot.delete(snapshot: 'bar') }.to raise_exception(ArgumentError) end it 'performs the request' do expect(client_double.snapshot.delete(repository: 'foo', snapshot: 'bar')).to eq({}) end end get_repository_spec.rb000066400000000000000000000020751462737751600371770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.snapshot#get_repository' do let(:expected_args) do [ 'GET', '_snapshot/foo', {}, nil, {} ] end it 'performs the request' do expect(client_double.snapshot.get_repository(repository: 'foo')).to eq({}) end end get_spec.rb000066400000000000000000000026541462737751600347030ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.snapshot#get' do let(:expected_args) do [ 'GET', '_snapshot/foo/bar', {}, nil, {} ] end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :snapshot argument' do expect { client.snapshot.get(repository: 'foo') }.to raise_exception(ArgumentError) end it 'requires the :repository argument' do expect { client.snapshot.get(snapshot: 'bar') }.to raise_exception(ArgumentError) end it 'performs the request' do expect(client_double.snapshot.get(repository: 'foo', snapshot: 'bar')).to eq({}) end end repository_analize_spec.rb000066400000000000000000000024751462737751600400470ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.snapshot#repository_analyze' do let(:expected_args) do [ 'POST', url, {}, nil, {} ] end let(:url) do '_snapshot/foo/_analyze' end it 'performs the request' do expect(client_double.snapshot.repository_analyze(repository: 'foo')).to eq({}) end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :repository argument' do expect { client.snapshot.repository_analyze }.to raise_exception(ArgumentError) end end restore_spec.rb000066400000000000000000000027061462737751600356050ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.snapshot#restore' do let(:expected_args) do [ 'POST', '_snapshot/foo/bar/_restore', {}, nil, {} ] end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :snapshot argument' do expect { client.snapshot.restore(repository: 'foo') }.to raise_exception(ArgumentError) end it 'requires the :repository argument' do expect { client.snapshot.restore(snapshot: 'bar') }.to raise_exception(ArgumentError) end it 'performs the request' do expect(client_double.snapshot.restore(repository: 'foo', snapshot: 'bar')).to eq({}) end end status_spec.rb000066400000000000000000000024771462737751600354520ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.snapshot#status' do let(:expected_args) do [ 'GET', url, {}, nil, {} ] end let(:url) do '_snapshot/_status' end it 'performs the request' do expect(client_double.snapshot.status).to eq({}) end context 'when a repository and snapshot are specified' do let(:url) do '_snapshot/foo/bar/_status' end it 'performs the request' do expect(client_double.snapshot.status(repository: 'foo', snapshot: 'bar')).to eq({}) end end end verify_repository_spec.rb000066400000000000000000000021141462737751600377160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/snapshot# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.snapshot#verify_repository' do let(:expected_args) do [ 'POST', '_snapshot/foo/_verify', {}, nil, {} ] end it 'performs the request' do expect(client_double.snapshot.verify_repository(repository: 'foo')).to eq({}) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/tasks/000077500000000000000000000000001462737751600321235ustar00rootroot00000000000000cancel_spec.rb000066400000000000000000000024101462737751600346250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/tasks# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.tasks#cancel' do let(:expected_args) do [ 'POST', url, {}, nil, {} ] end let(:url) do '_tasks/_cancel' end it 'performs the request' do expect(client_double.tasks.cancel).to eq({}) end context 'when a task id is specified' do let(:url) do '_tasks/foo/_cancel' end it 'performs the request' do expect(client_double.tasks.cancel(task_id: 'foo')).to eq({}) end end end get_spec.rb000066400000000000000000000020351462737751600341620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/tasks# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.tasks#get' do let(:expected_args) do [ 'GET', '_tasks/foo1', {}, nil, {} ] end it 'performs the request' do expect(client_double.tasks.get(task_id: 'foo1')).to eq({}) end end list_spec.rb000066400000000000000000000020471462737751600343610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions/tasks# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.tasks#list' do let(:expected_args) do [ 'GET', url, {}, nil, {} ] end let(:url) do '_tasks' end it 'performs the request' do expect(client_double.tasks.list).to eq({}) end end termvectors_spec.rb000066400000000000000000000032111462737751600346300ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#termvectors' do let(:expected_args) do [ 'POST', url, params, body, {} ] end let(:url) do 'foo/bar/123/_termvectors' end let(:params) do {} end let(:body) do {} end let(:client) do Class.new { include Elasticsearch::API }.new end it 'requires the :index argument' do expect { client.termvectors(type: 'bar', id: '1') }.to raise_exception(ArgumentError) end it 'performs the request' do expect(client_double.termvectors(index: 'foo', type: 'bar', id: '123', body: {})).to eq({}) end context 'when the older api name \'termvector\' is used' do let(:url) do 'foo/bar/123/_termvector' end it 'performs the request' do expect(client_double.termvector(index: 'foo', type: 'bar', id: '123', body: {})).to eq({}) end end end update_by_query_spec.rb000066400000000000000000000020601462737751600354550ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#update_by_query' do let(:expected_args) do [ 'POST', 'foo/_update_by_query', {}, nil, {} ] end it 'performs the request' do expect(client_double.update_by_query(index: 'foo')).to eq({}) end end update_document_spec.rb000066400000000000000000000055561462737751600354510ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#update' do let(:expected_args) do [ 'POST', url, params, body, {} ] end let(:body) do { doc: { } } end let(:url) do 'foo/bar/1/_update' end let(:client) do Class.new { include Elasticsearch::API }.new end let(:params) do {} end it 'requires the :index argument' do expect { client.update(type: 'bar', id: '1') }.to raise_exception(ArgumentError) end it 'requires the :id argument' do expect { client.update(index: 'foo', type: 'bar') }.to raise_exception(ArgumentError) end it 'performs the request' do expect(client_double.update(index: 'foo', type: 'bar', id: '1', body: { doc: {} })).to eq({}) end context 'when URL parameters are provided' do let(:url) do 'foo/bar/1/_update' end let(:body) do {} end it 'performs the request' do expect(client_double.update(index: 'foo', type: 'bar', id: '1', body: {})) end end context 'when invalid parameters are specified' do it 'raises an ArgumentError' do expect { client.update(index: 'foo', type: 'bar', id: '1', body: { doc: {} }, qwertypoiuy: 'asdflkjhg') }.to raise_exception(ArgumentError) end end context 'when the request needs to be URL-escaped' do let(:url) do 'foo%5Ebar/bar%2Fbam/1/_update' end let(:body) do {} end it 'escapes the parts' do expect(client_double.update(index: 'foo^bar', type: 'bar/bam', id: '1', body: {})) end end context 'when a NotFound exception is raised' do before do allow(client).to receive(:perform_request).and_raise(NotFound) end it 'raises it to the user' do expect { client.update(index: 'foo', type: 'bar', id: 'XXX', body: {}) }.to raise_exception(NotFound) end context 'when the :ignore parameter is specified' do it 'does not raise the error to the user' do expect(client.update(index: 'foo', type: 'bar', id: 'XXX', body: {}, ignore: 404)).to eq(false) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/api_spec.rb000066400000000000000000000024401462737751600314460ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::API do describe '#settings' do it 'allows access to settings' do expect(described_class.settings).not_to be_nil end it 'has a default serializer' do expect(Elasticsearch::API.serializer).to eq(MultiJson) end context 'when settings are changed' do before do Elasticsearch::API.settings[:foo] = 'bar' end it 'changes the settings' do expect(Elasticsearch::API.settings[:foo]).to eq('bar') end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/client_spec.rb000066400000000000000000000024111462737751600321510ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'API Client' do let(:client) do Class.new { include Elasticsearch::API }.new end describe '#cluster' do it 'responds to the method' do expect(client.respond_to?(:cluster)).to be(true) end end describe '#indices' do it 'responds to the method' do expect(client.respond_to?(:indices)).to be(true) end end describe '#bulk' do it 'responds to the method' do expect(client.respond_to?(:bulk)).to be(true) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/rest_api_yaml_spec.rb000066400000000000000000000151461462737751600335340ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' require 'rest_yaml_tests_helper' describe 'Rest API YAML tests' do if REST_API_YAML_FILES.empty? logger = Logger.new($stdout) logger.error 'No test files found!' logger.info 'Use rake rake elasticsearch:download_artifacts in the root directory of the project to download the test artifacts.' exit 1 end # Traverse YAML files and create TestFile object: REST_API_YAML_FILES.each do |file| begin test_file = Elasticsearch::RestAPIYAMLTests::TestFile.new(file, ADMIN_CLIENT, REST_API_YAML_SKIP_FEATURES) rescue SkipTestsException => _e # If the test file has a `skip` at the top level that applies to this # version of Elasticsearch, continue with the next text. logger = Logger.new($stdout) logger.info "Skipping #{file} due to 'skip all'." next end context "#{file.gsub("#{YAML_FILES_DIRECTORY}/", '')}" do test_file.tests.each do |test| context "#{test.description}" do if test.skip_test?(ADMIN_CLIENT) skip 'Test contains feature(s) not yet supported or version is not satisfied' else let(:client) do DEFAULT_CLIENT end # Runs once before each test in a test file before(:all) do test_file.setup end after(:all) do test_file.teardown Elasticsearch::RestAPIYAMLTests::WipeCluster.run(ADMIN_CLIENT) end test.task_groups.each do |task_group| before do task_group.run(client) end # 'catch' is in the task group definition if task_group.catch_exception? it 'sends the request and throws the expected error' do expect(task_group.exception).to match_error(task_group.expected_exception_message) end # 'match' on error description is in the task group definition if task_group.has_match_clauses? task_group.match_clauses.each do |match| it 'contains the expected error in the request response' do expect(task_group.exception.message).to match(Regexp.new(Regexp.escape(match['match'].values.first.to_s))) end end end else # 'match' is in the task group definition if task_group.has_match_clauses? task_group.match_clauses.each do |match| it "has the expected value (#{match['match'].values.join(',')}) in the response field (#{match['match'].keys.join(',')})" do expect(task_group.response).to match_response(match['match'], test) end end end # 'length' is in the task group definition if task_group.has_length_match_clauses? task_group.length_match_clauses.each do |match| it "the '#{match['length'].keys.join(',')}' field have the expected length" do expect(task_group.response).to match_response_field_length(match['length'], test) end end end # 'is_true' is in the task group definition if task_group.has_true_clauses? task_group.true_clauses.each do |match| it "sends the request and the '#{match['is_true']}' field is set to true" do expect(task_group.response).to match_true_field(match['is_true'], test) end end end # 'is_false' is in the task group definition if task_group.has_false_clauses? task_group.false_clauses.each do |match| it "sends the request and the '#{match['is_false']}' field is set to true" do expect(task_group.response).to match_false_field(match['is_false'], test) end end end # 'gte' is in the task group definition if task_group.has_gte_clauses? task_group.gte_clauses.each do |match| it "sends the request and the '#{match['gte']}' field is greater than or equal to the expected value" do expect(task_group.response).to match_gte_field(match['gte'], test) end end end # 'gt' is in the task group definition if task_group.has_gt_clauses? task_group.gt_clauses.each do |match| it "sends the request and the '#{match['gt']}' field is greater than the expected value" do expect(task_group.response).to match_gt_field(match['gt'], test) end end end # 'lte' is in the task group definition if task_group.has_lte_clauses? task_group.lte_clauses.each do |match| it "sends the request and the '#{match['lte']}' field is less than or equal to the expected value" do expect(task_group.response).to match_lte_field(match['lte'], test) end end end # 'lt' is in the task group definition if task_group.has_lt_clauses? task_group.lt_clauses.each do |match| it "sends the request and the '#{match['lt']}' field is less than the expected value" do expect(task_group.response).to match_lt_field(match['lt'], test) end end end end end end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/elasticsearch/api/utils_spec.rb000066400000000000000000000267401462737751600320460ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::API::Utils do let(:utils) do Class.new { include Elasticsearch::API::Utils }.new end describe '#__escape' do it 'encodes Unicode characters' do expect(utils.__escape('中文')).to eq('%E4%B8%AD%E6%96%87') end it 'encodes special characters' do expect(utils.__escape('foo bar')).to eq('foo%20bar') expect(utils.__escape('foo/bar')).to eq('foo%2Fbar') expect(utils.__escape('foo^bar')).to eq('foo%5Ebar') end it 'does not encode asterisks' do expect(utils.__escape('*')).to eq('*') end end describe '#__listify' do it 'creates a list from a single value' do expect(utils.__listify('foo')).to eq('foo') end it 'creates a list from an array' do expect(utils.__listify(['foo', 'bar'])).to eq('foo,bar') end it 'creates a list from multiple arguments' do expect(utils.__listify('foo', 'bar')).to eq('foo,bar') end it 'ignores nil values' do expect(utils.__listify(['foo', nil, 'bar'])).to eq('foo,bar') end it 'ignores special characters' do expect(utils.__listify(['foo', 'bar^bam'])).to eq('foo,bar%5Ebam') end context 'when the escape option is set to false' do it 'does not escape the characters' do expect(utils.__listify(['foo', 'bar^bam'], escape: false)).to eq('foo,bar^bam') end end end describe '#__pathify' do it 'creates a path from a single value' do expect(utils.__pathify('foo')).to eq('foo') end it 'creates a path from an array' do expect(utils.__pathify(['foo', 'bar'])).to eq('foo/bar') end it 'ignores nil values' do expect(utils.__pathify(['foo', nil, 'bar'])).to eq('foo/bar') end it 'ignores empty string values' do expect(utils.__pathify(['foo', '', 'bar'])).to eq('foo/bar') end end describe '#__bulkify' do context 'when the input is an array of hashes' do let(:result) do utils.__bulkify [ { index: { _index: 'myindexA', _id: '1', data: { title: 'Test' } } }, { update: { _index: 'myindexB', _id: '2', data: { doc: { title: 'Update' } } } }, { delete: { _index: 'myindexC', _id: '3' } } ] end let(:expected_string) do <<-PAYLOAD.gsub(/^\s+/, '') {"index":{"_index":"myindexA","_id":"1"}} {"title":"Test"} {"update":{"_index":"myindexB","_id":"2"}} {"doc":{"title":"Update"}} {"delete":{"_index":"myindexC","_id":"3"}} PAYLOAD end it 'serializes the hashes' do expect(result).to eq(expected_string) end end context 'when the input is an array of strings' do let(:result) do utils.__bulkify(['{"foo":"bar"}','{"moo":"bam"}']) end let(:expected_string) do <<-PAYLOAD.gsub(/^\s+/, '') {"foo":"bar"} {"moo":"bam"} PAYLOAD end it 'serializes the array of strings' do expect(result).to eq(expected_string) end end context 'when the input is an array of header/data pairs' do let(:result) do utils.__bulkify([{ foo: 'bar' }, { moo: 'bam' },{ foo: 'baz' }]) end let(:expected_string) do <<-PAYLOAD.gsub(/^\s+/, '') {"foo":"bar"} {"moo":"bam"} {"foo":"baz"} PAYLOAD end it 'serializes the array of strings' do expect(result).to eq(expected_string) end end context 'when the payload has the :data option' do let(:input) do { index: { foo: 'bar', data: { moo: 'bam' } } } end let(:result) do utils.__bulkify([input]) end let(:expected_string) do <<-PAYLOAD.gsub(/^\s+/, '') {"index":{"foo":"bar"}} {"moo":"bam"} PAYLOAD end it 'does not mutate the input' do expect(input[:index][:data]).to eq(moo: 'bam') end it 'serializes the array of strings' do expect(result).to eq(expected_string) end end context 'when the payload has nested :data options' do let(:data) do { data: { a: 'b', data: { c: 'd' } } } end let(:result) do utils.__bulkify([{ index: { foo: 'bar'} } , data]) end let(:lines) do result.split("\n") end let(:header) do MultiJson.load(lines.first) end let(:data_string) do MultiJson.load(lines.last) end it 'does not mutate the input' do expect(data[:data]).to eq(a: 'b', data: { c: 'd' }) end it 'serializes the array of strings' do expect(header['index']['foo']).to eq('bar') expect(data_string['data']['a']).to eq('b') expect(data_string['data']['data']['c']).to eq('d') end end end context '#__validate_and_extract_params' do it 'listify Arrays' do expect(utils.__validate_and_extract_params({ foo: ['a', 'b'] }, [:foo] )).to eq(foo: 'a,b') end it 'does not escape the parameters' do expect(utils.__validate_and_extract_params({ foo: ['a.*', 'b.*'] }, [:foo] )).to eq(foo: 'a.*,b.*') end context 'when the params are valid' do it 'extracts the valid params from the hash' do expect(utils.__validate_and_extract_params({ foo: 'qux' }, [:foo, :bar]) ).to eq(foo: 'qux') end end context 'when the params are invalid' do it 'raises an ArgumentError' do expect { utils.__validate_and_extract_params({ foo: 'qux', bam: 'mux' }, [:foo, :bar]) }.to raise_exception(ArgumentError) end end context 'when COMMON_PARAMS are provided' do it 'extracts the params' do expect(utils.__validate_and_extract_params({ index: 'foo'}, [:foo])).to eq({}) end end context 'when COMMON_QUERY_PARAMS are provided' do it 'extracts the params' do expect(utils.__validate_and_extract_params(format: 'yaml')).to eq(format: 'yaml') end end context 'when the :skip_paramter_validation option is set' do let(:result) do utils.__validate_and_extract_params( { foo: 'q', bam: 'm' }, [:foo, :bar], { skip_parameter_validation: true } ) end it 'skips parameter validation' do expect(result).to eq(foo: 'q', bam: 'm') end end context 'when the module has the setting to skip parameter validation' do around do |example| original_value = Elasticsearch::API.settings[:skip_parameter_validation] Elasticsearch::API.settings[:skip_parameter_validation] = true example.run Elasticsearch::API.settings[:skip_parameter_validation] = original_value end let(:result) do utils.__validate_and_extract_params( { foo: 'q', bam: 'm' }, [:foo, :bar]) end it 'applies the module setting' do expect(result).to eq(foo: 'q', bam: 'm') end end end describe '#__extract_parts' do it 'extracts parts with true value from a Hash' do expect(utils.__extract_parts({ foo: true, moo: 'blah' }, [:foo, :bar])).to eq(['foo']) end it 'extracts parts with string value from a Hash' do expect(utils.__extract_parts({ foo: 'qux', moo: 'blah' }, [:foo, :bar])).to eq(['qux']) end end context '#__rescue_from_not_found' do it 'returns false if exception class name contains \'NotFound\'' do expect(utils.__rescue_from_not_found { raise NotFound }).to be(false) end it 'returns false if exception message contains \'Not Found\'' do expect(utils.__rescue_from_not_found { raise StandardError.new "Not Found" }).to be(false) expect(utils.__rescue_from_not_found { raise StandardError.new "NotFound" }).to be(false) end it 'raises the exception if the class name and message do not include \'NotFound\'' do expect { utils.__rescue_from_not_found { raise StandardError.new "Any other exception" } }.to raise_exception(StandardError) end end context '#__report_unsupported_parameters' do context 'when the parameters are passed as Symbols' do let(:arguments) do { foo: 'bar', moo: 'bam', baz: 'qux' } end let(:unsupported_params) do [ :foo, :moo] end let(:message) do message = '' expect(Kernel).to receive(:warn) { |msg| message = msg } utils.__report_unsupported_parameters(arguments, unsupported_params) message end it 'prints the unsupported parameters' do expect(message).to match(/You are using unsupported parameter \[\:foo\]/) expect(message).to match(/You are using unsupported parameter \[\:moo\]/) end end context 'when the parameters are passed as Hashes' do let(:arguments) do { foo: 'bar', moo: 'bam', baz: 'qux' } end let(:unsupported_params) do [ :foo, :moo] end let(:message) do message = '' expect(Kernel).to receive(:warn) { |msg| message = msg } utils.__report_unsupported_parameters(arguments, unsupported_params) message end it 'prints the unsupported parameters' do expect(message).to match(/You are using unsupported parameter \[\:foo\]/) expect(message).to match(/You are using unsupported parameter \[\:moo\]/) end end context 'when the parameters are passed as a mix of Hashes and Symbols' do let(:arguments) do { foo: 'bar', moo: 'bam', baz: 'qux' } end let(:unsupported_params) do [ { foo: { explanation: 'NOT_SUPPORTED'} }, :moo ] end let(:message) do message = '' expect(Kernel).to receive(:warn) { |msg| message = msg } utils.__report_unsupported_parameters(arguments, unsupported_params) message end it 'prints the unsupported parameters' do expect(message).to match(/You are using unsupported parameter \[\:foo\]/) expect(message).to match(/You are using unsupported parameter \[\:moo\]/) expect(message).to match(/NOT_SUPPORTED/) end end context 'when unsupported parameters are unused' do let(:arguments) do { moo: 'bam', baz: 'qux' } end let(:unsupported_params) do [ :foo ] end it 'prints the unsupported parameters' do expect(Kernel).not_to receive(:warn) utils.__report_unsupported_parameters(arguments, unsupported_params) end end end describe '#__report_unsupported_method' do let(:message) do message = '' expect(Kernel).to receive(:warn) { |msg| message = msg } utils.__report_unsupported_method(:foo) message end it 'prints a warning' do expect(message).to match(/foo/) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/rest_yaml_tests_helper.rb000066400000000000000000000123321462737751600310610ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require "#{File.expand_path(File.dirname('..'), '..')}/api-spec-testing/test_file" require "#{File.expand_path(File.dirname('..'), '..')}/api-spec-testing/rspec_matchers" require "#{File.expand_path(File.dirname('..'), '..')}/api-spec-testing/wipe_cluster" include Elasticsearch::RestAPIYAMLTests TRANSPORT_OPTIONS = {} PROJECT_PATH = File.join(File.dirname(__FILE__), '..') STACK_VERSION = ENV['STACK_VERSION'] require 'elasticsearch/xpack' def testing_compatibility? [1, true, 'true'].include?(ENV['ELASTIC_CLIENT_APIVERSIONING']) end if (hosts = ELASTICSEARCH_URL) split_hosts = hosts.split(',').map do |host| /(http\:\/\/)?\S+/.match(host) end uri = URI.parse(split_hosts.first[0]) TEST_HOST = uri.host TEST_PORT = uri.port else TEST_HOST, TEST_PORT = 'localhost', '9200' end test_suite = ENV['TEST_SUITE'] || 'free' password = ENV['ELASTIC_PASSWORD'] || 'changeme' user = ENV['ELASTIC_USER'] || 'elastic' if defined?(TEST_HOST) && defined?(TEST_PORT) URL = "http://#{TEST_HOST}:#{TEST_PORT}".freeze if STACK_VERSION.match?(/^8\./) if ENV['TEST_SUITE'] == 'platinum' raw_certificate = File.read(File.join(PROJECT_PATH, '../.ci/certs/testnode.crt')) certificate = OpenSSL::X509::Certificate.new(raw_certificate) raw_key = File.read(File.join(PROJECT_PATH, '../.ci/certs/testnode.key')) key = OpenSSL::PKey::RSA.new(raw_key) ca_file = File.expand_path(File.join(PROJECT_PATH, '/.ci/certs/ca.crt')) host = "https://elastic:#{password}@#{uri.host}:#{uri.port}".freeze transport_options = { ssl: { verify: false, client_cert: certificate, client_key: key, ca_file: ca_file } } else host = "http://elastic:#{password}@#{uri.host}:#{uri.port}".freeze transport_options = {} end ADMIN_CLIENT = Elasticsearch::Client.new(host: host, transport_options: transport_options) DEFAULT_CLIENT = if ENV['QUIET'] == 'true' Elasticsearch::Client.new(host: host, transport_options: transport_options) else Elasticsearch::Client.new( host: host, tracer: Logger.new($stdout), transport_options: transport_options ) end if ENV['QUIET'] == 'true' DEFAULT_CLIENT = Elasticsearch::Client.new( host: URL, transport_options: TRANSPORT_OPTIONS, user: user, password: password ) else DEFAULT_CLIENT = Elasticsearch::Client.new( host: URL, transport_options: TRANSPORT_OPTIONS, user: user, password: password, tracer: Logger.new($stdout) ) end else ADMIN_CLIENT = Elasticsearch::Client.new(host: URL, transport_options: TRANSPORT_OPTIONS) if ENV['QUIET'] == 'true' DEFAULT_CLIENT = Elasticsearch::Client.new(host: URL, transport_options: TRANSPORT_OPTIONS) else DEFAULT_CLIENT = Elasticsearch::Client.new(host: URL, transport_options: TRANSPORT_OPTIONS, tracer: Logger.new($stdout)) end end end YAML_FILES_DIRECTORY = "#{PROJECT_PATH}/../tmp/rest-api-spec/#{STACK_VERSION.match?(/^8\./) ? 'compatTest' : 'test'}/free" SINGLE_TEST = if ENV['SINGLE_TEST'] && !ENV['SINGLE_TEST'].empty? test_target = ENV['SINGLE_TEST'] if test_target.match?(/\.yml$/) ["#{PROJECT_PATH}/../tmp/rest-api-spec/test/free/#{test_target}"] else Dir.glob( ["#{PROJECT_PATH}/../tmp/rest-api-spec/test/free/#{test_target}/*.yml"] ) end end # Skipped tests file = File.expand_path("#{__dir__}/skipped_tests.yml") skipped_tests = YAML.load_file(file) # The directory of rest api YAML files. REST_API_YAML_FILES = if ENV['RUN_SKIPPED_TESTS'] # only run the skipped tests if true SKIPPED_TESTS = [] skipped_tests.map { |test| "#{YAML_FILES_DIRECTORY}/#{test[:file]}" } else # If not, define the skipped tests constant and try the single test or all # the tests SKIPPED_TESTS = skipped_tests SINGLE_TEST || Dir.glob("#{YAML_FILES_DIRECTORY}/**/*.yml") end # The features to skip REST_API_YAML_SKIP_FEATURES = ['warnings', 'node_selector'].freeze elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/skipped_tests.yml000066400000000000000000000014371462737751600273640ustar00rootroot00000000000000# Response from Elasticsearch is just a String, so it's not possible to compare using headers. - :file: 'cat.aliases/20_headers.yml' :description: 'Simple alias with yaml body through Accept header' # Check version skip logic - :file: 'create/15_without_id.yml' :description: 'Create without ID' # No error is raised - :file: 'create/15_without_id_with_types.yml' :description: 'Create without ID' # Error message doesn't match - :file: 'tasks.get/10_basic.yml' :description: 'get task test' # Figure out how to match response when there is an error - :file: 'delete/70_mix_typeless_typeful.yml' :description: '*' # Figure out how to match response when there is an error - :file: 'cat.templates/10_basic.yml' :description: '*' elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/spec/spec_helper.rb000066400000000000000000000053031462737751600265720ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. if ENV['COVERAGE'] && ENV['CI'].nil? require 'simplecov' SimpleCov.start { add_filter %r{^/test|spec/} } end if defined?(JRUBY_VERSION) require 'pry-nav' else require 'pry-byebug' end require 'ansi' require 'yaml' require 'active_support/isolated_execution_state' unless RUBY_VERSION < '2.7.0' require 'jbuilder' require 'jsonify' require 'elasticsearch' require 'elasticsearch-api' require 'elasticsearch-transport' require 'jbuilder' require 'jsonify' require 'yaml' tracer = ::Logger.new(STDERR) tracer.formatter = lambda { |s, d, p, m| "#{m.gsub(/^.*$/) { |n| ' ' + n }.ansi(:faint)}\n" } unless defined?(ELASTICSEARCH_URL) ELASTICSEARCH_URL = ENV['ELASTICSEARCH_URL'] || ENV['TEST_ES_SERVER'] || "localhost:#{(ENV['TEST_CLUSTER_PORT'] || 9200)}" end DEFAULT_CLIENT = Elasticsearch::Client.new(host: ELASTICSEARCH_URL, tracer: (tracer unless ENV['QUIET'])) module HelperModule def self.included(context) context.let(:client_double) do Class.new { include Elasticsearch::API }.new.tap do |client| expect(client).to receive(:perform_request).with(*expected_args).and_return(response_double) end end context.let(:client) do Class.new { include Elasticsearch::API }.new.tap do |client| expect(client).to receive(:perform_request).with(*expected_args).and_return(response_double) end end context.let(:response_double) do double('response', status: 200, body: {}, headers: {}) end end end RSpec.configure do |config| config.include(HelperModule) config.formatter = 'documentation' config.add_formatter('RspecJunitFormatter', 'tmp/elasticsearch-api-junit.xml') config.add_formatter( 'RSpec::Core::Formatters::HtmlFormatter', "tmp/elasticsearch-#{ENV['TEST_SUITE']}-#{RUBY_VERSION}-#{ENV['STACK_VERSION']}.html" ) config.color_mode = :on end class NotFound < StandardError; end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/000077500000000000000000000000001462737751600241615ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/Gemfile000066400000000000000000000016471462737751600254640ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. source 'https://rubygems.org' gem 'activesupport' gem 'byebug' gem 'coderay' gem 'json' gem 'multi_json' gem 'pry' gem 'rest-client' gem 'rubocop' gem 'thor' elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/README.md000066400000000000000000000033661462737751600254500ustar00rootroot00000000000000# Utils ## The Generator This directory hosts The Generator, a tool that generates the classes for each API endpoint from the [Elasticsearch REST API JSON Specification](https://github.com/elastic/elasticsearch/tree/master/rest-api-spec). ### Generate To generate the code, you need to have the Elasticsearch REST API spec files in `tmp/rest-api-spec` in the root of the project. You can run a rake task from the root of the project to download the specs corresponding to the current running cluster: ```bash $ rake elasticsearch:download_artifacts ``` Once the JSON files have been downloaded, you need to run (from this folder): ```bash $ thor api:code:generate ``` - The oss Ruby code will be generated in `elasticsearch-api/lib/elasticsearch/api/actions`. - The xpack Ruby code will be generated in `elasticsearch-xpack/lib/elasticsearch/xpack/api/actions`. - The generator runs Rubocop to autolint and clean up the generated files. Alternatively, you can pass in `oss` or `xpack` as parameters to generate only one of the 2 sets of endpoints: ```bash $ thor api:code:generate --api=xpack $ thor api:code:generate --api=oss ``` ### Development The main entry point is `generate_source.rb`, which contains a class that implements a Thor task: `generate`: ``` $ thor api:code:generate ``` It uses [Thor::Actions](https://github.com/erikhuda/thor/wiki/Actions)' `template` method and `templates/method.erb` to generate the final code. The `generator` directory contains some helpers used to generate the code. The ERB template is split into partials and you can find all ERB files in the `templates` directory. There's also a lister task: ``` $ thor api:list ``` It's implemented in `lister.rb` and it lists all the REST API endpoints from the JSON specification. elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/Thorfile000066400000000000000000000004501462737751600256570ustar00rootroot00000000000000# Licensed to Elasticsearch B.V under one or more agreements. # Elasticsearch B.V licenses this file to you under the Apache 2.0 License. # See the LICENSE file in the project root for more information require File.expand_path('./thor/generate_source') require File.expand_path('./thor/lister') elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/000077500000000000000000000000001462737751600251355ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/.rubocop.yml000066400000000000000000000001101462737751600273770ustar00rootroot00000000000000Layout/EndAlignment: AutoCorrect: true Metrics/LineLength: Max: 160 elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/generate_source.rb000066400000000000000000000256111462737751600306410ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # encoding: UTF-8 require 'thor' require 'pathname' require 'active_support/core_ext/hash/deep_merge' require 'active_support/inflector' require 'multi_json' require 'coderay' require 'pry' require_relative 'generator/files_helper' require_relative 'generator/endpoint_specifics' module Elasticsearch module API # A command line application based on [Thor](https://github.com/wycats/thor), # which will read the JSON API spec file(s), and generate # the Ruby source code (one file per API endpoint) with correct # module namespace, method names, and RDoc documentation, # as well as test files for each endpoint. # # Specific exceptions and code snippets that need to be included are written # in EndpointSpecifics (generator/endpoint_specifics) and the module is included # here. # class SourceGenerator < Thor namespace 'api:code' include Thor::Actions include EndpointSpecifics __root = Pathname(File.expand_path('../../..', __FILE__)) desc 'generate', 'Generate source code and tests from the REST API JSON specification' method_option :verbose, type: :boolean, default: false, desc: 'Output more information' method_option :tests, type: :boolean, default: false, desc: 'Generate test files' method_option :api, type: :array, default: %w[oss xpack], desc: 'APIs to generate (oss, x-pack)' def generate self.class.source_root File.expand_path(__dir__) @xpack = options[:api].include? 'xpack' @oss = options[:api].include? 'oss' __generate_source(:xpack) if @xpack __generate_source(:oss) if @oss # -- Tree output print_tree if options[:verbose] end private def __generate_source(api) @current_api = api @output = FilesHelper.output_dir(api) FilesHelper.files(api).each do |filepath| @path = Pathname(filepath) @json = MultiJson.load(File.read(@path)) @spec = @json.values.first say_status 'json', @path, :yellow @spec['url'] ||= {} @endpoint_name = @json.keys.first @full_namespace = __full_namespace @namespace_depth = @full_namespace.size > 0 ? @full_namespace.size - 1 : 0 @module_namespace = @full_namespace[0, @namespace_depth] @method_name = @full_namespace.last @parts = __endpoint_parts @params = @spec['params'] || {} @specific_params = specific_params(@module_namespace.first) # See EndpointSpecifics @http_method = __http_method @paths = @spec['url']['paths'].map { |b| b['path'] } # Using Ruby's safe operator on array: @deprecation_note = @spec['url']['paths'].last&.[]('deprecated') @http_path = __http_path @required_parts = __required_parts @module_namespace.shift if @module_namespace.first == 'xpack' @path_to_file = @output.join(@module_namespace.join('/')).join("#{@method_name}.rb") dir = @output.join(@module_namespace.join('/')) empty_directory(dir, verbose: false) # Write the file with the ERB template: template('templates/method.erb', @path_to_file, force: true) print_source_code(@path_to_file) if options[:verbose] generate_tests if options[:tests] puts end run_rubocop(api) end def __full_namespace names = @endpoint_name.split('.') if @current_api == :xpack names = (names.first == 'xpack' ? names : ['xpack', names].flatten) # Return an array to expand 'ccr', 'ilm', 'ml' and 'slm' names.map do |name| name .gsub(/^ml$/, 'machine_learning') .gsub(/^ilm$/, 'index_lifecycle_management') .gsub(/^ccr/, 'cross_cluster_replication') .gsub(/^slm/, 'snapshot_lifecycle_management') end else names end end # Create the hierarchy of directories based on API namespaces # def __create_directories(key, value) return if value['documentation'] empty_directory @output.join(key) create_directory_hierarchy * value.to_a.first end # Extract parts from each path # def __endpoint_parts parts = @spec['url']['paths'].select do |a| a.keys.include?('parts') end.map do |path| path&.[]('parts') end (parts.inject(&:merge) || []) end def __http_method return '_id ? Elasticsearch::API::HTTP_PUT : Elasticsearch::API::HTTP_POST' if @endpoint_name == 'index' return post_and_get if @endpoint_name == 'count' default_method = @spec['url']['paths'].map { |a| a['methods'] }.flatten.first if @spec['body'] && default_method == 'GET' # When default method is GET and body is required, we should always use POST if @spec['body']['required'] 'Elasticsearch::API::HTTP_POST' else post_and_get end else "Elasticsearch::API::HTTP_#{default_method}" end end def post_and_get <<~SRC if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end SRC end def __http_path return "\"#{__parse_path(@paths.first)}\"" if @paths.size == 1 return termvectors_path if @method_name == 'termvectors' result = '' anchor_string = [] @paths.sort { |a, b| b.length <=> a.length }.each_with_index do |path, i| var_string = __extract_path_variables(path).map { |var| "_#{var}" }.join(' && ') next if anchor_string.include? var_string anchor_string << var_string result += if i.zero? "if #{var_string}\n" elsif (i == @paths.size - 1) || var_string.empty? "else\n" else "elsif #{var_string}\n" end result += "\"#{__parse_path(path)}\"\n" end result += 'end' result end def __parse_path(path) path.gsub(/^\//, '') .gsub(/\/$/, '') .gsub('{', "\#{#{__utils}.__listify(_") .gsub('}', ')}') end def __path_variables @paths.map do |path| __extract_path_variables(path) end end # extract values that are in the {var} format: def __extract_path_variables(path) path.scan(/{(\w+)}/).flatten end # Find parts that are definitely required and should raise an error if # they're not present # def __required_parts required = [] return required if @endpoint_name == 'tasks.get' required << 'body' if (@spec['body'] && @spec['body']['required']) # Get required variables from paths: req_variables = __path_variables.inject(:&) # find intersection required << req_variables unless req_variables.empty? required.flatten end def docs_helper(name, info) info['type'] = 'String' if info['type'] == 'enum' # Rename 'enums' to 'strings' info['type'] = 'Integer' if info['type'] == 'int' # Rename 'int' to 'Integer' tipo = info['type'] ? info['type'].capitalize : 'String' description = info['description'] ? info['description'].strip : '[TODO]' options = info['options'] ? "(options: #{info['options'].join(', ').strip})" : nil required = info['required'] ? '(*Required*)' : '' deprecated = info['deprecated'] ? '*Deprecated*' : '' optionals = [required, deprecated, options].join(' ').strip "# @option arguments [#{tipo}] :#{name} #{description} #{optionals}\n" end def stability_doc_helper(stability) return if stability == 'stable' if stability == 'experimental' <<~MSG # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. MSG elsif stability == 'beta' <<~MSG # This functionality is in Beta and is subject to change. The design and # code is less mature than official GA features and is being provided # as-is with no warranties. Beta features are not subject to the support # SLA of official GA features. MSG else <<~MSG # This functionality is subject to potential breaking changes within a # minor version, meaning that your referencing code may break when this # library is upgraded. MSG end end def generate_tests copy_file 'templates/test_helper.rb', @output.join('test').join('test_helper.rb') @test_directory = @output.join('test/api').join(@module_namespace.join('/')) @test_file = @test_directory.join("#{@method_name}_test.rb") empty_directory @test_directory template 'templates/test.erb', @test_file print_source_code(@test_file) if options[:verbose] end def print_source_code(path_to_file) colorized_output = CodeRay.scan_file(path_to_file, :ruby).terminal lines = colorized_output.split("\n") formatted = lines.first + "\n" + lines[1, lines.size].map { |l| ' ' * 14 + l }.join("\n") say_status('ruby', formatted, :yellow) end def print_tree return unless `which tree > /dev/null 2>&1; echo $?`.to_i < 1 lines = `tree #{@output}`.split("\n") say_status('tree', lines.first + "\n" + lines[1, lines.size].map { |l| ' ' * 14 + l }.join("\n")) end def __utils @current_api == :xpack ? 'Elasticsearch::API::Utils' : 'Utils' end def run_rubocop(api) system("rubocop -c ./thor/.rubocop.yml --format autogenconf -x #{FilesHelper::output_dir(api)}") end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/generator/000077500000000000000000000000001462737751600271235ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/generator/endpoint_specifics.rb000066400000000000000000000135661462737751600333330ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module API # Handles specific exceptional parameters and code snippets that need to be # included in the generated code. This module is included in SourceGenerator # so its methods can be used from the ERB template (method.erb). This will # potentially be refactored into different templates. module EndpointSpecifics # Endpoints that need Utils.__rescue_from_not_found IGNORE_404 = %w[ exists indices.exists indices.exists_alias indices.exists_index_template indices.exists_template indices.exists_type ].freeze # Endpoints that need Utils.__rescue_from_not_found if the ignore # parameter is included COMPLEX_IGNORE_404 = %w[ delete get indices.flush_synced indices.delete indices.delete_index_template indices.delete_template security.get_role security.get_user snapshot.status snapshot.get snapshot.get_repository snapshot.delete_repository snapshot.delete update watcher.delete_watch ].freeze # Endpoints that need params[:h] listified H_PARAMS = %w[aliases allocation count health indices nodes pending_tasks recovery shards thread_pool].freeze # Function that adds the listified h param code def specific_params(namespace) params = [] if H_PARAMS.include?(@method_name) && namespace == 'cat' if @method_name == 'nodes' params << 'params[:h] = Utils.__listify(params[:h], escape: false) if params[:h]' else params << 'params[:h] = Utils.__listify(params[:h]) if params[:h]' end end params end def needs_ignore_404?(endpoint) IGNORE_404.include? endpoint end def needs_complex_ignore_404?(endpoint) COMPLEX_IGNORE_404.include? endpoint end def module_name_helper(name) return name.upcase if %w[sql ssl].include? name name.split('_').map(&:capitalize).join end def termvectors_path <<~SRC if _index && _type && _id "\#{Utils.__listify(_index)}/\#{Utils.__listify(_type)}/\#{Utils.__listify(_id)}/\#{endpoint}" elsif _index && _type "\#{Utils.__listify(_index)}/\#{Utils.__listify(_type)}/\#{endpoint}" elsif _index && _id "\#{Utils.__listify(_index)}/\#{endpoint}/\#{Utils.__listify(_id)}" else "\#{Utils.__listify(_index)}/\#{endpoint}" end SRC end def ping_perform_request <<~SRC begin perform_request(method, path, params, body, headers).status == 200 ? true : false rescue Exception => e if e.class.to_s =~ /NotFound|ConnectionFailed/ || e.message =~ /Not\s*Found|404|ConnectionFailed/i false else raise e end end SRC end def indices_stats_params_registry <<~SRC ParamsRegistry.register(:stats_params, [ #{@spec['params'].keys.map { |k| ":#{k}" }.join(",\n")} ].freeze) ParamsRegistry.register(:stats_parts, [ #{@parts['metric']['options'].push('metric').map { |k| ":#{k}" }.join(",\n")} ].freeze) SRC end def msearch_body_helper <<~SRC case when body.is_a?(Array) && body.any? { |d| d.has_key? :search } payload = body. inject([]) do |sum, item| meta = item data = meta.delete(:search) sum << meta sum << data sum end. map { |item| Elasticsearch::API.serializer.dump(item) } payload << "" unless payload.empty? payload = payload.join("\\n") when body.is_a?(Array) payload = body.map { |d| d.is_a?(String) ? d : Elasticsearch::API.serializer.dump(d) } payload << "" unless payload.empty? payload = payload.join("\\n") else payload = body end SRC end def msearch_template_body_helper <<~SRC case when body.is_a?(Array) payload = body.map { |d| d.is_a?(String) ? d : Elasticsearch::API.serializer.dump(d) } payload << "" unless payload.empty? payload = payload.join("\n") else payload = body end SRC end def bulk_body_helper <<~SRC if body.is_a? Array payload = Elasticsearch::API::Utils.__bulkify(body) else payload = body end SRC end def find_structure_body_helper bulk_body_helper end def bulk_doc_helper(info) <<~SRC # @option arguments [String|Array] :body #{info}. Array of Strings, Header/Data pairs, # or the conveniency "combined" format can be passed, refer to Elasticsearch::API::Utils.__bulkify documentation. SRC end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/generator/files_helper.rb000066400000000000000000000056511462737751600321200ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'pathname' require_relative '../../../lib/elasticsearch/api/version.rb' module Elasticsearch module API module FilesHelper PROJECT_PATH = File.join(File.dirname(__FILE__), '..') SRC_PATH = File.join(PROJECT_PATH, '..', '..', '..', 'tmp/rest-api-spec/api/') OSS_OUTPUT_DIR = '../../elasticsearch-api/lib/elasticsearch/api/actions'.freeze XPACK_OUTPUT_DIR = '../../elasticsearch-xpack/lib/elasticsearch/xpack/api/actions'.freeze TESTS_DIRECTORIES = { oss: "#{PROJECT_PATH}/../../../tmp/rest-api-spec/test/free", xpack: "#{PROJECT_PATH}/../../../tmp/rest-api-spec/test/platinum" }.freeze # Only get JSON files and remove hidden files def self.files(api) json_files = if api == :xpack xpack_files else Dir.entries(SRC_PATH) - xpack_files end json_files.reject do |file| File.extname(file) != '.json' || File.basename(file) == '_common.json' end.map { |file| "#{SRC_PATH}#{file}" } end XPACK_ENDPOINTS = [ 'autoscaling', 'cross_cluster_replication', 'ccr', 'data_frame_transform_deprecated', 'enrich', 'eql', 'fleet', 'ilm', 'logstash', 'migration', 'watcher', 'slm' ] XPACK_ENDPOINTS_REGEXP = /data_stream|ml_|reload_search_analyzers|transform|freeze|unfreeze/ def self.xpack_files xpack_tests = Dir.entries(TESTS_DIRECTORIES[:xpack]) Dir.entries(SRC_PATH).map do |entry| filename = entry.split('.').first next if filename == 'snapshot' if xpack_tests.include?(filename) || XPACK_ENDPOINTS.include?(filename) || entry.match?(XPACK_ENDPOINTS_REGEXP) entry end end.compact end # Path to directory to copy generated files def self.output_dir(api) api == :xpack ? Pathname(XPACK_OUTPUT_DIR) : Pathname(OSS_OUTPUT_DIR) end def self.gem_version regex = /([0-9]{1,2}\.[0-9x]{1,2})/ Elasticsearch::API::VERSION.match(regex)[0] end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/lister.rb000066400000000000000000000035761462737751600267770ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # encoding: UTF-8 require 'thor' require 'pathname' module Elasticsearch module API class Lister < Thor namespace 'api' DEFAULT_PATH = '../../tmp/elasticsearch/rest-api-spec/src/main/resources/rest-api-spec/api/'.freeze desc "list ", "List all the REST API endpoints from the JSON specification" method_option :verbose, type: :boolean, default: false, desc: 'Output more information' method_option :format, default: 'text', desc: 'Output format (text, json)' def list(directory = DEFAULT_PATH) input = Pathname(directory).join('*.json') apis = Dir[input.to_s].map do |f| File.basename(f, '.json') end.sort if options[:verbose] say_status 'Count', apis.size say '▬'*terminal_width end case options[:format] when 'text' apis.each { |a| puts "* #{a}" } when 'json' puts apis.inspect else puts "[!] ERROR: Unknown output format '#{options[:format]}'" exit(1) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/templates/000077500000000000000000000000001462737751600271335ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/templates/_documentation_top.erb000066400000000000000000000046501462737751600335240ustar00rootroot00000000000000<%# # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. %> <%- if @spec['documentation']['description'] -%> <%= ' '*(@namespace_depth+3) %># <%= @spec['documentation']['description'].gsub("\n", "\n#{' '*(@namespace_depth+3)}# ") -%> <%- else %> <%= ' '*(@namespace_depth+3) %># TODO: Description <%- end %> <%= stability_doc_helper(@spec['stability']) -%> <%= ' '*(@namespace_depth+3) %># <%- unless @parts.nil? || @parts.empty? %><%# URL parts -%> <%- @parts.each do |name, info| -%> <%= docs_helper(name, info) -%> <%- end -%> <%- end -%><%# Body -%> <%# URL parameters -%> <%- @params.each do |name, info| -%> <%= docs_helper(name, info) unless (!@parts.empty? && @parts.keys.include?(name)) -%> <%- end -%> # @option arguments [Hash] :headers Custom HTTP headers <%- if @spec['body'] -%> <%- if @method_name == 'bulk' -%> <%= bulk_doc_helper(@spec['body']['description']) -%> <%- else -%> <%= ' '*(@namespace_depth+1) + '# @option arguments [Hash] :body ' + (@spec['body']['description'] ? @spec['body']['description'].strip : 'TODO: Description') + (@spec['body']['required'] ? ' (*Required*)' : '') + "\n" -%> <%- end -%> <%- end -%> <% if @deprecation_note -%> # # *Deprecation notice*: # <%= @deprecation_note['description'] %> # Deprecated since version <%= @deprecation_note['version'] %> # <% end -%> <%= ' '*(@namespace_depth+3) -%># <%# Documentation link -%> <%= ' '*(@namespace_depth+3) %># @see <%= @spec['documentation']['url'] ? @spec['documentation']['url'].gsub(/\/(current|master)\//, "/#{Elasticsearch::API::FilesHelper.gem_version}/") : "[TODO]" %> <%= ' '*(@namespace_depth+3) %># elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/templates/_method_setup.erb000066400000000000000000000045151462737751600324710ustar00rootroot00000000000000<%# # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. %> <%- if @endpoint_name == 'indices.stats' %> method = HTTP_GET parts = Utils.__extract_parts arguments, ParamsRegistry.get(:stats_parts) path = Utils.__pathify Utils.__listify(arguments[:index]), '_stats', Utils.__listify(parts) params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(:stats_params) params[:fields] = Utils.__listify(params[:fields], :escape => false) if params[:fields] params[:groups] = Utils.__listify(params[:groups], :escape => false) if params[:groups] <%- else %> <%= ' '*(@namespace_depth+4) %>arguments = arguments.clone <%- if @method_name == 'mtermvectors' -%> ids = arguments.delete(:ids) <%- end -%> <%- if @method_name == 'search' -%> arguments[:index] = UNDERSCORE_ALL if ! arguments[:index] && arguments[:type] <%- end -%> <%- @parts.each do |name, _| %> <%- unless @method_name == 'get_field_mapping' && name == 'fields' %> <%= ' '*(@namespace_depth+3) + "_#{name}" %> = arguments.delete(:<%=name %>) <%- end -%> <%- end -%> <%= ' '*(@namespace_depth+4) %>method = <%= @http_method %> <%- if @method_name == 'termvectors' %> endpoint = arguments.delete(:endpoint) || '_termvectors' <%- end -%> <%= ' '*(@namespace_depth+4) %>path = <%= @http_path %> <%- unless @params.empty? -%> <%= ' '*(@namespace_depth+4) %>params = <%= __utils %>.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) <%- else -%> <%= ' '*(@namespace_depth+4) %>params = {} <%- end -%> <%- @specific_params.each do |param| -%> <%= param %> <%- end -%> <%- end -%> elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/templates/_params_registry.erb000066400000000000000000000025431462737751600332030ustar00rootroot00000000000000<%# # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. %> <%- unless @params.empty? -%> <%= ' '*(@namespace_depth+3) %># Register this action with its valid params when the module is loaded. <%= ' '*(@namespace_depth+3) %># <%= ' '*(@namespace_depth+3) %># @since 6.2.0 <%- if @endpoint_name == 'indices.stats' -%> <%= indices_stats_params_registry %> <%- else -%> <%= ' '*(@namespace_depth+3) %>ParamsRegistry.register(:<%= @method_name %>, [ <%= ' '*(@namespace_depth+4) %><%= @params.keys.map { |k| ":#{k}" }.join(",\n#{' '*(@namespace_depth+4)}") %> <%= ' '*(@namespace_depth+3) %>].freeze) <%- end -%> <%- end -%> elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/templates/_perform_request.erb000066400000000000000000000042361462737751600332130ustar00rootroot00000000000000<%# # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. %> <%- case @endpoint_name when 'mtermvectors' -%> if ids body = { :ids => ids } else body = arguments[:body] end <%- when 'cluster.reroute', 'cluster.put_settings' %> body = arguments[:body] || {} <%- when 'ml.find_file_structure' %> body = <%= __utils %>.__bulkify(arguments.delete(:body)) <%- else -%> <%= ' '*(@namespace_depth+3) %>body = <%= @spec['body'].nil? ? 'nil' : 'arguments[:body]' %> <%- end -%> <%- if ['bulk', 'msearch', 'msearch_template', 'find_structure'].include? @method_name -%> <%= self.send("#{@method_name}_body_helper".to_s) %> headers = <%= __utils %>.ndjson_headers(headers) <%= ' '*(@namespace_depth+4) %>perform_request(method, path, params, payload, headers).body <%- elsif @method_name == 'ping' -%> <%= ping_perform_request %> <%- else -%> <%- if needs_ignore_404?(@endpoint_name) %> <%= __utils %>.__rescue_from_not_found do perform_request(method, path, params, body, headers).status == 200 ? true : false end <%- elsif needs_complex_ignore_404?(@endpoint_name) -%> if Array(arguments[:ignore]).include?(404) <%= __utils %>.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end <%- else -%> perform_request(method, path, params, body, headers).body <%- end -%> <%- end -%> <%= ' '*(@namespace_depth+3) %>end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/templates/method.erb000066400000000000000000000057601462737751600311150ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch <%- if @current_api == :xpack -%> <%= ' '*(@namespace_depth) %>module XPack <%- end %> <%= ' '*(@namespace_depth) %>module API <%- @module_namespace.each_with_index do |name, i| -%> <%= ' '*i %>module <%= module_name_helper(name) %> <%- end -%> <%= ' '*(@namespace_depth+2) %>module Actions <%= ERB.new(File.new("./thor/templates/_documentation_top.erb").read, trim_mode: '-').result(binding) -%> <%# Method definition -%> <%= ' '*(@namespace_depth+3) -%>def <%= @method_name %>(arguments = {}) <%- if @endpoint_name == 'create' -%> <%= ' '*(@namespace_depth+3) %>if arguments[:id] <%= ' '*(@namespace_depth+3) %> index arguments.update op_type: 'create' <%= ' '*(@namespace_depth+3) %>else <%= ' '*(@namespace_depth+3) %> index arguments <%= ' '*(@namespace_depth+3) %>end <%= ' '*(@namespace_depth+2) %>end <%- else -%> <%- if @method_name == 'get_field_mapping' %> _fields = arguments.delete(:field) || arguments.delete(:fields) raise ArgumentError, "Required argument 'field' missing" unless _fields <%- else -%> <%- @required_parts.each do |required| %><%# Arguments -%> <%= ' '*(@namespace_depth+3) + "raise ArgumentError, \"Required argument '#{required}' missing\" unless arguments[:#{required}]" + "\n" -%> <%- end -%> <%- end -%> headers = arguments.delete(:headers) || {} <%- # Method setup -%> <%= ERB.new(File.new("./thor/templates/_method_setup.erb").read, trim_mode: '-').result(binding) %> <%- # Perform request -%> <%= ERB.new(File.new("./thor/templates/_perform_request.erb").read, trim_mode: '-').result(binding) %> <%- end -%> <%- if @method_name.match?(/^exists\S*/) -%> alias_method :<%= @method_name %>?, :<%= @method_name %> <%- end -%> <%- if @method_name == 'termvectors' %> # Deprecated: Use the plural version, {#termvectors} # def termvector(arguments={}) termvectors(arguments.merge endpoint: '_termvector') end <%- end -%> <%# Params Registry Template -%> <%- unless @endpoint_name == 'create' -%> <%= ERB.new(File.new("./thor/templates/_params_registry.erb").read, trim_mode: '-').result(binding) %> <%- end -%> <%- @namespace_depth.downto(1) do |i| -%> <%= ' '*(i-1) %>end <%- end if @namespace_depth > 0 -%> end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/templates/test.erb000066400000000000000000000034021462737751600306030ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class <%= @module_namespace.map {|n| n.capitalize}.map { |n| n == 'Xpack' ? 'XPack' : n }.join('') + @method_name.camelize %>Test < ::Test::Unit::TestCase context "<%= @module_namespace.map {|n| n.capitalize}.map { |n| n == 'Xpack' ? 'XPack' : n }.join(' ') + ': ' %><%= @method_name.humanize %>" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'FAKE', method assert_equal 'test', url assert_equal Hash.new, params <%= @spec['body'].nil? ? 'assert_nil body' : 'assert_equal Hash.new, body' %> true end.returns(FakeResponse.new) subject.<%= @full_namespace.join('.') %> <%= @spec['url']['parts'].select { |name, info| info['required'] }.keys.map { |d| ":#{d} => 'foo'" }.join(', ') rescue '' %> end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-api/utils/thor/templates/test_helper.rb000066400000000000000000000045671462737751600320120ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'simplecov' and SimpleCov.start { add_filter "/test|test_/" } if ENV["COVERAGE"] require 'test/unit' require 'shoulda-context' require 'mocha/setup' require 'require-prof' if ENV["REQUIRE_PROF"] Dir[ File.expand_path('../../lib/elasticsearch/api/**/*.rb', __FILE__) ].each do |f| puts 'Loading: ' + f.to_s if ENV['DEBUG'] require f end RequireProf.print_timing_infos if ENV["REQUIRE_PROF"] module Elasticsearch module Utils def __validate_and_extract_params(*args) {} end extend self end module Test def __full_namespace(o) o.constants.inject([o]) do |sum, c| m = o.const_get(c.to_s.to_sym) sum << __full_namespace(m).flatten if m.is_a?(Module) sum end.flatten end; module_function :__full_namespace module Namespace def cluster self end end class FakeClient # Include all "Actions" modules into the fake client Elasticsearch::Test.__full_namespace(Elasticsearch::API).select { |m| m.to_s =~ /Actions$/ }.each do |m| puts "Including: #{m}" if ENV['DEBUG'] include m end # Include the fake "namespace" methods in the client include Namespace def perform_request(method, path, params, body) puts "PERFORMING REQUEST:", "--> #{method.to_s.upcase} #{path} #{params} #{body}" FakeResponse.new(200, 'FAKE', {}) end end FakeResponse = Struct.new(:status, :body, :headers) do def status values[0] || 200 end def body values[1] || '{}' end def headers values[2] || {} end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/000077500000000000000000000000001462737751600230325ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/.gitignore000066400000000000000000000002321462737751600250170ustar00rootroot00000000000000*.gem *.rbc .bundle .config .yardoc Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/Gemfile000066400000000000000000000033461462737751600243330ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. source 'https://rubygems.org' # Specify your gem's dependencies in elasticsearch-dsl.gemspec gemspec if File.exist? File.expand_path('../../elasticsearch/elasticsearch.gemspec', __FILE__) gem 'elasticsearch', path: File.expand_path('../../elasticsearch', __FILE__), require: false end if File.exist? File.expand_path('../../elasticsearch-transport', __FILE__) gem 'elasticsearch-transport', path: File.expand_path('../../elasticsearch-transport', __FILE__), require: true end if File.exist? File.expand_path('../../elasticsearch-api', __FILE__) gem 'elasticsearch-api', path: File.expand_path('../../elasticsearch-api', __FILE__), require: false end if File.exist? File.expand_path('../../elasticsearch-extensions', __FILE__) gem 'elasticsearch-extensions', path: File.expand_path('../../elasticsearch-extensions', __FILE__), require: false end group :development do gem 'rspec' if defined?(JRUBY_VERSION) gem 'pry-nav' else gem 'pry-byebug', '~> 3.9' end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/LICENSE000066400000000000000000000261361462737751600240470ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/README.md000066400000000000000000000175371462737751600243260ustar00rootroot00000000000000# Elasticsearch::DSL The `elasticsearch-dsl` library provides a Ruby API for the [Elasticsearch Query DSL](http://www.elasticsearch.com/guide/en/elasticsearch/reference/current/query-dsl.html). The library is compatible with Ruby 1.9 or higher and Elasticsearch 1.0 and higher. ## Installation Install the package from [Rubygems](https://rubygems.org): gem install elasticsearch-dsl To use an unreleased version, either add it to your `Gemfile` for [Bundler](http://gembundler.com): gem 'elasticsearch-dsl', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git' or install it from a source code checkout: git clone https://github.com/elasticsearch/elasticsearch-ruby.git cd elasticsearch-ruby/elasticsearch-dsl bundle install rake install ## Usage The library is designed as a group of standalone Ruby modules, classes and DSL methods, which provide an idiomatic way to build complex [search definitions](http://www.elasticsearch.com/guide/en/elasticsearch/reference/current/search-request-body.html). Let's have a simple example using the declarative variant: ```ruby require 'elasticsearch/dsl' include Elasticsearch::DSL definition = search do query do match title: 'test' end end definition.to_hash # => { query: { match: { title: "test"} } } require 'elasticsearch' client = Elasticsearch::Client.new trace: true client.search body: definition # curl -X GET 'http://localhost:9200/test/_search?pretty' -d '{ # "query":{ # "match":{ # "title":"test" # } # } # }' # ... # => {"took"=>10, "hits"=> {"total"=>42, "hits"=> [...] } } ``` Let's build the same definition in a more imperative fashion: ```ruby require 'elasticsearch/dsl' include Elasticsearch::DSL definition = Search::Search.new definition.query = Search::Queries::Match.new title: 'test' definition.to_hash # => { query: { match: { title: "test"} } } ``` The library doesn't depend on an Elasticsearch client -- its sole purpose is to facilitate building search definitions in Ruby. This makes it possible to use it with any Elasticsearch client: ```ruby require 'elasticsearch/dsl' include Elasticsearch::DSL definition = search { query { match title: 'test' } } require 'json' require 'faraday' client = Faraday.new(url: 'http://localhost:9200') response = JSON.parse( client.post( '/_search', JSON.dump(definition.to_hash), { 'Accept' => 'application/json', 'Content-Type' => 'application/json' } ).body ) # => {"took"=>10, "hits"=> {"total"=>42, "hits"=> [...] } } ``` ## Features Overview The library allows to programatically build complex search definitions for Elasticsearch in Ruby, which are translated to Hashes, and ultimately, JSON, the language of Elasticsearch. All Elasticsearch DSL features are supported, namely: * [Queries and Filter context](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html) * [Aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html) * [Suggestions](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html) * [Sorting](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#request-body-search-sort) * [Pagination](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#request-body-search-from-size) * [Options](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html) (source filtering, highlighting, etc) An example of a complex search definition is below. **NOTE:** In order to run the example, you have to allow restoring from the `data.elasticsearch.org` repository by adding the following configuration line to your `elasticsearch.yml`: ```yaml repositories.url.allowed_urls: ["https://s3.amazonaws.com/data.elasticsearch.com/*"] ``` ```ruby require 'awesome_print' require 'elasticsearch' require 'elasticsearch/dsl' include Elasticsearch::DSL client = Elasticsearch::Client.new transport_options: { request: { timeout: 3600, open_timeout: 3600 } } puts "Recovering the 'bicycles.stackexchange.com' index...".yellow client.indices.delete index: 'bicycles.stackexchange.com', ignore: 404 client.snapshot.create_repository repository: 'data.elasticsearch.com', body: { type: 'url', settings: { url: 'https://s3.amazonaws.com/data.elasticsearch.com/bicycles.stackexchange.com/' } } client.snapshot.restore repository: 'data.elasticsearch.com', snapshot: 'bicycles.stackexchange.com', body: { indices: 'bicycles.stackexchange.com' } until client.cluster.health(level: 'indices')['indices']['bicycles.stackexchange.com']['status'] == 'green' r = client.indices.recovery(index: 'bicycles.stackexchange.com', human: true)['bicycles.stackexchange.com']['shards'][0] rescue nil print "\r#{r['index']['size']['recovered'] rescue '0b'} of #{r['index']['size']['total'] rescue 'N/A'}".ljust(52).gray sleep 1 end; puts # The search definition # definition = search { query do # Use a `function_score` query to modify the default score # function_score do query do filtered do # Use a `multi_match` query for the fulltext part of the search # query do multi_match do query 'fixed fixie' operator 'or' fields %w[ title^10 body ] end end # Use a `range` filter on the `creation_date` field # filter do range :creation_date do gte '2013-01-01' end end end end # Multiply the default `_score` by the document rating # functions << { script_score: { script: '_score * doc["rating"].value' } } end end # Calculate the most frequently used tags # aggregation :tags do terms do field 'tags' # Calculate average view count per tag (inner aggregation) # aggregation :avg_view_count do avg field: 'view_count' end end end # Calculate the posting frequency # aggregation :frequency do date_histogram do field 'creation_date' interval 'month' format 'yyyy-MM' # Calculate the statistics on comment count per day (inner aggregation) # aggregation :comments do stats field: 'comment_count' end end end # Calculate the statistical information about the number of comments # aggregation :comment_count_stats do stats field: 'comment_count' end # Highlight the `title` and `body` fields # highlight fields: { title: { fragment_size: 50 }, body: { fragment_size: 50 } } # Return only a selection of the fields # source ['title', 'tags', 'creation_date', 'rating', 'user.location', 'user.display_name'] } puts "Search definition #{'-'*63}\n".yellow ap definition.to_hash # Execute the search request # response = client.search index: 'bicycles.stackexchange.com', type: ['question','answer'], body: definition puts "\nSearch results #{'-'*66}\n".yellow ap response ``` NOTE: You have to enable dynamic scripting to be able to execute the `function_score` query, either by adding `script.disable_dynamic: false` to your elasticsearch.yml or command line parameters. **Please see the extensive RDoc examples in the source code and the integration tests.** ## Development To work on the code, clone the repository and install the dependencies: ``` git clone https://github.com/elasticsearch/elasticsearch-ruby.git cd elasticsearch-ruby/elasticsearch-dsl/ bundle install ``` Use the Rake tasks to run the test suites: ``` bundle exec rake test:unit bundle exec rake test:integration ``` To launch a separate Elasticsearch server for integration tests, see instructions in the main [README](../README.md#development). ## License This software is licensed under the [Apache 2 license](./LICENSE). elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/Rakefile000066400000000000000000000175421462737751600245100ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require "bundler/gem_tasks" task(:default) { system "rake --tasks" } task :test => 'test:unit' # ----- Test tasks ------------------------------------------------------------ require 'rake/testtask' require 'rspec/core/rake_task' namespace :test do desc "Wait for Elasticsearch to be in a green state" task :wait_for_green do sh '../scripts/wait-cluster.sh' end RSpec::Core::RakeTask.new(:spec) Rake::TestTask.new(:unit) do |test| test.libs << 'lib' << 'test' test.test_files = FileList["test/unit/**/*_test.rb"] test.deps = [ :spec ] test.verbose = false test.warning = false end Rake::TestTask.new(:integration) do |test| test.deps = [ :wait_for_green ] test.libs << 'lib' << 'test' test.test_files = FileList["test/integration/**/*_test.rb"] test.verbose = false test.warning = false end desc "Run unit and integration tests" task :all do Rake::Task['test:unit'].invoke Rake::Task['test:integration'].invoke end namespace :cluster do desc "Start Elasticsearch nodes for tests" task :start do $LOAD_PATH << File.expand_path('../../elasticsearch-transport/lib', __FILE__) << File.expand_path('../test', __FILE__) require 'elasticsearch/extensions/test/cluster' Elasticsearch::Extensions::Test::Cluster.start end desc "Stop Elasticsearch nodes for tests" task :stop do $LOAD_PATH << File.expand_path('../../elasticsearch-transport/lib', __FILE__) << File.expand_path('../test', __FILE__) require 'elasticsearch/extensions/test/cluster' Elasticsearch::Extensions::Test::Cluster.stop end end end # ----- Documentation tasks --------------------------------------------------- require 'yard' YARD::Rake::YardocTask.new(:doc) do |t| t.options = %w| --embed-mixins --markup=markdown | end # ----- Code analysis tasks --------------------------------------------------- require 'cane/rake_task' Cane::RakeTask.new(:quality) do |cane| cane.abc_max = 15 cane.no_style = true end # ----- Generating the source code -------------------------------------------- require 'net/http' require 'json' require 'coderay' namespace :generate do desc <<-DESC.gsub(/^ /, '') Generate Ruby source and tests for query/filter/aggregation Pass the type of the component, the name, and any option methods as Rake task arguments. Example: $ rake generate:source[query,boosting] Source: /.../elasticsearch-ruby/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/boosting.rb ... Test: /.../elasticsearch-ruby/elasticsearch-dsl/test/unit/queries/boosting_test.rb ... $ rake generate:source[query,common,query/cutoff_frequency/low_freq_operator/...] Source: /.../elasticsearch-ruby/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/common.rb ... Test: /.../elasticsearch-ruby/elasticsearch-dsl/test/unit/queries/common_test.rb ... DESC task :source, [:type, :name, :option_methods] do |task, options| begin query = URI.escape("#{options[:name]} #{options[:type]}") response = Net::HTTP.get('search.elasticsearch.org', "/search/?q=#{query}") hits = JSON.load(response)['hits']['hits'] if hit = hits.first doc_url = ("http://elasticsearch.org" + hit['fields']['url']).gsub(/#.+$/, '') if hit['_score'] > 0.2 end rescue Exception => e puts "[!] ERROR: #{e.inspect}" end unless ENV['NOCRAWL'] case options[:type] when /query/ module_name = 'Queries' path_name = 'queries' include_module = 'BaseComponent' when /filter/ module_name = 'Filters' path_name = 'filters' include_module = 'BaseComponent' when /agg/ module_name = 'Aggregations' path_name = 'aggregations' include_module = 'BaseAggregationComponent' else raise ArgumentError, "Unknown DSL type [#{options[:type]}]" end name = options[:name].downcase class_name = options[:name].split('_').map(&:capitalize).join option_methods = options[:option_methods].to_s.split('/').reduce('') do |sum, item| sum << " " sum << "option_method :#{item}" sum << "\n" unless item == options[:option_methods].to_s.split('/').last sum end option_methods = "\n\n#{option_methods}" unless option_methods.empty? source = <<-RUBY.gsub(/^ /, '') module Elasticsearch module DSL module Search module #{module_name} # #{class_name} #{options[:type]} # # @example # # @see #{doc_url} # class #{class_name} include #{include_module}#{option_methods} end end end end end RUBY if options[:option_methods].to_s.empty? test_option_methods = '' else setup = "\n" + options[:option_methods].to_s.split('/').reduce('') do |sum,item| sum << " subject.#{item} 'bar'\n"; sum end asserts = "\n assert_equal %w[ #{options[:option_methods].to_s.split('/').sort.join(' ')} ],\n subject.to_hash[:#{name}][:foo].keys.map(&:to_s).sort" asserts << "\n assert_equal 'bar', subject.to_hash[:#{name}][:foo][:#{options[:option_methods].to_s.split('/').first}]" test_option_methods = <<-RUBY.gsub(/^ /, '') should "have option methods" do subject = #{class_name}.new :foo #{setup}#{asserts} end should "take a block" do subject = #{class_name}.new :foo do #{options[:option_methods].to_s.split('/').first} 'bar' end assert_equal({#{name}: { foo: { #{options[:option_methods].to_s.split('/').first}: 'bar' } }}, subject.to_hash) end RUBY end test = <<-RUBY.gsub(/^ /, '') require 'test_helper' module Elasticsearch module Test module #{module_name} class #{class_name}Test < ::Elasticsearch::Test::UnitTestCase include Elasticsearch::DSL::Search::#{module_name} context "#{class_name} #{options[:type]}" do subject { #{class_name}.new } should "be converted to a Hash" do assert_equal({ #{name}: {} }, subject.to_hash) end #{test_option_methods.empty? ? '' : test_option_methods.split("\n").map { |l| ' ' + l }.join("\n")} end end end end end RUBY source_full_path = File.expand_path("../lib/elasticsearch/dsl/search/#{path_name}/#{name}.rb", __FILE__) test_full_path = File.expand_path("../test/unit/#{path_name}/#{name}_test.rb", __FILE__) puts '-'*80, "Source: #{source_full_path}", '-'*80, "\n", CodeRay.scan(source, :ruby).terminal, "\n\n" puts '-'*80, "Test: #{test_full_path}", '-'*80, "\n", CodeRay.scan(test, :ruby).terminal, "\n" File.open(source_full_path, 'w') { |file| file << source } File.open(test_full_path, 'w') { |file| file << test } end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/elasticsearch-dsl.gemspec000066400000000000000000000053471462737751600300020ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'elasticsearch/dsl/version' Gem::Specification.new do |s| s.name = 'elasticsearch-dsl' s.version = Elasticsearch::DSL::VERSION s.authors = ['Karel Minarik'] s.email = ['karel.minarik@elasticsearch.com'] s.description = %q{A Ruby DSL builder for Elasticsearch} s.summary = s.description s.homepage = 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.x/index.html' s.license = 'Apache-2.0' s.metadata = { 'homepage_uri' => 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.x/index.html', 'changelog_uri' => 'https://github.com/elastic/elasticsearch-ruby/blob/7.x/CHANGELOG.md', 'source_code_uri' => 'https://github.com/elastic/elasticsearch-ruby/tree/7.x/elasticsearch-dsl', 'bug_tracker_uri' => 'https://github.com/elastic/elasticsearch-ruby/issues' } s.files = `git ls-files`.split($/) s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } s.test_files = s.files.grep(%r{^(test|spec|features)/}) s.require_paths = ['lib'] s.extra_rdoc_files = [ 'README.md', 'LICENSE' ] s.rdoc_options = [ '--charset=UTF-8' ] s.required_ruby_version = '>= 2.4' s.add_development_dependency 'bundler' s.add_development_dependency 'rake', '~> 13' s.add_development_dependency 'elasticsearch' s.add_development_dependency 'elasticsearch-extensions' s.add_development_dependency 'cane' s.add_development_dependency 'minitest', '~> 5' s.add_development_dependency 'minitest-reporters', '~> 1' s.add_development_dependency 'mocha' s.add_development_dependency 'pry' s.add_development_dependency 'shoulda-context' s.add_development_dependency 'simplecov', '~> 0.17', '< 0.18' s.add_development_dependency 'yard' if defined?(RUBY_VERSION) && RUBY_VERSION > '2.2' s.add_development_dependency 'test-unit', '~> 2' end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/000077500000000000000000000000001462737751600236005ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch-dsl.rb000066400000000000000000000014441462737751600275220ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'elasticsearch/dsl' elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/000077500000000000000000000000001462737751600264125ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl.rb000066400000000000000000000043331462737751600275240ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'elasticsearch/dsl/version' require 'elasticsearch/dsl/utils' require 'elasticsearch/dsl/search/base_component' require 'elasticsearch/dsl/search/base_compound_filter_component' require 'elasticsearch/dsl/search/base_aggregation_component' require 'elasticsearch/dsl/search/query' require 'elasticsearch/dsl/search/filter' require 'elasticsearch/dsl/search/aggregation' require 'elasticsearch/dsl/search/highlight' require 'elasticsearch/dsl/search/sort' require 'elasticsearch/dsl/search/options' require 'elasticsearch/dsl/search/suggest' Dir[ File.expand_path('../dsl/search/queries/**/*.rb', __FILE__) ].each { |f| require f } Dir[ File.expand_path('../dsl/search/filters/**/*.rb', __FILE__) ].each { |f| require f } Dir[ File.expand_path('../dsl/search/aggregations/**/*.rb', __FILE__) ].each { |f| require f } require 'elasticsearch/dsl/search' module Elasticsearch # The main module, which can be included into your own class or namespace, # to provide the DSL methods. # # @example # # include Elasticsearch::DSL # # definition = search do # query do # match title: 'test' # end # end # # definition.to_hash # # => { query: { match: { title: "test"} } } # # @see Search # @see https://www.elastic.co/guide/en/elasticsearch/guide/current/query-dsl-intro.html # module DSL def self.included(base) base.__send__ :include, Elasticsearch::DSL::Search end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/000077500000000000000000000000001462737751600271745ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search.rb000066400000000000000000000172171462737751600307760ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL # Provides DSL methods for building the search definition # (queries, filters, aggregations, sorting, etc) # module Search # Initialize a new Search object # # @example Building a search definition declaratively # # definition = search do # query do # match title: 'test' # end # end # definition.to_hash # => {:query=>{:match=>{:title=>"test"}}} # # @example Using the class imperatively # # definition = Search.new # query = Queries::Match.new title: 'test' # definition.query query # definition.to_hash # # => {:query=>{:match=>{:title=>"test"}}} # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html # def search(*args, &block) Search.new(*args, &block) end extend self # Wraps the whole search definition (queries, filters, aggregations, sorting, etc) # class Search attr_reader :aggregations def initialize(*args, &block) @options = Options.new *args block.arity < 1 ? self.instance_eval(&block) : block.call(self) if block end # DSL method for building or accessing the `query` part of a search definition # # @return [self, {Query}] # def query(*args, &block) case when block @query = Query.new(*args, &block) self when !args.empty? @query = args.first self else @query end end # Set the query part of a search definition # def query=(value) query value end # DSL method for building the `filter` part of a search definition # # @return [self] # def filter(*args, &block) case when block @filter = Filter.new(*args, &block) self when !args.empty? @filter = args.first self else @filter end end # Set the filter part of a search definition # def filter=(value) filter value end # DSL method for building the `post_filter` part of a search definition # # @return [self] # def post_filter(*args, &block) case when block @post_filter = Filter.new(*args, &block) self when !args.empty? @post_filter = args.first self else @post_filter end end # Set the post_filter part of a search definition # def post_filter=(value) post_filter value end # DSL method for building the `aggregations` part of a search definition # # @return [self] # def aggregation(*args, &block) @aggregations ||= AggregationsCollection.new if block @aggregations.update args.first => Aggregation.new(*args, &block) else name = args.shift @aggregations.update name => args.shift end self end # Set the aggregations part of a search definition # def aggregations=(value) @aggregations = value end # DSL method for building the `highlight` part of a search definition # # @return [self] # def highlight(*args, &block) if !args.empty? || block @highlight = Highlight.new(*args, &block) self else @highlight end end # DSL method for building the `sort` part of a search definition # # @return [self] # def sort(*args, &block) if !args.empty? || block @sort = Sort.new(*args, &block) self else @sort end end # Set the sort part of a search definition # def sort=(value) @sort = value end # DSL method for building the `stored_fields` part of a search definition # # @return [self] # def stored_fields(value=nil) if value @stored_fields = value self else @stored_fields end end; alias_method :stored_fields=, :stored_fields # DSL method for building the `size` part of a search definition # # @return [self] # def size(value=nil) if value @size = value self else @size end end; alias_method :size=, :size # DSL method for building the `from` part of a search definition # # @return [self] # def from(value=nil) if value @from = value self else @from end end; alias_method :from=, :from # DSL method for building the `suggest` part of a search definition # # @return [self] # def suggest(*args, &block) if !args.empty? || block @suggest ||= {} key, options = args @suggest.update key => Suggest.new(key, options, &block) self else @suggest end end # Set the suggest part of a search definition # def suggest=(value) @suggest = value end # Delegates to the methods provided by the {Options} class # def method_missing(name, *args, &block) if @options.respond_to? name @options.__send__ name, *args, &block self else super end end # Converts the search definition to a Hash # # @return [Hash] # def to_hash hash = {} hash.update(query: @query.to_hash) if @query hash.update(filter: @filter.to_hash) if @filter hash.update(post_filter: @post_filter.to_hash) if @post_filter hash.update(aggregations: @aggregations.reduce({}) { |sum,item| sum.update item.first => item.last.to_hash }) if @aggregations hash.update(sort: @sort.to_hash) if @sort hash.update(size: @size) if @size hash.update(stored_fields: @stored_fields) if @stored_fields hash.update(from: @from) if @from hash.update(suggest: @suggest.reduce({}) { |sum,item| sum.update item.last.to_hash }) if @suggest hash.update(highlight: @highlight.to_hash) if @highlight hash.update(@options) unless @options.empty? hash end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/000077500000000000000000000000001462737751600304415ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregation.rb000066400000000000000000000055471462737751600332700ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search # Contains the classes for Elasticsearch aggregations # module Aggregations;end class AggregationsCollection < Hash def to_hash @hash ||= Hash[map { |k,v| [k, v.to_hash] }] end end # Wraps the `aggregations` part of a search definition # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html # class Aggregation def initialize(*args, &block) @block = block end # Looks up the corresponding class for a method being invoked, and initializes it # # @raise [NoMethodError] When the corresponding class cannot be found # def method_missing(name, *args, &block) klass = Utils.__camelize(name) if Aggregations.const_defined? klass @value = Aggregations.const_get(klass).new *args, &block else raise NoMethodError, "undefined method '#{name}' for #{self}" end end # Defines an aggregation nested in another one # def aggregation(*args, &block) call @value.__send__ :aggregation, *args, &block end # Returns the aggregations # def aggregations call @value.__send__ :aggregations end # Evaluates the block passed to initializer, ensuring it is called just once # # @return [self] # # @api private # def call @block.arity < 1 ? self.instance_eval(&@block) : @block.call(self) if @block && ! @_block_called @_block_called = true self end # Converts the object to a Hash # # @return [Hash] # def to_hash(options={}) call if @value case when @value.respond_to?(:to_hash) @value.to_hash else @value end else {} end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/000077500000000000000000000000001462737751600331135ustar00rootroot00000000000000avg.rb000066400000000000000000000025261462737751600341430ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A single-value metric aggregation which returns the average of numeric values # # @example # # search do # aggregation :avg_clicks do # avg field: 'clicks' # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-avg-aggregation.html # class Avg include BaseComponent end end end end end cardinality.rb000066400000000000000000000030711462737751600356650ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A single-value metric aggregation which returns the approximate count of distinct values # # @example # # search do # aggregation :authors do # cardinality do # field 'author' # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html # class Cardinality include BaseComponent option_method :field option_method :precision_threshold option_method :rehash option_method :script option_method :params end end end end end children.rb000066400000000000000000000035551462737751600351610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A single-bucket aggregation which allows to aggregate from buckets on parent documents # to buckets on the children documents # # @example Return the top commenters per article category # # search do # aggregation :top_categories do # terms field: 'category' do # aggregation :comments do # children type: 'comment' do # aggregation :top_authors do # terms field: 'author' # end # end # end # end # end # end # # # See the integration test for a full example. # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-children-aggregation.html # class Children include BaseAggregationComponent option_method :type end end end end end composite.rb000066400000000000000000000036761462737751600353770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # # A multi-bucket aggregation that creates composite buckets from different sources. # # @example # # search do # aggregation :things do # composite do # size 2000 # sources [ # { thing1: { terms: { field: 'thing1.field1' } } }, # { thing2: { terms: { field: 'thing2.field2' } } } # ] # after after_key # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-composite-aggregation.html # class Composite include BaseAggregationComponent option_method :size option_method :sources option_method :after def to_hash(_options={}) super # remove :after if no value is given @hash[name.to_sym].delete(:after) if @hash[name.to_sym].is_a?(Hash) && @hash[name.to_sym][:after].nil? @hash end end end end end end date_histogram.rb000066400000000000000000000035551462737751600363630ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A multi-bucket aggregation which returns a histogram for date fields # # @example # # search do # aggregation :daily do # field 'published_at' # interval 'day' # format 'yyyy-MM-dd' # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html # class DateHistogram include BaseAggregationComponent option_method :field option_method :interval option_method :pre_zone option_method :post_zone option_method :time_zone option_method :pre_zone_adjust_large_interval option_method :pre_offset option_method :post_offset option_method :format option_method :min_doc_count option_method :extended_bounds option_method :order end end end end end date_range.rb000066400000000000000000000032741462737751600354600ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A multi-bucket aggregation which returns document counts for custom date ranges # # @example # # search do # aggregation :compare_to_last_year do # date_range do # field 'published_at' # ranges [ # { from: 'now-1M/M', to: 'now/M' }, # { from: 'now-13M/M', to: 'now-12M/M' } # ] # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-daterange-aggregation.html # class DateRange include BaseAggregationComponent option_method :field option_method :format option_method :ranges end end end end end extended_stats.rb000066400000000000000000000026161462737751600364040ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A multi-value metrics aggregation which returns the extended statistical information on numeric values # # @example # # search do # aggregation :clicks_stats do # extended_stats field: 'clicks' # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-extendedstats-aggregation.html # class ExtendedStats include BaseComponent end end end end end filter.rb000066400000000000000000000030561462737751600346520ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # Defines a single bucket with documents matching the provided filter, # usually to define scope for a nested aggregation # # @example # # search do # aggregation :clicks_for_tag_one do # filter terms: { tags: ['one'] } do # aggregation :sum_clicks do # sum field: 'clicks' # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filters-aggregation.html # class Filter include BaseAggregationComponent end end end end end filters.rb000066400000000000000000000033271462737751600350360ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A multi-bucket aggregation which defines multiple buckets matching the provided filters, # usually to define scope for a nested aggregation # # @example # # search do # aggregation :avg_clicks_per_tag_one_and_two do # filters do # filters one: { terms: { tags: ['one'] } }, # two: { terms: { tags: ['two'] } } # # aggregation :avg do # avg field: 'clicks' # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filters-aggregation.html # class Filters include BaseAggregationComponent option_method :filters end end end end end geo_bounds.rb000066400000000000000000000036171462737751600355140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # An aggregation which will calculate the smallest bounding box required to encapsulate # all of the documents matching the query # # @example # # search do # query do # filtered do # filter do # geo_bounding_box :location do # top_left "40.8,-74.1" # bottom_right "40.4,-73.9" # end # end # end # end # # aggregation :new_york do # geohash_grid field: 'location' # end # # aggregation :map_zoom do # geo_bounds field: 'location' # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/guide/current/geo-bounds-agg.html # class GeoBounds include BaseComponent option_method :field option_method :wrap_longitude end end end end end geo_distance.rb000066400000000000000000000035021462737751600360050ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A multi-bucket aggregation which will return document counts for distance perimeters, # defined as ranges # # @example # # search do # aggregation :venue_distances do # geo_distance do # field :location # origin '38.9126352,1.4350621' # unit 'km' # ranges [ { to: 1 }, { from: 1, to: 5 }, { from: 5, to: 10 }, { from: 10 } ] # end # end # end # # See the integration test for a full example. # # @see http://elasticsearch.org/guide/en/elasticsearch/guide/current/geo-distance-agg.html # class GeoDistance include BaseAggregationComponent option_method :field option_method :origin option_method :ranges option_method :unit option_method :distance_type end end end end end geohash_grid.rb000066400000000000000000000031711462737751600360060ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A multi-bucket aggregation which will return document counts for geohash grid cells # # @example # # search do # aggregation :venue_distributions do # geohash_grid do # field :location # precision 5 # end # end # end # # See the integration test for a full example. # # @see http://elasticsearch.org/guide/en/elasticsearch/guide/current/geohash-grid-agg.html # class GeohashGrid include BaseAggregationComponent option_method :field option_method :precision option_method :size option_method :shard_size end end end end end global.rb000066400000000000000000000027241462737751600346260ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # Defines a single bucket of all the documents matching a query # # @example # # search do # aggregation :all_documents do # global do # aggregation :avg_clicks do # avg field: 'clicks' # end # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-global-aggregation.html # class Global include BaseAggregationComponent end end end end end histogram.rb000066400000000000000000000032111462737751600353530ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A multi-bucket aggregation which returns document counts for a defined numerical interval # # @example # # search do # aggregation :age do # histogram do # field 'age' # interval 5 # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-histogram-aggregation.html # class Histogram include BaseAggregationComponent option_method :field option_method :interval option_method :min_doc_count option_method :extended_bounds option_method :order option_method :keyed end end end end end ip_range.rb000066400000000000000000000030411462737751600351430ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A multi-bucket aggregation which returns document counts for defined IP ranges # # @example # # search do # aggregation :ips do # ip_range do # field 'ip' # ranges [ { mask: '10.0.0.0/25' }, { mask: '10.0.0.127/25' } ] # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-iprange-aggregation.html # class IpRange include BaseAggregationComponent option_method :field option_method :ranges end end end end end max.rb000066400000000000000000000025361462737751600341540ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A single-value metric aggregation which returns the maximum value from numeric values # # @example # # search do # aggregation :max_clicks do # max field: 'clicks' # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-max-aggregation.html # class Max include BaseComponent end end end end end min.rb000066400000000000000000000025361462737751600341520ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A single-value metric aggregation which returns the minimum value from numeric values # # @example # # search do # aggregation :min_clicks do # min field: 'clicks' # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-min-aggregation.html # class Min include BaseComponent end end end end end missing.rb000066400000000000000000000032651462737751600350400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A single bucket aggregation that creates a bucket of all documents # which are missing a value for the field # # @example Passing the options as a Hash # # aggregation :articles_without_tags do # missing field: 'tags' # end # # @example Passing the options as a block # # search do # aggregation :articles_without_tags do # missing do # field 'tags' # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/master/search-aggregations-bucket-missing-aggregation.html # class Missing include BaseAggregationComponent option_method :field end end end end end nested.rb000066400000000000000000000031231462737751600346420ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A single-bucket aggregation which allows to aggregate on nested fields # # @example # # search do # aggregation :offers do # nested do # path 'offers' # aggregation :min_price do # min field: 'offers.price' # end # end # end # end # # See the integration test for a full example. # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-nested-aggregation.html # class Nested include BaseAggregationComponent option_method :path end end end end end percentile_ranks.rb000066400000000000000000000032051462737751600367110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A multi-value metrics aggregation which calculates percentile ranks on numeric values # # @example # # search do # aggregation :load_time_outliers do # percentile_ranks do # field 'load_time' # values [ 15, 30 ] # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-percentile-rank-aggregation.html # class PercentileRanks include BaseComponent option_method :field option_method :values option_method :script option_method :params option_method :compression end end end end end percentiles.rb000066400000000000000000000031161462737751600356770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A multi-value metrics aggregation which calculates percentiles on numeric values # # @example # # search do # aggregation :load_time_outliers do # percentiles do # field 'load_time' # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-percentile-aggregation.html # class Percentiles include BaseComponent option_method :field option_method :percents option_method :script option_method :params option_method :compression end end end end end pipeline/000077500000000000000000000000001462737751600346415ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregationsavg_bucket.rb000066400000000000000000000034051462737751600373020ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A sibling pipeline aggregation which calculates the (mean) average value of a specified metric in a sibling aggregation. # # @example Passing the options as a Hash # # aggregation :avg_monthly_sales do # avg_bucket buckets_path: 'sales_per_month>sales' # end # # @example Passing the options as a block # # aggregation :avg_monthly_sales do # avg_bucket do # buckets_path 'sales_per_month>sales' # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-avg-bucket-aggregation.html # class AvgBucket include BaseAggregationComponent option_method :buckets_path option_method :gap_policy option_method :format end end end end end bucket_script.rb000066400000000000000000000040011462737751600400220ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A parent pipeline aggregation which executes a script which can perform per bucket computations on specified metrics in the parent multi-bucket aggregation. # # @example Passing the options as a Hash # # aggregation :t-shirt-percentage do # bucket_script buckets_path: { tShirtSales: 't-shirts>sales', totalSales: 'total_sales' }, script: 'tShirtSales / totalSales * 100' # end # # @example Passing the options as a block # # aggregation :t-shirt-percentage do # bucket_script do # buckets_path tShirtSales: 't-shirts>sales', totalSales: 'total_sales' # script 'tShirtSales / totalSales * 100' # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-script-aggregation.html # class BucketScript include BaseAggregationComponent option_method :buckets_path option_method :script option_method :gap_policy option_method :format end end end end end bucket_selector.rb000066400000000000000000000036171462737751600403520ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A parent pipeline aggregation which executes a script which determines whether the current bucket will be retained in the parent multi-bucket aggregation. # # @example Passing the options as a Hash # # aggregation :sales_bucket_filter do # bucket_selector buckets_path: { totalSales: 'total_sales' }, script: 'totalSales <= 50' # end # # @example Passing the options as a block # # aggregation :sales_bucket_filter do # bucket_selector do # buckets_path totalSales: 'total_sales' # script 'totalSales <= 50' # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-selector-aggregation.html # class BucketSelector include BaseAggregationComponent option_method :buckets_path option_method :script option_method :gap_policy end end end end end bucket_sort.rb000066400000000000000000000061151462737751600375150ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A parent pipeline aggregation which sorts the buckets of its parent multi-bucket aggregation. # # @example Passing the options as a Hash # # aggregation :sales_bucket_filter do # bucket_sort gap_policy: 'insert_zero' # end # # @example Passing the options as a block # # aggregation :sales_bucket_sort do # bucket_sort do # sort do # by :total_sales, order: 'desc' # end # size 3 # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-sort-aggregation.html # class BucketSort include BaseAggregationComponent # Add a sort clause to the search definition. # # @example # # bucket_sort do # sort do # by :total_sales, order: 'desc' # end # end # # @return [ Sort, Hash ] The sort definition. # # @since 0.1.9 def sort(*args, &block) if !args.empty? || block @sort = Sort.new(*args, &block) self else @sort end end # Get a hash representation of the aggregation. # # @example # # s = search do # aggregation do # bucket_sort do # sort do # by :total_sales, order: 'desc' # end # end # end # end # # client.search(body: s.to_hash) # # @return [ Hash ] The hash representation of the aggregation. # # @since 0.1.9 def to_hash call if @aggregations @hash[:aggregations] = @aggregations.to_hash end @hash[name].merge!(sort: @sort.to_hash) if @sort @hash end option_method :from option_method :size option_method :gap_policy end end end end end cumulative_sum.rb000066400000000000000000000033461462737751600402360ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A parent pipeline aggregation which calculates the cumulative sum of a specified metric in a parent histogram (or date_histogram) aggregation. # # @example Passing the options as a Hash # # aggregation :cumulative_sales do # cumulative_sum buckets_path: 'sales' # end # # @example Passing the options as a block # # aggregation :cumulative_sales do # cumulative_sum do # buckets_path 'sales' # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-cumulative-sum-aggregation.html # class CumulativeSum include BaseAggregationComponent option_method :buckets_path option_method :format end end end end end derivative.rb000066400000000000000000000033541462737751600373350ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A parent pipeline aggregation which calculates the derivative of a specified metric in a parent histogram (or date_histogram) aggregation. # # @example Passing the options as a Hash # # aggregation :sales_deriv do # derivative buckets_path: 'sales' # end # # @example Passing the options as a block # # aggregation :sales_deriv do # derivative do # buckets_path 'sales' # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-derivative-aggregation.html # class Derivative include BaseAggregationComponent option_method :buckets_path option_method :gap_policy option_method :format end end end end end extended_stats_bucket.rb000066400000000000000000000036451462737751600415510ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A sibling pipeline aggregation which calculates a variety of stats across all bucket of a specified metric in a sibling aggregation. The specified metric must be numeric and the sibling aggregation must be a multi-bucket aggregation. # # @example Passing the options as a Hash # # aggregation :stats_monthly_sales do # extended_stats_bucket buckets_path: 'sales_per_month>sales' # end # # @example Passing the options as a block # # aggregation :stats_monthly_sales do # extended_stats_bucket do # buckets_path 'sales_per_month>sales' # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-extended-stats-bucket-aggregation.html # class ExtendedStatsBucket include BaseAggregationComponent option_method :buckets_path option_method :gap_policy option_method :format end end end end end max_bucket.rb000066400000000000000000000035141462737751600373130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A sibling pipeline aggregation which identifies the bucket(s) with the maximum value of a specified metric in a sibling aggregation and outputs both the value and the key(s) of the bucket(s). # # @example Passing the options as a Hash # # aggregation :max_monthly_sales do # max_bucket buckets_path: 'sales_per_month>sales' # end # # @example Passing the options as a block # # aggregation :max_monthly_sales do # max_bucket do # buckets_path 'sales_per_month>sales' # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-max-bucket-aggregation.html # class MaxBucket include BaseAggregationComponent option_method :buckets_path option_method :gap_policy option_method :format end end end end end min_bucket.rb000066400000000000000000000035141462737751600373110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A sibling pipeline aggregation which identifies the bucket(s) with the minimum value of a specified metric in a sibling aggregation and outputs both the value and the key(s) of the bucket(s). # # @example Passing the options as a Hash # # aggregation :min_monthly_sales do # min_bucket buckets_path: 'sales_per_month>sales' # end # # @example Passing the options as a block # # aggregation :min_monthly_sales do # min_bucket do # buckets_path 'sales_per_month>sales' # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-min-bucket-aggregation.html # class MinBucket include BaseAggregationComponent option_method :buckets_path option_method :gap_policy option_method :format end end end end end moving_avg.rb000066400000000000000000000040011462737751600373150ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # Given an ordered series of data, the Moving Average aggregation will slide a window across the data and emit the average value of that window. # # @example Passing the options as a Hash # # aggregation :the_movavg do # moving_avg buckets_path: 'the_sum' # end # # @example Passing the options as a block # # aggregation :the_movavg do # moving_avg do # buckets_path 'the_sum' # model 'holt' # window 5 # gap_policy 'insert_zero' # settings({ alpha: 0.5 }) # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-movavg-aggregation.html # class MovingAvg include BaseAggregationComponent option_method :buckets_path option_method :model option_method :gap_policy option_method :window option_method :format option_method :minimize option_method :settings end end end end end percentiles_bucket.rb000066400000000000000000000035711462737751600410460ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A sibling pipeline aggregation which calculates percentiles across all bucket of a specified metric in a sibling aggregation. # # @example Passing the options as a Hash # # aggregation :sum_monthly_sales do # percentiles_bucket buckets_path: 'sales_per_month>sales' # end # # @example Passing the options as a block # # aggregation :sum_monthly_sales do # percentiles_bucket do # buckets_path 'sales_per_month>sales' # percents [25.0 50.0 75.0] # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-percentiles-bucket-aggregation.html # class PercentilesBucket include BaseAggregationComponent option_method :buckets_path option_method :gap_policy option_method :format option_method :percents end end end end end serial_diff.rb000066400000000000000000000034561462737751600374450ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # Serial differencing is a technique where values in a time series are subtracted from itself at different time lags or periods. # # @example Passing the options as a Hash # # aggregation :thirtieth_difference do # serial_diff buckets_path: 'the_sum' # end # # @example Passing the options as a block # # aggregation :thirtieth_difference do # serial_diff do # buckets_path 'the_sum' # lag 30 # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-serialdiff-aggregation.html # class SerialDiff include BaseAggregationComponent option_method :buckets_path option_method :lag option_method :gap_policy option_method :format end end end end end stats_bucket.rb000066400000000000000000000034351462737751600376660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A sibling pipeline aggregation which calculates a variety of stats across all bucket of a specified metric in a sibling aggregation. # # @example Passing the options as a Hash # # aggregation :stats_monthly_sales do # stats_bucket buckets_path: 'sales_per_month>sales' # end # # @example Passing the options as a block # # aggregation :stats_monthly_sales do # stats_bucket do # buckets_path 'sales_per_month>sales' # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-stats-bucket-aggregation.html # class StatsBucket include BaseAggregationComponent option_method :buckets_path option_method :gap_policy option_method :format end end end end end sum_bucket.rb000066400000000000000000000034061462737751600373320ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A sibling pipeline aggregation which calculates the sum across all bucket of a specified metric in a sibling aggregation. # # @example Passing the options as a Hash # # aggregation :sum_monthly_sales do # sum_bucket buckets_path: 'sales_per_month>sales' # end # # @example Passing the options as a block # # aggregation :sum_monthly_sales do # sum_bucket do # buckets_path 'sales_per_month>sales' # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-sum-bucket-aggregation.html # class SumBucket include BaseAggregationComponent option_method :buckets_path option_method :gap_policy option_method :format end end end end end range.rb000066400000000000000000000044721462737751600344640ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A multi-bucket aggregation which returns document counts for custom numerical ranges, # which define the buckets # # @example # # search do # aggregation :clicks do # range field: 'clicks', # ranges: [ # { to: 10 }, # { from: 10, to: 20 } # ] # end # end # # @example Using custom names for the ranges # # search do # aggregation :clicks do # range do # field 'clicks' # key :low, to: 10 # key :mid, from: 10, to: 20 # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-range-aggregation.html class Range include BaseAggregationComponent option_method :field option_method :script option_method :params option_method :keyed def key(key, value) @hash[name].update(@args) if @args @hash[name][:keyed] = true unless @hash[name].has_key?(:keyed) @hash[name][:ranges] ||= [] @hash[name][:ranges] << value.merge(key: key) unless @hash[name][:ranges].any? { |i| i[:key] == key } self end end end end end end reverse_nested.rb000066400000000000000000000033651462737751600364050ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A single-bucket aggregation which allows to aggregate on "parent" documents # from the nested documents # # @example # # search do # aggregation :offers do # nested do # path 'offers' # aggregation :top_categories do # reverse_nested do # aggregation :top_category_per_offer do # terms field: 'category' # end # end # end # end # end # end # # See the integration test for a full example. # # @see http://elasticsearch.org/guide/en/elasticsearch/guide/current/nested-aggregation.html # class ReverseNested include BaseAggregationComponent end end end end end scripted_metric.rb000066400000000000000000000037731462737751600365530ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A metric aggregation which uses scripts for the computation # # @example # # search do # aggregation :clicks_for_one do # scripted_metric do # init_script "_agg['transactions'] = []" # map_script "if (doc['tags'].value.contains('one')) { _agg.transactions.add(doc['clicks'].value) }" # combine_script "sum = 0; for (t in _agg.transactions) { sum += t }; return sum" # reduce_script "sum = 0; for (a in _aggs) { sum += a }; return sum" # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-scripted-metric-aggregation.html # # See the integration test for a full example. # class ScriptedMetric include BaseComponent option_method :init_script option_method :map_script option_method :combine_script option_method :reduce_script option_method :params option_method :lang end end end end end significant_terms.rb000066400000000000000000000037471462737751600371040ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A multi-bucket aggregation that returns interesting or unusual occurrences of terms in a set # # @example # # search do # query do # match :title do # query 'fink' # end # end # # aggregation :interesting_terms do # significant_terms do # field :body # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-significantterms-aggregation.html # class SignificantTerms include BaseAggregationComponent option_method :field option_method :size option_method :shard_size option_method :min_doc_count option_method :shard_min_doc_count option_method :include option_method :exclude option_method :background_filter option_method :mutual_information option_method :chi_square option_method :gnd end end end end end stats.rb000066400000000000000000000033131462737751600345170ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A multi-value metrics aggregation which returns statistical information on numeric values # # @example Passing the options as a Hash # # search do # aggregation :clicks_stats do # stats field: 'clicks' # end # end # # @example Passing the options as a block # # search do # aggregation :clicks_stats do # stats do # field 'clicks' # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-stats-aggregation.html # class Stats include BaseComponent option_method :field option_method :script end end end end end sum.rb000066400000000000000000000025221462737751600341660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A single-value metric aggregation which returns the sum of numeric values # # @example # # search do # aggregation :sum_clicks do # sum field: 'clicks' # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-sum-aggregation.html # class Sum include BaseComponent end end end end end terms.rb000066400000000000000000000036111462737751600345140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A multi-bucket aggregation which returns the collection of terms and their document counts # # @example Passing the options as a Hash # # aggregation :tags do # terms field: 'tags' # end # # @example Passing the options as a block # # search do # aggregation :tags do # terms do # field 'tags' # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html # class Terms include BaseAggregationComponent option_method :field option_method :size option_method :shard_size option_method :order option_method :min_doc_count option_method :shard_min_doc_count option_method :script option_method :include option_method :exclude end end end end end top_hits.rb000066400000000000000000000032141462737751600352120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A metric aggregator which returns the most relevant documents per bucket # # @example # # search do # aggregation :tags do # terms do # field 'tags' # # aggregation :top_hits do # top_hits sort: [ clicks: { order: 'desc' } ], _source: { include: 'title' } # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-top-hits-aggregation.html # class TopHits include BaseComponent option_method :from option_method :size option_method :sort end end end end end value_count.rb000066400000000000000000000025761462737751600357170ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Aggregations # A single-value metric aggregation which returns the number of values for the aggregation scope # # @example # # search do # aggregation :value_count do # value_count field: 'clicks' # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html # class ValueCount include BaseComponent end end end end end base_aggregation_component.rb000066400000000000000000000047341462737751600362620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search # Module containing common functionality for aggregation DSL classes # module BaseAggregationComponent def self.included(base) base.__send__ :include, BaseComponent base.__send__ :include, InstanceMethods end module InstanceMethods attr_reader :aggregations # Looks up the corresponding class for a method being invoked, and initializes it # # @raise [NoMethodError] When the corresponding class cannot be found # def method_missing(name, *args, &block) klass = Utils.__camelize(name) if Aggregations.const_defined? klass @value = Aggregations.const_get(klass).new *args, &block else raise NoMethodError, "undefined method '#{name}' for #{self}" end end # Adds a nested aggregation into the aggregation definition # # @return [self] # def aggregation(*args, &block) @aggregations ||= AggregationsCollection.new @aggregations.update args.first => Aggregation.new(*args, &block) self end # Convert the aggregations to a Hash # # A default implementation, DSL classes can overload it. # # @return [Hash] # def to_hash(options={}) call @hash = { name => @args } unless @hash && @hash[name] && ! @hash[name].empty? if @aggregations @hash[:aggregations] = @aggregations.to_hash end @hash end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/base_component.rb000066400000000000000000000141201462737751600337600ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search # Module containing common functionality for DSL classes # module BaseComponent def self.included(base) base.__send__ :extend, ClassMethods base.__send__ :include, InstanceMethods base.instance_eval do # Defines an "inner" method for DSL classes # # @example Define a method `bar` for the MyQuery class which updates the query definition # # class MyQuery # include BaseComponent # # option_method :bar # end # # q = MyQuery.new :foo do # bar 'TEST' # end # # q.to_hash # # => {:myquery=>{:foo=>{:bar=>"TEST"}}} # # @example Define a method `bar` with custom logic for updating the Hash with query definition # # class MyCustomQuery # include BaseComponent # # option_method :bar, lambda { |*args| @hash[self.name.to_sym][@args].update custom: args.pop } # end # # q = MyCustomQuery.new :foo do # bar 'TEST' # end # # q.to_hash # # => {:mycustomquery=>{:foo=>{:custom=>"TEST"}}} # def option_method(name, block=nil) option_methods << name if block self.__send__ :define_method, name, &block else self.__send__ :define_method, name do |*args| # 1. Component has empty @args (ie. no user supplied name or @hash value) if @args && @args.respond_to?(:to_hash) && @args.empty? @hash[self.name.to_sym].update name.to_sym => args.first # 2. Component user-supplied name or @hash value passed in @args else @hash[self.name.to_sym] = { @args => {} } unless @hash[self.name.to_sym][@args] @hash[self.name.to_sym][@args].update name.to_sym => args.first end end end end end end def initialize(*args, &block) @hash = { name => {} } @args = args.first || {} @options = args.size > 1 ? args.last : {} @block = block end module ClassMethods # Get or set the name for the DSL class # # @example Set the index name for the `Article` model and re-evaluate it on each call # # class MyQuery # include BaseComponent # name :my_special_query # end # # MyQuery.name # # => :my_special_query # def name(value=nil) if value @name = value.to_sym else @name ||= begin value = self.to_s.split('::').last value.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2') value.gsub!(/([a-z\d])([A-Z])/,'\1_\2') value.tr!("-", "_") value.downcase! value.to_sym end end end # Set the name for the DSL class # def name=(value) @name = value.to_sym end def option_methods @option_methods ||= [] end end module InstanceMethods # Return the name for instance of the DSL class # # @return [String] # def name self.class.name end # Evaluates any block passed to the query # # @return [self] # def call @block.arity < 1 ? self.instance_eval(&@block) : @block.call(self) if @block self end # Return true when the component definition is empty # def empty? to_hash[name].respond_to?(:empty?) && to_hash[name].empty? end # Convert the query definition to a Hash # # A default implementation, DSL classes can overload it. # # @return [Hash] # def to_hash(options={}) case # 1. Create hash from the block when @block @hash = (@args && ! @args.empty?) ? { name => { @args => {} } } : { name => {} } call @hash[self.name.to_sym].update @options unless @options.empty? @hash # 2. Hash created with option methods when @hash[self.name.to_sym] && ! @args.is_a?(Hash) && @hash[self.name.to_sym][@args] @hash[self.name.to_sym].update @options unless @options.empty? @hash # 3. Hash passsed as @args when @hash[self.name.to_sym] && @args.respond_to?(:to_hash) && ! @args.empty? { name => @args.to_hash } # 4. Hash already built else @hash end end end end end end end base_compound_filter_component.rb000066400000000000000000000064451462737751600371650ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search # Module containing common functionality for a "compound" (wrapping) filters, such as `and`, `or`, `not` # module BaseCompoundFilterComponent include Enumerable def initialize(*args, &block) super @value = [] end def self.included(base) base.__send__ :include, InstanceMethods base.__send__ :include, EnumerableMethods base.__send__ :include, MethodDelegation end # Common functionality for the compound filter components # module InstanceMethods # Evaluates the block passed to initializer, ensuring it is called just once # # @return [self] # # @api private # def call @block.arity < 1 ? self.instance_eval(&@block) : @block.call(self) if @block && ! @_block_called @_block_called = true self end # Convert the component to a Hash # # A default implementation, DSL classes can overload it. # # @return [Hash] # def to_hash(options={}) case when @value.empty? && ! @block @hash = super when @block call @hash = { name.to_sym => @value.map { |i| i.to_hash } } else @hash = { name.to_sym => @value } end @hash end end # Implements the {Enumerable} methods # module EnumerableMethods def each(&block) @value.each(&block) end def slice(*args) @value.slice(*args) end; alias :[] :slice def size @value.size end def <<(value) @value << value end def empty? @value.empty? end end module MethodDelegation # Looks up the corresponding class for a method being invoked, and initializes it # # @raise [NoMethodError] When the corresponding class cannot be found # def method_missing(name, *args, &block) klass = Utils.__camelize(name) if Filters.const_defined? klass @value << Filters.const_get(klass).new(*args, &block) else raise NoMethodError, "undefined method '#{name}' for #{self}" end end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filter.rb000066400000000000000000000042321462737751600322540ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search # Contains the classes for Elasticsearch filters # module Filters;end # Wraps the `filter` part of a search definition, aggregation, etc # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-filters.html # class Filter def initialize(*args, &block) @block = block end # Looks up the corresponding class for a method being invoked, and initializes it # # @raise [NoMethodError] When the corresponding class cannot be found # def method_missing(name, *args, &block) klass = Utils.__camelize(name) if Filters.const_defined? klass @value = Filters.const_get(klass).new *args, &block else raise NoMethodError, "undefined method '#{name}' for #{self}" end end # Evaluates any block passed to the query # # @return [self] # def call @block.arity < 1 ? self.instance_eval(&@block) : @block.call(self) if @block self end # Converts the query definition to a Hash # # @return [Hash] # def to_hash(options={}) call if @value @value.to_hash else {} end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/000077500000000000000000000000001462737751600321115ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/and.rb000066400000000000000000000040041462737751600331760ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A compound filter which matches documents by an intersection of individual filters. # # @note Since `and` is a keyword in Ruby, use the `_and` method in DSL definitions # # @example Pass the filters as a Hash # search do # query do # filtered do # filter do # _and filters: [ {term: { color: 'red' }}, {term: { size: 'xxl' }} ] # end # end # end # end # # @example Define the filters with a block # # search do # query do # filtered do # filter do # _and do # term color: 'red' # term size: 'xxl' # end # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-and-filter.html # class And include BaseComponent include BaseCompoundFilterComponent end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/bool.rb000066400000000000000000000061551462737751600334000ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A compound filter which matches documents based on combinations of filters # # @example Defining a bool filter with multiple conditions # # search do # query do # filtered do # filter do # bool do # must do # term category: 'men' # end # # must do # term size: 'xxl' # end # # should do # term color: 'red' # end # # must_not do # term manufacturer: 'evil' # end # end # end # end # end # end # # See the integration test for a working example. # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-filter.html # class Bool include BaseComponent def must(*args, &block) @hash[name][:must] ||= [] value = args.empty? ? Filter.new(*args, &block).to_hash : args.first.to_hash @hash[name][:must].push(value).flatten! unless @hash[name][:must].include?(value) self end def must_not(*args, &block) @hash[name][:must_not] ||= [] value = args.empty? ? Filter.new(*args, &block).to_hash : args.first.to_hash @hash[name][:must_not].push(value).flatten! unless @hash[name][:must_not].include?(value) self end def should(*args, &block) @hash[name][:should] ||= [] value = args.empty? ? Filter.new(*args, &block).to_hash : args.first.to_hash @hash[name][:should].push(value).flatten! unless @hash[name][:should].include?(value) self end def to_hash @hash[name].update(@args.to_hash) if @args.respond_to?(:to_hash) if @block call else @hash[name] = @args unless @args.nil? || @args.empty? end @hash end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/exists.rb000066400000000000000000000027771462737751600337720ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents which have a non-`null` value in the specified field # (ie. the reverse of the `missing` filter) # # @example # # search do # query do # filtered do # filter do # exists field: 'occupation' # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-exists-filter.html # class Exists include BaseComponent option_method :field end end end end end geo_bounding_box.rb000066400000000000000000000040121462737751600356630ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents which fall into a "box" of the specified geographical coordinates # # @example # # search do # query do # filtered do # filter do # geo_bounding_box :location do # top_right "50.1815123678,14.7149200439" # bottom_left "49.9415476869,14.2162566185" # end # end # end # end # end # # See the integration test for a working example. # # Use eg. to visually define the bounding box. # # @see http://elasticsearch.org/guide/en/elasticsearch/guide/current/geo-bounding-box.html # class GeoBoundingBox include BaseComponent option_method :top_left option_method :bottom_right option_method :top_right option_method :bottom_left option_method :top option_method :left option_method :bottom option_method :right end end end end end geo_distance.rb000066400000000000000000000050741462737751600350110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents which fall into a specified geographical distance # # @example Define the filter with a hash # # search do # query do # filtered do # filter do # geo_distance location: '50.090223,14.399590', distance: '5km' # end # end # end # end # # @example Define the filter with a block # # search do # query do # filtered do # filter do # geo_distance :location do # lat '50.090223' # lon '14.399590' # distance '5km' # end # end # end # end # end # # See the integration test for a working example. # # @see http://elasticsearch.org/guide/en/elasticsearch/guide/current/geo-distance.html # class GeoDistance include BaseComponent option_method :distance, lambda { |*args| @hash[self.name.to_sym].update distance: args.pop } option_method :distance_type, lambda { |*args| @hash[self.name.to_sym].update distance_type: args.pop } option_method :lat, lambda { |*args| @hash[self.name.to_sym][@args].update lat: args.pop } option_method :lon, lambda { |*args| @hash[self.name.to_sym][@args].update lon: args.pop } def initialize(*args, &block) super @hash[self.name.to_sym] = { @args => {} } unless @args.empty? end end end end end end geo_distance_range.rb000066400000000000000000000030541462737751600361610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents which fall into a specified geographical distance range # # @example Define the filter with a hash # # search do # query do # filtered do # filter do # geo_distance location: '50.090223,14.399590', gte: '2km', lte: '5km' # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/guide/current/geo-distance.html # class GeoDistanceRange include BaseComponent option_method :lat option_method :lon end end end end end geo_polygon.rb000066400000000000000000000035411462737751600347030ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents which fall into a specified geographical polygon # # @example # # search do # query do # filtered do # filter do # geo_polygon :location do # points [ # [14.2244355,49.9419006], # [14.2244355,50.1774301], # [14.7067869,50.1774301], # [14.7067869,49.9419006], # [14.2244355,49.9419006] # ] # end # end # end # end # end # # See the integration test for a working example. # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-polygon-filter.html # class GeoPolygon include BaseComponent option_method :points end end end end end geo_shape.rb000066400000000000000000000032411462737751600343110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents which fall into a specified geographical shape # # @example # # search do # query do # filtered do # filter do # geo_shape :location do # shape type: 'envelope', # coordinates: [[14.2162566185,49.9415476869], [14.7149200439,50.1815123678]] # end # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-filter.html # class GeoShape include BaseComponent option_method :shape option_method :indexed_shape end end end end end geohash_cell.rb000066400000000000000000000044271462737751600350030ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which translates lat/lon values into a geohash with the specified precision # and returns all documents which fall into it # # @example # # search do # query do # filtered do # filter do # geohash_cell :location do # lat '50.090223' # lon '14.399590' # precision '5km' # neighbors true # end # end # end # end # end # # See the integration test for a working example. # # @see http://elasticsearch.org/guide/en/elasticsearch/guide/current/geohash-cell-filter.html # class GeohashCell include BaseComponent option_method :precision, lambda { |*args| @hash[self.name.to_sym].update precision: args.pop } option_method :lat, lambda { |*args| @hash[self.name.to_sym][@args].update lat: args.pop } option_method :lon, lambda { |*args| @hash[self.name.to_sym][@args].update lon: args.pop } option_method :neighbors, lambda { |*args| @hash[self.name.to_sym].update neighbors: args.pop } def initialize(*args, &block) super @hash[self.name.to_sym] = { @args => {} } unless @args.empty? end end end end end end has_child.rb000066400000000000000000000055421462737751600343030ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns parent documents for children documents matching a query or a filter # # @example Return articles where John has commented # # search do # query do # filtered do # filter do # has_child do # type 'comment' # query do # match author: 'John' # end # end # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-has-child-filter.html # class HasChild include BaseComponent option_method :type option_method :min_children option_method :max_children option_method :inner_hits # DSL method for building the `query` part of the query definition # # @return [self] # def query(*args, &block) @query = block ? Elasticsearch::DSL::Search::Query.new(*args, &block) : args.first self end # DSL method for building the `filter` part of the query definition # # @return [self] # def filter(*args, &block) @filter = block ? Elasticsearch::DSL::Search::Filter.new(*args, &block) : args.first self end # Converts the query definition to a Hash # # @return [Hash] # def to_hash hash = super if @query _query = @query.respond_to?(:to_hash) ? @query.to_hash : @query hash[self.name].update(query: _query) end if @filter _filter = @filter.respond_to?(:to_hash) ? @filter.to_hash : @filter hash[self.name].update(filter: _filter) end hash end end end end end end has_parent.rb000066400000000000000000000055131462737751600345070ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns children documents for parent documents matching a query or a filter # # @example Return comments for articles about Ruby # # search do # query do # filtered do # filter do # has_parent do # type 'article' # query do # match title: 'Ruby' # end # end # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-has-parent-filter.html # class HasParent include BaseComponent option_method :parent_type option_method :score_mode option_method :inner_hits # DSL method for building the `query` part of the query definition # # @return [self] # def query(*args, &block) @query = block ? @query = Elasticsearch::DSL::Search::Query.new(*args, &block) : args.first self end # DSL method for building the `filter` part of the query definition # # @return [self] # def filter(*args, &block) @filter = block ? Elasticsearch::DSL::Search::Filter.new(*args, &block) : args.first self end # Converts the query definition to a Hash # # @return [Hash] # def to_hash hash = super if @query _query = @query.respond_to?(:to_hash) ? @query.to_hash : @query hash[self.name].update(query: _query) end if @filter _filter = @filter.respond_to?(:to_hash) ? @filter.to_hash : @filter hash[self.name].update(filter: _filter) end hash end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/ids.rb000066400000000000000000000027051462737751600332210ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents matching the specified IDs # # @example # # search do # query do # filtered do # filter do # ids values: [1, 2, 3] # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-ids-filter.html # class Ids include BaseComponent option_method :type option_method :values end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/indices.rb000066400000000000000000000057331462737751600340640ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which executes a custom filter only for documents in specified indices, # and optionally another filter for documents in other indices # # @example # # search do # query do # filtered do # filter do # indices do # indices ['audio', 'video'] # # filter do # terms tags: ['music'] # end # # no_match_filter do # terms tags: ['music', 'audio', 'video'] # end # end # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-indices-filter.html # class Indices include BaseComponent option_method :indices # DSL method for building the `filter` part of the query definition # # @return [self] # def filter(*args, &block) @filter = block ? Filter.new(*args, &block) : args.first self end # DSL method for building the `no_match_filter` part of the query definition # # @return [self] # def no_match_filter(*args, &block) @no_match_filter = block ? Filter.new(*args, &block) : args.first self end # Converts the query definition to a Hash # # @return [Hash] # def to_hash hash = super if @filter _filter = @filter.respond_to?(:to_hash) ? @filter.to_hash : @filter hash[self.name].update(filter: _filter) end if @no_match_filter _no_match_filter = @no_match_filter.respond_to?(:to_hash) ? @no_match_filter.to_hash : @no_match_filter hash[self.name].update(no_match_filter: _no_match_filter) end hash end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/limit.rb000066400000000000000000000026431462737751600335610ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which limits the number of documents to evaluate # # @example # # search do # query do # filtered do # filter do # limit value: 100 # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-limit-filter.html # class Limit include BaseComponent option_method :value end end end end end match_all.rb000066400000000000000000000025571462737751600343140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which matches on all documents # # @example # # search do # query do # filtered do # filter do # match_all # end # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-all-filter.html # class MatchAll include BaseComponent end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/missing.rb000066400000000000000000000031041462737751600341050ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents which have a `null` value in the specified field # (ie. the reverse of the `exists` filter) # # @example # # search do # query do # filtered do # filter do # missing field: 'occupation' # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-missing-filter.html # class Missing include BaseComponent option_method :field option_method :existence option_method :null_value end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/nested.rb000066400000000000000000000050411462737751600337200ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which executes another filter in the context of a nested document # # @example # # search do # query do # filtered do # filter do # nested do # path 'comments' # filter do # term 'comments.title' => 'Ruby' # end # end # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-nested-filter.html # class Nested include BaseComponent option_method :path # DSL method for building the `filter` part of the query definition # # @return [self] # def filter(*args, &block) @filter = block ? Filter.new(*args, &block) : args.first self end def query(*args, &block) @query = block ? Elasticsearch::DSL::Search::Query.new(*args, &block) : args.first self end # Converts the query definition to a Hash # # @return [Hash] # def to_hash hash = super if @filter _filter = @filter.respond_to?(:to_hash) ? @filter.to_hash : @filter hash[self.name].update(filter: _filter) end if @query _query = @query.respond_to?(:to_hash) ? @query.to_hash : @query hash[self.name].update(query: _query) end hash end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/not.rb000066400000000000000000000055111462737751600332400ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which takes out documents matching a filter from the results # # @note Since `not` is a keyword in Ruby, use the `_not` method in DSL definitions # # @example Pass the filter as a Hash # search do # query do # filtered do # filter do # _not term: { color: 'red' } # end # end # end # end # # @example Define the filter with a block # # search do # query do # filtered do # filter do # _not do # term color: 'red' # end # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-not-filter.html # class Not include BaseComponent # Looks up the corresponding class for a method being invoked, and initializes it # # @raise [NoMethodError] When the corresponding class cannot be found # def method_missing(name, *args, &block) klass = Utils.__camelize(name) if Filters.const_defined? klass @value = Filters.const_get(klass).new(*args, &block) else raise NoMethodError, "undefined method '#{name}' for #{self}" end end # Convert the component to a Hash # # A default implementation, DSL classes can overload it. # # @return [Hash] # def to_hash(options={}) case when (! @value || @value.empty?) && ! @block @hash = super when @block call @hash = { name.to_sym => @value.to_hash } end @hash end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/or.rb000066400000000000000000000037661462737751600330720ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A compound filter which matches documents by a union of individual filters. # # @note Since `or` is a keyword in Ruby, use the `_or` method in DSL definitions # # @example Pass the filters as a Hash # search do # query do # filtered do # filter do # _or filters: [ {term: { color: 'red' }}, {term: { size: 'xxl' }} ] # end # end # end # end # # @example Define the filters with a block # # search do # query do # filtered do # filter do # _or do # term color: 'red' # term size: 'xxl' # end # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-or-filter.html # class Or include BaseComponent include BaseCompoundFilterComponent end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/prefix.rb000066400000000000000000000026361462737751600337420ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents where the field value a specified prefix # # @example # # search do # query do # filtered do # filter do # prefix path: '/usr/local' # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-prefix-filter.html # class Prefix include BaseComponent end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/query.rb000066400000000000000000000040761462737751600336120ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which wraps a query so it can be used as a filter # # @example # # search do # query do # filtered do # filter do # query do # query_string :title do # query 'Ruby OR Python' # end # end # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-query-filter.html # class Query include BaseComponent def initialize(*args, &block) super if block @query = Elasticsearch::DSL::Search::Query.new(*args, &block) @block = nil end end # Converts the query definition to a Hash # # @return [Hash] # def to_hash hash = super if @query _query = @query.respond_to?(:to_hash) ? @query.to_hash : @query hash[self.name].update(_query) end hash end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/range.rb000066400000000000000000000032671462737751600335420ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents that have terms in a specified range # # @example # # search do # query do # filtered do # filter do # range :age do # gte 10 # lte 20 # end # end # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-filter.html # class Range include BaseComponent option_method :gte option_method :gt option_method :lte option_method :lt option_method :boost option_method :time_zone option_method :format end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/regexp.rb000066400000000000000000000030341462737751600337300ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents matching the specified regular expression # # @example # # search do # query do # filtered do # filter do # regexp :path do # value '^/usr/?.*/var' # end # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-regexp-filter.html # class Regexp include BaseComponent option_method :value option_method :flags end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/script.rb000066400000000000000000000027661462737751600337550ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents matching the criteria defined with a script # # @example # # search do # query do # filtered do # filter do # script script: "doc['clicks'].value % 4 == 0" # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-script-filter.html # class Script include BaseComponent option_method :script option_method :params end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/term.rb000066400000000000000000000030271462737751600334070ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents matching the specified terms # # @example # # search do # query do # filtered do # filter do # term color: 'red' # end # end # end # end # # @note The specified terms are *not analyzed* (lowercased, stemmed, etc), # so they must match the indexed terms. # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-filter.html # class Term include BaseComponent end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/terms.rb000066400000000000000000000031031462737751600335650ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents matching any term from the specified list of terms # # @example # # search do # query do # filtered do # filter do # terms tags: ['ruby', 'development'] # end # end # end # end # # @note The specified terms are *not analyzed* (lowercased, stemmed, etc), # so they must match the indexed terms. # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-terms-filter.html # class Terms include BaseComponent end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/filters/type.rb000066400000000000000000000027471462737751600334310ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Filters # A filter which returns documents matching the specified type # # @example # # search do # query do # filtered do # filter do # type do # value 'article' # end # end # end # end # end # # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-type-filter.html # class Type include BaseComponent option_method :value end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/highlight.rb000066400000000000000000000061341462737751600327410ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search # Wraps the `highlight` part of a search definition # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-highlighting.html # class Highlight include BaseComponent def initialize(*args, &block) @value = args.pop || {} super end # Specify the fields to highlight # # @example # # search do # highlight do # fields [:title, :body] # field :comments.body if options[:comments] # end # end # def fields(value_or_name) value = case value_or_name when Hash value_or_name when Array value_or_name.reduce({}) { |sum, item| sum.update item.to_sym => {}; sum } else end (@value[:fields] ||= {}).update value self end # Specify a single field to highlight # # @example # # search do # highlight do # field :title, fragment_size: 0 # field :body if options[:comments] # end # end # def field(name, options={}) (@value[:fields] ||= {}).update name.to_sym => options end # Specify the opening tags for the highlighted snippets # def pre_tags(*value) @value[:pre_tags] = value.flatten end; alias_method :pre_tags=, :pre_tags # Specify the closing tags for the highlighted snippets # def post_tags(*value) @value[:post_tags] = value.flatten end; alias_method :post_tags=, :post_tags # Specify the `encoder` option for highlighting # def encoder(value) @value[:encoder] = value end; alias_method :encoder=, :encoder # Specify the `tags_schema` option for highlighting # def tags_schema(value) @value[:tags_schema] = value end; alias_method :tags_schema=, :tags_schema # Convert the definition to a Hash # # @return [Hash] # def to_hash call @hash = @value @hash end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/options.rb000066400000000000000000000037651462737751600324740ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search # Wraps the "extra" options of a search definition # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html # class Options DSL_METHODS = [ :_source, :fields, :script_fields, :fielddata_fields, :rescore, :explain, :version, :indices_boost, :track_scores, :min_score, :track_total_hits ] def initialize(*args, &block) @hash = {} end # Defines a method for each valid search definition option # DSL_METHODS.each do |name| define_method name do |*args, &block| @hash[name] = args.pop end define_method name.to_s.gsub(/^_(.*)/, '\1') do |*args, &block| @hash[name] = args.pop end end # Returns true when there are no search options defined # def empty? @hash.empty? end # Convert the definition to a Hash # # @return [Hash] # def to_hash(options={}) @hash end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/000077500000000000000000000000001462737751600321165ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/bool.rb000066400000000000000000000064131462737751600334020ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A compound query which matches documents based on combinations of queries # # @example Defining a bool query with multiple conditions # # search do # query do # bool do # must do # term category: 'men' # end # # must do # term size: 'xxl' # end # # should do # term color: 'red' # end # # must_not do # term manufacturer: 'evil' # end # end # end # end # # See the integration test for a working example. # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html # class Bool include BaseComponent option_method :minimum_should_match option_method :boost def must(*args, &block) @hash[name][:must] ||= [] value = args.empty? ? Query.new(*args, &block).to_hash : args.first.to_hash @hash[name][:must].push(value).flatten! unless @hash[name][:must].include?(value) self end def must_not(*args, &block) @hash[name][:must_not] ||= [] value = args.empty? ? Query.new(*args, &block).to_hash : args.first.to_hash @hash[name][:must_not].push(value).flatten! unless @hash[name][:must_not].include?(value) self end def should(*args, &block) @hash[name][:should] ||= [] value = args.empty? ? Query.new(*args, &block).to_hash : args.first.to_hash @hash[name][:should].push(value).flatten! unless @hash[name][:should].include?(value) self end def filter(*args, &block) @hash[name][:filter] ||= [] if filter = block ? Filter.new(*args, &block) : args.first @hash[name][:filter] << filter.to_hash end self end def to_hash @hash[name].update(@args.to_hash) if @args.respond_to?(:to_hash) if @block call else @hash[name] = @args unless @args.nil? || @args.empty? end @hash end end end end end end boosting.rb000066400000000000000000000031261462737751600342120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which will decrease the score of documents matching the `negative` query # # @example # # search do # query do # boosting do # positive terms: { amenities: ['wifi', 'pets'] } # negative terms: { amenities: ['pool'] } # negative_boost 0.5 # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-boosting-query.html # class Boosting include BaseComponent option_method :positive option_method :negative option_method :negative_boost end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/common.rb000066400000000000000000000034551462737751600337420ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which executes the search for low frequency terms first, and high frequency ("common") # terms second # # @example # # search do # query do # common :body do # query 'shakespeare to be or not to be' # end # end # end # # This query is frequently used when a stopwords-based approach loses too much recall and/or precision. # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-common-terms-query.html # class Common include BaseComponent option_method :query option_method :cutoff_frequency option_method :low_freq_operator option_method :minimum_should_match option_method :boost option_method :analyzer option_method :disable_coord end end end end end constant_score.rb000066400000000000000000000047701462737751600354200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which wraps another query or filter and returns a constant score for matching documents # # @example # # search do # query do # constant_score do # query do # match content: 'Twitter' # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/guide/current/ignoring-tfidf.html # class ConstantScore include BaseComponent option_method :boost # DSL method for building the `query` part of the query definition # # @return [self] # def query(*args, &block) @query = block ? @query = Query.new(*args, &block) : args.first self end # DSL method for building the `filter` part of the query definition # # @return [self] # def filter(*args, &block) @filter = block ? Filter.new(*args, &block) : args.first self end # Converts the query definition to a Hash # # @return [Hash] # def to_hash hash = super if @query _query = @query.respond_to?(:to_hash) ? @query.to_hash : @query hash[self.name].update(query: _query) end if @filter _filter = @filter.respond_to?(:to_hash) ? @filter.to_hash : @filter hash[self.name].update(filter: _filter) end hash end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/dis_max.rb000066400000000000000000000032161462737751600340710ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which will score the documents based on the highest score of any individual specified query, # not by summing the scores (as eg. a `bool` query would) # # @example # # search do # query do # dis_max do # queries [ # { match: { title: 'albino' } }, # { match: { content: 'elephant' } } # ] # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/guide/current/_best_fields.html # class DisMax include BaseComponent option_method :queries option_method :boost option_method :tie_breaker end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/exists.rb000066400000000000000000000035771462737751600337760ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # Returns documents that have at least one non-null value in the field. # # @example Find documents with non-empty "name" property # # search do # query do # exists do # field 'name' # end # end # end # # @note The "Exists" query can be used as a "Missing" query in a "Bool" query "Must Not" context. # # @example Find documents with an empty "name" property # # search do # query do # bool do # must_not do # exists do # field 'name' # end # end # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/5.1/query-dsl-exists-query.html # class Exists include BaseComponent option_method :field end end end end end filtered.rb000066400000000000000000000057011462737751600341650ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which allows to combine a query with a filter # # @note It's possible and common to define just the `filter` part of the search definition, # for a structured search use case. # # @example Find documents about Twitter published last month # # search do # query do # filtered do # query do # multi_match do # query 'twitter' # fields [ :title, :abstract, :content ] # end # end # filter do # range :published_on do # gte 'now-1M/M' # end # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-filtered-query.html # class Filtered include BaseComponent option_method :strategy # DSL method for building the `query` part of the query definition # # @return [self] # def query(*args, &block) @query = block ? @query = Query.new(*args, &block) : args.first self end # DSL method for building the `filter` part of the query definition # # @return [self] # def filter(*args, &block) @filter = block ? Filter.new(*args, &block) : args.first self end # Converts the query definition to a Hash # # @return [Hash] # def to_hash hash = super if @query _query = @query.respond_to?(:to_hash) ? @query.to_hash : @query hash[self.name].update(query: _query) end if @filter _filter = @filter.respond_to?(:to_hash) ? @filter.to_hash : @filter hash[self.name].update(filter: _filter) end hash end end end end end end function_score.rb000066400000000000000000000072771462737751600354210ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which allows to modify the score of documents matching the query, # either via built-in functions or a custom script # # @example Find documents with specific amenities, boosting documents within a certain # price range and geogprahical location # # search do # query do # function_score do # filter do # terms amenities: ['wifi', 'pets'] # end # functions << { gauss: { price: { origin: 100, scale: 200 } } } # functions << { gauss: { location: { origin: '50.090223,14.399590', scale: '5km' } } } # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/guide/current/function-score-query.html # class FunctionScore include BaseComponent option_method :script_score option_method :boost option_method :max_boost option_method :score_mode option_method :boost_mode def initialize(*args, &block) super @functions = [] end # DSL method for building the `query` part of the query definition # # @return [self] # def query(*args, &block) @query = block ? @query = Query.new(*args, &block) : args.first self end # DSL method for building the `filter` part of the query definition # # @return [self] # def filter(*args, &block) @filter = block ? Filter.new(*args, &block) : args.first self end # DSL method for building the `functions` part of the query definition # # @return [Array] # def functions(value=nil) if value @functions = value else @functions end end # Set the `functions` part of the query definition # # @return [Array] # def functions=(value) @functions = value end # Converts the query definition to a Hash # # @return [Hash] # def to_hash hash = super if @query _query = @query.respond_to?(:to_hash) ? @query.to_hash : @query hash[self.name].update(query: _query) end if @filter _filter = @filter.respond_to?(:to_hash) ? @filter.to_hash : @filter hash[self.name].update(filter: _filter) end unless @functions.empty? hash[self.name].update(functions: @functions) end hash end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/fuzzy.rb000066400000000000000000000035261462737751600336400ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which uses a Levenshtein distance on string fields and plus-minus margin on numerical # fields to match documents # # @example # # search do # query do # fuzzy :name do # value 'Eyjafjallajökull' # end # end # end # # @example # # search do # query do # fuzzy :published_on do # value '2014-01-01' # fuzziness '7d' # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-fuzzy-query.html # class Fuzzy include BaseComponent option_method :value option_method :boost option_method :fuzziness option_method :prefix_length option_method :max_expansions end end end end end fuzzy_like_this.rb000066400000000000000000000033061462737751600356100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents which are similar to the specified text # # @example # # search do # query do # fuzzy_like_this do # like_text 'Eyjafjallajökull' # fields [:title, :abstract, :content] # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-flt-query.html # class FuzzyLikeThis include BaseComponent option_method :fields option_method :like_text option_method :fuzziness option_method :analyzer option_method :max_query_terms option_method :prefix_length option_method :boost option_method :ignore_tf end end end end end fuzzy_like_this_field.rb000066400000000000000000000032551462737751600367560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents which are similar to the specified text, # executed on a single field # # @example # # search do # query do # fuzzy_like_this_field :content do # like_text 'Eyjafjallajökull' # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-flt-field-query.html # class FuzzyLikeThisField include BaseComponent option_method :like_text option_method :fuzziness option_method :analyzer option_method :max_query_terms option_method :prefix_length option_method :boost option_method :ignore_tf end end end end end geo_shape.rb000066400000000000000000000030431462737751600343160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents which fall into a specified geographical shape # # @example # # search do # query do # geo_shape :location do # shape type: 'envelope', # coordinates: [[14.2162566185,49.9415476869], [14.7149200439,50.1815123678]] # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-query.html # class GeoShape include BaseComponent option_method :shape option_method :indexed_shape end end end end end has_child.rb000066400000000000000000000044161462737751600343070ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns parent documents for children documents matching a query # # @example Return articles where John has commented # # search do # query do # has_child do # type 'comment' # query do # match author: 'John' # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-has-child-query.html # class HasChild include BaseComponent option_method :type option_method :score_mode option_method :min_children option_method :max_children option_method :inner_hits # DSL method for building the `query` part of the query definition # # @return [self] # def query(*args, &block) @query = block ? @query = Query.new(*args, &block) : args.first self end # Converts the query definition to a Hash # # @return [Hash] # def to_hash hash = super if @query _query = @query.respond_to?(:to_hash) ? @query.to_hash : @query hash[self.name].update(query: _query) end hash end end end end end end has_parent.rb000066400000000000000000000043471462737751600345200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns children documents for parent documents matching a query # # @example Return comments for articles about Ruby # # search do # query do # has_parent do # type 'article' # query do # match title: 'Ruby' # end # end # end # end # # @example # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-has-parent-query.html # class HasParent include BaseComponent option_method :parent_type option_method :score_mode option_method :inner_hits # DSL method for building the `query` part of the query definition # # @return [self] # def query(*args, &block) @query = block ? @query = Query.new(*args, &block) : args.first self end # Converts the query definition to a Hash # # @return [Hash] # def to_hash hash = super if @query _query = @query.respond_to?(:to_hash) ? @query.to_hash : @query hash[self.name].update(query: _query) end hash end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/ids.rb000066400000000000000000000025251462737751600332260ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents matching the specified IDs # # @example # # search do # query do # ids values: [1, 2, 3] # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-ids-query.html # class Ids include BaseComponent option_method :type option_method :values end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/indices.rb000066400000000000000000000032421462737751600340620ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which executes a custom query only for documents in specified indices, # and optionally another query for documents in other indices # # @example # # search do # query do # indices do # indices ['audio', 'video'] # query match: { artist: 'Fugazi' } # no_match_query match: { label: 'Dischord' } # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-indices-query.html # class Indices include BaseComponent option_method :indices option_method :query option_method :no_match_query end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/match.rb000066400000000000000000000040341462737751600335400ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A simple to use, yet sophisticated query which returns documents matching the specified terms, # taking into account field types, analyzers, etc. and allowing to search in phrase, prefix, fuzzy modes # # @example # # search do # query do # match :content do # query 'how to fix my printer' # operator 'and' # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html # class Match include BaseComponent option_method :query option_method :operator option_method :minimum_should_match option_method :type option_method :boost option_method :fuzziness option_method :prefix_length option_method :max_expansions option_method :fuzzy_rewrite option_method :analyzer option_method :lenient option_method :zero_terms_query option_method :cutoff_frequency option_method :max_expansions end end end end end match_all.rb000066400000000000000000000024341462737751600343130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which matches all documents # # @example # # search do # query do # match_all # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-all-query.html # class MatchAll include BaseComponent option_method :boost end end end end end match_phrase.rb000066400000000000000000000030511462737751600350210ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query that analyzes the text and creates a phrase query out of the analyzed text # # @example # # search do # query do # match_phrase :content do # query 'example content' # analyzer 'standard' # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase.html # class MatchPhrase include BaseComponent option_method :query option_method :analyzer option_method :boost option_method :slop end end end end end match_phrase_prefix.rb000066400000000000000000000030601462737751600363760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # The same as match_phrase, except that it allows for prefix matches on the last term in the text # # @example # # search do # query do # match_phrase_prefix :content do # query 'example content' # max_expansions 10 # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase-prefix.html # class MatchPhrasePrefix include BaseComponent option_method :query option_method :boost option_method :max_expansions end end end end end more_like_this.rb000066400000000000000000000051161462737751600353640ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents which are similar to the specified text or documents # # @example Find documents similar to the provided text # # search do # query do # more_like_this do # like ['Eyjafjallajökull'] # fields [:title, :abstract, :content] # end # end # end # # # @example Find documents similar to the specified documents # # search do # query do # more_like_this do # like [{_id: 1}, {_id: 2}, {_id: 3}] # fields [:title, :abstract] # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-mlt-query.html # class MoreLikeThis include BaseComponent # like/unlike is since 2.0.0 option_method :like option_method :unlike # before 2.0.0 the following 3 options were available option_method :like_text option_method :docs option_method :ids option_method :fields option_method :min_term_freq option_method :max_query_terms option_method :include option_method :exclude option_method :percent_terms_to_match option_method :stop_words option_method :min_doc_freq option_method :max_doc_freq option_method :min_word_length option_method :max_word_length option_method :boost_terms option_method :boost option_method :analyzer end end end end end multi_match.rb000066400000000000000000000037461462737751600347040ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which allows to use the `match` query on multiple fields # # @example # # search do # query do # multi_match do # query 'how to fix my printer' # fields [:title, :abstract, :content] # operator 'and' # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html # class MultiMatch include BaseComponent option_method :analyzer option_method :boost option_method :cutoff_frequency option_method :fields option_method :fuzziness option_method :max_expansions option_method :minimum_should_match option_method :operator option_method :prefix_length option_method :query option_method :rewrite option_method :slop option_method :type option_method :use_dis_max option_method :zero_terms_query end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/nested.rb000066400000000000000000000043051462737751600337270ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns the root documents for nested documents matching the specified query # # @example Return articles where John has commented # # search do # query do # nested do # path 'comments' # query do # match user: 'John' # end # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html # class Nested include BaseComponent option_method :path option_method :score_mode option_method :inner_hits # DSL method for building the `query` part of the query definition # # @return [self] # def query(*args, &block) @query = block ? @query = Query.new(*args, &block) : args.first self end # Converts the query definition to a Hash # # @return [Hash] # def to_hash hash = super if @query _query = @query.respond_to?(:to_hash) ? @query.to_hash : @query hash[self.name].update(query: _query) end hash end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/prefix.rb000066400000000000000000000025611462737751600337440ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents matching a specified prefix # # @example # # search do # query do # prefix :title do # value 'dis' # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-prefix-query.html # class Prefix include BaseComponent option_method :value option_method :boost end end end end end query_string.rb000066400000000000000000000046371462737751600351310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents matching a specified expression in the Lucene Query String syntax # # @example # # search do # query do # query_string do # query '(mortgage OR (bank AND loan)) AND published_on:[2013-01-01 TO 2013-12-31]' # fields [:title, :content] # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html # @see http://lucene.apache.org/core/2_9_4/queryparsersyntax.html # class QueryString include BaseComponent option_method :query option_method :fields option_method :type option_method :default_field option_method :default_operator option_method :analyzer option_method :allow_leading_wildcard option_method :lowercase_expanded_terms option_method :enable_position_increments option_method :fuzzy_max_expansions option_method :fuzziness option_method :fuzzy_prefix_length option_method :phrase_slop option_method :boost option_method :analyze_wildcard option_method :auto_generate_phrase_queries option_method :minimum_should_match option_method :lenient option_method :locale option_method :use_dis_max option_method :tie_breaker option_method :time_zone end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/range.rb000066400000000000000000000036541462737751600335470ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents matching the specified range # # @example Find documents within a numeric range # # search do # query do # range :age do # gte 10 # lte 20 # end # end # end # # @example Find documents published within a date range # # search do # query do # range :published_on do # gte '2013-01-01' # lte 'now' # time_zone '+1:00' # end # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html # class Range include BaseComponent option_method :gte option_method :gt option_method :lte option_method :lt option_method :boost option_method :time_zone option_method :format end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/regexp.rb000066400000000000000000000026671462737751600337500ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which matches documents matching a regular expression # # @example # # search do # query do # regexp :path do # value '^/usr/?.*/var' # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html # class Regexp include BaseComponent option_method :value option_method :boost option_method :flags end end end end end simple_query_string.rb000066400000000000000000000035451462737751600364770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents matching a simplified query string syntax # # @example # # search do # query do # simple_query_string do # query 'disaster -health' # fields ['title^5', 'abstract', 'content'] # default_operator 'and' # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html # class SimpleQueryString include BaseComponent option_method :query option_method :fields option_method :default_operator option_method :analyzer option_method :flags option_method :analyze_wildcard option_method :lenient option_method :minimum_should_match option_method :quote_field_suffix option_method :all_fields end end end end end span_first.rb000066400000000000000000000027521462737751600345420ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents having spans in the beginning of the field # # @example # # search do # query do # span_first match: { span_term: { title: 'disaster' } }, end: 10 # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-span-first-query.html # @see https://lucene.apache.org/core/5_0_0/core/org/apache/lucene/search/spans/package-summary.html # class SpanFirst include BaseComponent option_method :match end end end end end span_multi.rb000066400000000000000000000027351462737751600345460ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents matching a multi-term query as a span query # # @example # # search do # query do # span_multi match: { prefix: { name: 'jo' } } # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-span-multi-term-query.html # @see https://lucene.apache.org/core/5_0_0/core/org/apache/lucene/search/spans/package-summary.html # class SpanMulti include BaseComponent option_method :match end end end end end span_near.rb000066400000000000000000000032201462737751600343270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents matching spans near each other # # @example # # search do # query do # span_near clauses: [ { span_term: { title: 'disaster' } }, { span_term: { title: 'health' } } ], # slop: 10 # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-span-near-query.html # @see https://lucene.apache.org/core/5_0_0/core/org/apache/lucene/search/spans/package-summary.html # class SpanNear include BaseComponent option_method :span_near option_method :slop option_method :in_order option_method :collect_payloads end end end end end span_not.rb000066400000000000000000000032411462737751600342050ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which discards matching documents which overlap with another query # # @example # # search do # query do # span_not include: { span_term: { title: 'disaster' } }, # exclude: { span_term: { title: 'health' } } # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-span-not-query.html # @see https://lucene.apache.org/core/5_0_0/core/org/apache/lucene/search/spans/package-summary.html # class SpanNot include BaseComponent option_method :include option_method :exclude option_method :pre option_method :post option_method :dist end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/span_or.rb000066400000000000000000000030001462737751600340750ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents matching the union of provided queries # # @example # # search do # query do # span_or clauses: [ { span_term: { title: 'disaster' } }, { span_term: { title: 'health' } } ] # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-span-or-query.html # @see https://lucene.apache.org/core/5_0_0/core/org/apache/lucene/search/spans/package-summary.html # class SpanOr include BaseComponent option_method :clauses end end end end end span_term.rb000066400000000000000000000026311462737751600343560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents having a span containing a term # # @example # # search do # query do # span_term title: 'disaster' # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-span-term-query.html # @see https://lucene.apache.org/core/5_0_0/core/org/apache/lucene/search/spans/package-summary.html # class SpanTerm include BaseComponent end end end end end template.rb000066400000000000000000000027511462737751600342040ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which allows to use Mustache templates for query definitions # # @example # # search do # query do # template do # query match: { content: '{query_string}' } # params query_string: 'twitter' # end # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-template-query.html # class Template include BaseComponent option_method :query option_method :params end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/term.rb000066400000000000000000000025641462737751600334210ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents matching the specified term # # @note The specified term is *not analyzed* (lowercased, stemmed, etc) # # @example # # search do # query do # term category: 'Opinion' # end # end # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html # class Term include BaseComponent end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries/terms.rb000066400000000000000000000026201462737751600335750ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents matching the specified terms # # @note The specified terms are *not analyzed* (lowercased, stemmed, etc) # # @example # # search do # query do # terms categories: ['World', 'Opinion'] # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-common-terms-query.html # class Terms include BaseComponent end end end end end top_children.rb000066400000000000000000000044541462737751600350450ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A filter which returns parent documents for children documents matching a query # # @example Return articles with comments mentioning 'twitter', summing the score # # search do # query do # top_children do # type 'comment' # query match: { body: 'twitter' } # score 'sum' # end # end # end # # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-top-children-query.html # class TopChildren include BaseComponent option_method :type option_method :score option_method :factor option_method :incremental_factor option_method :_scope # DSL method for building the `query` part of the query definition # # @return [self] # def query(*args, &block) @query = block ? @query = Query.new(*args, &block) : args.first self end # Converts the query definition to a Hash # # @return [Hash] # def to_hash hash = super if @query _query = @query.respond_to?(:to_hash) ? @query.to_hash : @query hash[self.name].update(query: _query) end hash end end end end end end wildcard.rb000066400000000000000000000026701462737751600341620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search module Queries # A query which returns documents matching a wildcard expression # # @note The expression is *not analyzed* (lowercased, stemmed, etc) # # @example # # search do # query do # wildcard title: 'tw*' # end # end # # @see http://elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html # class Wildcard include BaseComponent option_method :value option_method :boost end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/query.rb000066400000000000000000000041751462737751600321420ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search # Contains the classes for Elasticsearch queries # module Queries;end # Wraps the `query` part of a search definition # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html # class Query def initialize(*args, &block) @block = block end # Looks up the corresponding class for a method being invoked, and initializes it # # @raise [NoMethodError] When the corresponding class cannot be found # def method_missing(name, *args, &block) klass = Utils.__camelize(name) if Queries.const_defined? klass @value = Queries.const_get(klass).new *args, &block else raise NoMethodError, "undefined method '#{name}' for #{self}" end end # Evaluates any block passed to the query # # @return [self] # def call @block.arity < 1 ? self.instance_eval(&@block) : @block.call(self) if @block self end # Converts the query definition to a Hash # # @return [Hash] # def to_hash(options={}) call if @value @value.to_hash else {} end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/sort.rb000066400000000000000000000040351462737751600317570ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search # Wraps the `sort` part of a search definition # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html # class Sort include BaseComponent def initialize(*args, &block) @value ||= [] super end # DSL method to specify sorting item # # @example # # search do # sort do # by :category # by :clicks, order: 'desc' # end # end # def by(name, direction=nil) @value << ( direction ? { name => direction } : name ) self end # Convert the definition to a Hash # # @return [Hash] # def to_hash if @block call unless @block_called @block_called = true else @value << @args if @args && !@args.empty? && ! @value.include?(@args) end @hash = @value.flatten @hash end # Return whether the definition is empty # # @return [Boolean] # def empty? to_hash.empty? end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/search/suggest.rb000066400000000000000000000025351462737751600324540ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL module Search # Wraps the `suggest` part of a search definition # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html # class Suggest include BaseComponent def initialize(key, options={}, &block) @key = key @options = options @block = block end # Convert the definition to a Hash # # @return [Hash] # def to_hash { @key => @options } end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/utils.rb000066400000000000000000000023221462737751600306600ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL # Generic utility methods # module Utils # Camelize an underscored string # # A lightweight version of ActiveSupport's `camelize` # # @example # __camelize('query_string') # # => 'QueryString' # # @api private # def __camelize(string) string.to_s.split('_').map(&:capitalize).join end extend self end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/lib/elasticsearch/dsl/version.rb000066400000000000000000000015121462737751600312050ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module DSL VERSION = "0.1.7" end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/000077500000000000000000000000001462737751600237645ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/000077500000000000000000000000001462737751600265765ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/000077500000000000000000000000001462737751600273605ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/000077500000000000000000000000001462737751600306255ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/000077500000000000000000000000001462737751600332775ustar00rootroot00000000000000avg_spec.rb000066400000000000000000000023111462737751600353310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Avg do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(avg: {}) end end context '#initialize' do let(:search) do described_class.new(foo: 'bar') end it 'takes a hash' do expect(search.to_hash).to eq(avg: { foo: 'bar' }) end end end cardinality_spec.rb000066400000000000000000000047761462737751600371000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Cardinality do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(cardinality: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:cardinality][:foo][:field]).to eq('bar') end end describe '#precision_threshold' do before do search.precision_threshold('bar') end it 'applies the option' do expect(search.to_hash[:cardinality][:foo][:precision_threshold]).to eq('bar') end end describe '#rehash' do before do search.rehash('skip') end it 'applies the option' do expect(search.to_hash[:cardinality][:foo][:rehash]).to eq('skip') end end describe '#script' do before do search.script('bar') end it 'applies the option' do expect(search.to_hash[:cardinality][:foo][:script]).to eq('bar') end end describe '#params' do before do search.params('bar') end it 'applies the option' do expect(search.to_hash[:cardinality][:foo][:params]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do field 'bar' end end it 'executes the block' do expect(search.to_hash).to eq({ cardinality: { foo: { field: 'bar' } } }) end end end end children_spec.rb000066400000000000000000000032041462737751600363460ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Children do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(children: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#type' do before do search.type('bar') end it 'applies the option' do expect(search.to_hash[:children][:foo][:type]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do type 'bar' end end it 'executes the block' do expect(search.to_hash).to eq({ children: { foo: { type: 'bar' } } }) end end end end composite_spec.rb000066400000000000000000000045461462737751600365720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Composite do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(composite: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#size' do before do search.size(2_000) end it 'applies the option' do expect(search.to_hash[:composite][:foo][:size]).to eq(2_000) end end describe '#sources' do before do search.sources('bar') end it 'applies the option' do expect(search.to_hash[:composite][:foo][:sources]).to eq('bar') end end describe '#after' do context 'when after is not given' do before do search.size(2_000) end it 'applies the option' do expect(search.to_hash[:composite][:foo].keys).not_to include(:after) end end context 'when after is given' do before do search.after('fake_after_key') end it 'applies the option' do expect(search.to_hash[:composite][:foo][:after]).to eq('fake_after_key') end end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do size 2_000 end end it 'executes the block' do expect(search.to_hash).to eq({ composite: { foo: { size: 2_000 } } }) end end end end date_histogram_spec.rb000066400000000000000000000102571462737751600375560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::DateHistogram do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(date_histogram: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:date_histogram][:foo][:field]).to eq('bar') end end describe '#interval' do before do search.interval('bar') end it 'applies the option' do expect(search.to_hash[:date_histogram][:foo][:interval]).to eq('bar') end end describe '#pre_zone' do before do search.pre_zone('bar') end it 'applies the option' do expect(search.to_hash[:date_histogram][:foo][:pre_zone]).to eq('bar') end end describe '#post_zone' do before do search.post_zone('bar') end it 'applies the option' do expect(search.to_hash[:date_histogram][:foo][:post_zone]).to eq('bar') end end describe '#time_zone' do before do search.time_zone('bar') end it 'applies the option' do expect(search.to_hash[:date_histogram][:foo][:time_zone]).to eq('bar') end end describe '#pre_zone_adjust_large_interval' do before do search.pre_zone_adjust_large_interval('bar') end it 'applies the option' do expect(search.to_hash[:date_histogram][:foo][:pre_zone_adjust_large_interval]).to eq('bar') end end describe '#pre_offest' do before do search.pre_offset('bar') end it 'applies the option' do expect(search.to_hash[:date_histogram][:foo][:pre_offset]).to eq('bar') end end describe '#post_offset' do before do search.post_offset('bar') end it 'applies the option' do expect(search.to_hash[:date_histogram][:foo][:post_offset]).to eq('bar') end end describe '#format' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:date_histogram][:foo][:format]).to eq('bar') end end describe '#min_doc_count' do before do search.min_doc_count('bar') end it 'applies the option' do expect(search.to_hash[:date_histogram][:foo][:min_doc_count]).to eq('bar') end end describe '#extended_bounds' do before do search.extended_bounds('bar') end it 'applies the option' do expect(search.to_hash[:date_histogram][:foo][:extended_bounds]).to eq('bar') end end describe '#order' do before do search.order('bar') end it 'applies the option' do expect(search.to_hash[:date_histogram][:foo][:order]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do field 'bar' interval 'day' format 'yyyy-MM-dd' end end it 'executes the block' do expect(search.to_hash).to eq(date_histogram: { field: 'bar', interval: 'day', format: 'yyyy-MM-dd' }) end end end end date_range_spec.rb000066400000000000000000000041631462737751600366540ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::DateRange do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(date_range: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:date_range][:foo][:field]).to eq('bar') end end describe '#format' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:date_range][:foo][:format]).to eq('bar') end end describe '#ranges' do before do search.ranges('bar') end it 'applies the option' do expect(search.to_hash[:date_range][:foo][:ranges]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do field 'bar' ranges [ {to: 'foo'}, {from: 'bar'} ] end end it 'executes the block' do expect(search.to_hash).to eq(date_range: { field: 'bar', ranges: [ {to: 'foo'}, {from: 'bar'} ] }) end end end end extended_stats_spec.rb000066400000000000000000000023511462737751600375760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::ExtendedStats do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(extended_stats: {}) end end context '#initialize' do let(:search) do described_class.new(foo: 'bar') end it 'takes a hash' do expect(search.to_hash).to eq(extended_stats: { foo: 'bar' }) end end end filter_spec.rb000066400000000000000000000027031462737751600360460ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Filter do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(filter: {}) end end context 'when another aggregation is nested' do let(:search) do described_class.new(terms: { foo: 'bar' }) do aggregation :sum_clicks do sum moo: 'bam' end end end it 'nests the aggregation in the hash' do expect(search.to_hash).to eq(filter: { terms: { foo: 'bar' } }, aggregations: { sum_clicks: { sum: { moo: 'bam' } } }) end end end filters_spec.rb000066400000000000000000000043641462737751600362360ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Filters do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(filters: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#filters' do before do search.filters(foo: 'bar') end it 'applies the option' do expect(search.to_hash[:filters][:filters][:foo]).to eq('bar') end end end context '#initialize' do let(:search) do described_class.new(foo: 'bar') end it 'takes a hash' do expect(search.to_hash).to eq(filters: { foo: 'bar' }) end context 'when filters are passed' do let(:search) do described_class.new(filters: { foo: 'bar' }) end it 'defines filters' do expect(search.to_hash).to eq(filters: { filters: { foo: 'bar' } }) end end end context 'when another aggregation is nested' do let(:search) do described_class.new do filters foo: { terms: { foo: 'bar' } } aggregation :sum_clicks do sum moo: 'bam' end end end it 'nests the aggregation in the hash' do expect(search.to_hash).to eq(filters: { filters: { foo: { terms: { foo: 'bar' } } } }, aggregations: { sum_clicks: { sum: { moo: 'bam' } } }) end end end geo_bounds_spec.rb000066400000000000000000000035441462737751600367110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::GeoBounds do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(geo_bounds: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:geo_bounds][:foo][:field]).to eq('bar') end end describe '#wrap_longitude' do before do search.wrap_longitude('bar') end it 'applies the option' do expect(search.to_hash[:geo_bounds][:foo][:wrap_longitude]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do field 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(geo_bounds: { field: 'bar' }) end end end end geo_distance_spec.rb000066400000000000000000000053171462737751600372110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::GeoDistance do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(geo_distance: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:geo_distance][:foo][:field]).to eq('bar') end end describe '#origin' do before do search.origin('bar') end it 'applies the option' do expect(search.to_hash[:geo_distance][:foo][:origin]).to eq('bar') end end describe '#ranges' do before do search.ranges('bar') end it 'applies the option' do expect(search.to_hash[:geo_distance][:foo][:ranges]).to eq('bar') end end describe '#unit' do before do search.unit('bar') end it 'applies the option' do expect(search.to_hash[:geo_distance][:foo][:unit]).to eq('bar') end end describe '#distance_type' do before do search.distance_type('bar') end it 'applies the option' do expect(search.to_hash[:geo_distance][:foo][:distance_type]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do field 'bar' origin lat: 50, lon: 5 ranges [ { to: 50 }, { from: 50, to: 100 }, { from: 100 } ] end end it 'executes the block' do expect(search.to_hash).to eq(geo_distance: { field: 'bar', origin: { lat: 50, lon: 5 }, ranges: [ { to: 50 }, { from: 50, to: 100 }, { from: 100 } ] }) end end end end geo_grid_spec.rb000066400000000000000000000044531462737751600363440ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::GeohashGrid do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(geohash_grid: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:geohash_grid][:foo][:field]).to eq('bar') end end describe '#precision' do before do search.precision('bar') end it 'applies the option' do expect(search.to_hash[:geohash_grid][:foo][:precision]).to eq('bar') end end describe '#size' do before do search.size('bar') end it 'applies the option' do expect(search.to_hash[:geohash_grid][:foo][:size]).to eq('bar') end end describe '#shard_size' do before do search.shard_size('bar') end it 'applies the option' do expect(search.to_hash[:geohash_grid][:foo][:shard_size]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do field 'bar' precision 5 end end it 'executes the block' do expect(search.to_hash).to eq(geohash_grid: { field: 'bar', precision: 5 }) end end end end global_spec.rb000066400000000000000000000032031462737751600360150ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Global do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(global: {}) end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do end end it 'executes the block' do expect(search.to_hash).to eq(global: {}) end end context 'when another aggregation is nested' do let(:search) do described_class.new do aggregation :foo do terms field: "bar" end end end it 'nests the aggregation in the hash' do expect(search.to_hash).to eq(aggregations: { foo: { terms: { field: "bar" } } }, global: {}) end end end end historgram_spec.rb000066400000000000000000000053221462737751600367400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Histogram do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(histogram: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:histogram][:foo][:field]).to eq('bar') end end describe '#interval' do before do search.interval('bar') end it 'applies the option' do expect(search.to_hash[:histogram][:foo][:interval]).to eq('bar') end end describe '#min_doc_count' do before do search.min_doc_count('bar') end it 'applies the option' do expect(search.to_hash[:histogram][:foo][:min_doc_count]).to eq('bar') end end describe '#extended_bounds' do before do search.extended_bounds('bar') end it 'applies the option' do expect(search.to_hash[:histogram][:foo][:extended_bounds]).to eq('bar') end end describe '#order' do before do search.order('bar') end it 'applies the option' do expect(search.to_hash[:histogram][:foo][:order]).to eq('bar') end end describe '#keyed' do before do search.keyed('bar') end it 'applies the option' do expect(search.to_hash[:histogram][:foo][:keyed]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do field 'bar' interval 5 end end it 'executes the block' do expect(search.to_hash).to eq(histogram: { field: 'bar', interval: 5 }) end end end end ip_range_spec.rb000066400000000000000000000044231462737751600363460ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::IpRange do let(:search) do described_class.new end context '#initialize' do let(:search) do described_class.new(foo: 'bar') end it 'takes a hash' do expect(search.to_hash).to eq(ip_range: { foo: 'bar' }) end context 'when args are passed' do let(:search) do described_class.new(field: 'test', ranges: [ {to: 'foo'}, {from: 'bar'} ]) end it 'defines filters' do expect(search.to_hash).to eq(ip_range: { field: 'test', ranges: [ {to: 'foo'}, {from: 'bar'} ] }) end end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:ip_range][:foo][:field]).to eq('bar') end end describe '#ranges' do before do search.ranges('bar') end it 'applies the option' do expect(search.to_hash[:ip_range][:foo][:ranges]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do field 'bar' ranges [ {to: 'foo'}, {from: 'bar'} ] end end it 'executes the block' do expect(search.to_hash).to eq(ip_range: { field: 'bar', ranges: [ {to: 'foo'}, {from: 'bar'} ] }) end end end end max_spec.rb000066400000000000000000000023111462737751600353410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Max do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(max: {}) end end context '#initialize' do let(:search) do described_class.new(foo: 'bar') end it 'takes a hash' do expect(search.to_hash).to eq(max: { foo: 'bar' }) end end end min_spec.rb000066400000000000000000000023111462737751600353370ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Min do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(min: {}) end end context '#initialize' do let(:search) do described_class.new(foo: 'bar') end it 'takes a hash' do expect(search.to_hash).to eq(min: { foo: 'bar' }) end end end missing_spec.rb000066400000000000000000000036321462737751600362340ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Missing do let(:search) do described_class.new end context '#initialize' do let(:search) do described_class.new(foo: 'bar') end it 'takes a hash' do expect(search.to_hash).to eq(missing: { foo: 'bar' }) end context 'when args are passed' do let(:search) do described_class.new(field: 'test') end it 'defines filters' do expect(search.to_hash).to eq(missing: { field: 'test' }) end end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:missing][:foo][:field]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do field 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(missing: { field: 'bar' }) end end end end nested_spec.rb000066400000000000000000000041141462737751600360410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Nested do let(:search) do described_class.new end context '#initialize' do let(:search) do described_class.new(path: 'bar') end it 'takes a hash' do expect(search.to_hash).to eq(nested: { path: 'bar' }) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#path' do before do search.path('bar') end it 'applies the option' do expect(search.to_hash[:nested][:foo][:path]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do path 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(nested: { path: 'bar' }) end end context 'when another aggregation is nested' do let(:search) do described_class.new do path 'bar' aggregation :min_price do min field: 'bam' end end end it 'nests the aggregation in the hash' do expect(search.to_hash).to eq(nested: { path: 'bar' }, aggregations: { min_price: { min: { field: 'bam' } } }) end end end end percentile_ranks_spec.rb000066400000000000000000000055231462737751600401140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::PercentileRanks do let(:search) do described_class.new end context '#initialize' do let(:search) do described_class.new(foo: 'bar') end it 'takes a hash' do expect(search.to_hash).to eq(percentile_ranks: { foo: 'bar' }) end context 'when args are passed' do let(:search) do described_class.new(field: 'test') end it 'defines filters' do expect(search.to_hash).to eq(percentile_ranks: { field: 'test' }) end end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:percentile_ranks][:foo][:field]).to eq('bar') end end describe '#values' do before do search.values('bar') end it 'applies the option' do expect(search.to_hash[:percentile_ranks][:foo][:values]).to eq('bar') end end describe '#script' do before do search.script('bar') end it 'applies the option' do expect(search.to_hash[:percentile_ranks][:foo][:script]).to eq('bar') end end describe '#params' do before do search.params('bar') end it 'applies the option' do expect(search.to_hash[:percentile_ranks][:foo][:params]).to eq('bar') end end describe '#compression' do before do search.compression('bar') end it 'applies the option' do expect(search.to_hash[:percentile_ranks][:foo][:compression]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do field 'bar' values [5, 10] end end it 'executes the block' do expect(search.to_hash).to eq(percentile_ranks: { field: 'bar', values: [5, 10] }) end end end end percentiles_spec.rb000066400000000000000000000054031462737751600370760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Percentiles do let(:search) do described_class.new end context '#initialize' do let(:search) do described_class.new(foo: 'bar') end it 'takes a hash' do expect(search.to_hash).to eq(percentiles: { foo: 'bar' }) end context 'when args are passed' do let(:search) do described_class.new(field: 'test') end it 'defines filters' do expect(search.to_hash).to eq(percentiles: { field: 'test' }) end end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:percentiles][:foo][:field]).to eq('bar') end end describe '#percents' do before do search.percents('bar') end it 'applies the option' do expect(search.to_hash[:percentiles][:foo][:percents]).to eq('bar') end end describe '#script' do before do search.script('bar') end it 'applies the option' do expect(search.to_hash[:percentiles][:foo][:script]).to eq('bar') end end describe '#params' do before do search.params('bar') end it 'applies the option' do expect(search.to_hash[:percentiles][:foo][:params]).to eq('bar') end end describe '#compression' do before do search.compression('bar') end it 'applies the option' do expect(search.to_hash[:percentiles][:foo][:compression]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do field 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(percentiles: { field: 'bar' }) end end end end pipeline/000077500000000000000000000000001462737751600350255ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregationsavg_bucket_spec.rb000066400000000000000000000041231462737751600404760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::AvgBucket do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(avg_bucket: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#buckets_path' do before do search.buckets_path('bar') end it 'applies the option' do expect(search.to_hash[:avg_bucket][:foo][:buckets_path]).to eq('bar') end end describe '#gap_policy' do before do search.gap_policy('skip') end it 'applies the option' do expect(search.to_hash[:avg_bucket][:foo][:gap_policy]).to eq('skip') end end describe '#format' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:avg_bucket][:foo][:format]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do format 'bar' end end it 'executes the block' do expect(search.to_hash).to eq({ avg_bucket: { foo: { format: 'bar' } } }) end end end end bucket_script_spec.rb000066400000000000000000000044671462737751600412400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::BucketScript do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(bucket_script: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#buckets_path' do before do search.buckets_path('bar') end it 'applies the option' do expect(search.to_hash[:bucket_script][:foo][:buckets_path]).to eq('bar') end end describe '#script' do before do search.script('bar') end it 'applies the option' do expect(search.to_hash[:bucket_script][:foo][:script]).to eq('bar') end end describe '#gap_policy' do before do search.gap_policy('skip') end it 'applies the option' do expect(search.to_hash[:bucket_script][:foo][:gap_policy]).to eq('skip') end end describe '#format' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:bucket_script][:foo][:format]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do format 'bar' end end it 'executes the block' do expect(search.to_hash).to eq({ bucket_script: { foo: { format: 'bar' } } }) end end end end bucket_selector_spec.rb000066400000000000000000000041731462737751600415460ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::BucketSelector do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(bucket_selector: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#buckets_path' do before do search.buckets_path('bar') end it 'applies the option' do expect(search.to_hash[:bucket_selector][:foo][:buckets_path]).to eq('bar') end end describe '#script' do before do search.script('bar') end it 'applies the option' do expect(search.to_hash[:bucket_selector][:foo][:script]).to eq('bar') end end describe '#gap_policy' do before do search.gap_policy('skip') end it 'applies the option' do expect(search.to_hash[:bucket_selector][:foo][:gap_policy]).to eq('skip') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do gap_policy 'skip' end end it 'executes the block' do expect(search.to_hash).to eq({ bucket_selector: { foo: { gap_policy: 'skip' } } }) end end end end bucket_sort_spec.rb000066400000000000000000000046111462737751600407120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::BucketSort do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(bucket_sort: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#sort' do before do search.sort do by :category, order: 'desc' end end it 'applies the option' do expect(search.to_hash[:bucket_sort][:sort]).to eq([{ category: { order: 'desc' } }]) end end describe '#from' do before do search.from(5) end it 'applies the option' do expect(search.to_hash[:bucket_sort][:from]).to eq(5) end end describe '#size' do before do search.size(10) end it 'applies the option' do expect(search.to_hash[:bucket_sort][:size]).to eq(10) end end describe '#gap_policy' do before do search.gap_policy('insert_zero') end it 'applies the option' do expect(search.to_hash[:bucket_sort][:gap_policy]).to eq('insert_zero') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do sort do by :total_sales, order: 'desc' end size 3 end end it 'executes the block' do expect(search.to_hash).to eq(bucket_sort: { size: 3, sort: [{ total_sales: { order: 'desc' } }] }) end end end end cumulative_sum_spec.rb000066400000000000000000000036121462737751600414300ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::CumulativeSum do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(cumulative_sum: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#buckets_path' do before do search.buckets_path('bar') end it 'applies the option' do expect(search.to_hash[:cumulative_sum][:foo][:buckets_path]).to eq('bar') end end describe '#script' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:cumulative_sum][:foo][:format]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do format 'bar' end end it 'executes the block' do expect(search.to_hash).to eq({ cumulative_sum: { foo: { format: 'bar' } } }) end end end end derivative_spec.rb000066400000000000000000000041221462737751600405250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Derivative do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(derivative: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#buckets_path' do before do search.buckets_path('bar') end it 'applies the option' do expect(search.to_hash[:derivative][:foo][:buckets_path]).to eq('bar') end end describe '#gap_policy' do before do search.gap_policy('bar') end it 'applies the option' do expect(search.to_hash[:derivative][:foo][:gap_policy]).to eq('bar') end end describe '#script' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:derivative][:foo][:format]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do format 'bar' end end it 'executes the block' do expect(search.to_hash).to eq({ derivative: { foo: { format: 'bar' } } }) end end end end extended_stats_bucket_spec.rb000066400000000000000000000042221462737751600427370ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::ExtendedStatsBucket do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(extended_stats_bucket: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#buckets_path' do before do search.buckets_path('bar') end it 'applies the option' do expect(search.to_hash[:extended_stats_bucket][:foo][:buckets_path]).to eq('bar') end end describe '#gap_policy' do before do search.gap_policy('bar') end it 'applies the option' do expect(search.to_hash[:extended_stats_bucket][:foo][:gap_policy]).to eq('bar') end end describe '#format' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:extended_stats_bucket][:foo][:format]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do format 'bar' end end it 'executes the block' do expect(search.to_hash).to eq({ extended_stats_bucket: { foo: { format: 'bar' } } }) end end end end max_bucket_spec.rb000066400000000000000000000041211462737751600405040ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::MaxBucket do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(max_bucket: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#buckets_path' do before do search.buckets_path('bar') end it 'applies the option' do expect(search.to_hash[:max_bucket][:foo][:buckets_path]).to eq('bar') end end describe '#gap_policy' do before do search.gap_policy('bar') end it 'applies the option' do expect(search.to_hash[:max_bucket][:foo][:gap_policy]).to eq('bar') end end describe '#format' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:max_bucket][:foo][:format]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do format 'bar' end end it 'executes the block' do expect(search.to_hash).to eq({ max_bucket: { foo: { format: 'bar' } } }) end end end end min_bucket_spec.rb000066400000000000000000000041211462737751600405020ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::MinBucket do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(min_bucket: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#buckets_path' do before do search.buckets_path('bar') end it 'applies the option' do expect(search.to_hash[:min_bucket][:foo][:buckets_path]).to eq('bar') end end describe '#gap_policy' do before do search.gap_policy('bar') end it 'applies the option' do expect(search.to_hash[:min_bucket][:foo][:gap_policy]).to eq('bar') end end describe '#format' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:min_bucket][:foo][:format]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do format 'bar' end end it 'executes the block' do expect(search.to_hash).to eq({ min_bucket: { foo: { format: 'bar' } } }) end end end end moving_avg_test_spec.rb000066400000000000000000000056341462737751600415670ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::MovingAvg do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(moving_avg: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#buckets_path' do before do search.buckets_path('bar') end it 'applies the option' do expect(search.to_hash[:moving_avg][:foo][:buckets_path]).to eq('bar') end end describe '#gap_policy' do before do search.gap_policy('bar') end it 'applies the option' do expect(search.to_hash[:moving_avg][:foo][:gap_policy]).to eq('bar') end end describe '#minimize' do before do search.minimize(false) end it 'applies the option' do expect(search.to_hash[:moving_avg][:foo][:minimize]).to eq(false) end end describe '#model' do before do search.model('simple') end it 'applies the option' do expect(search.to_hash[:moving_avg][:foo][:model]).to eq('simple') end end describe '#settings' do before do search.settings(period: 7) end it 'applies the option' do expect(search.to_hash[:moving_avg][:foo][:settings]).to eq(period: 7) end end describe '#window' do before do search.window(5) end it 'applies the option' do expect(search.to_hash[:moving_avg][:foo][:window]).to eq(5) end end describe '#format' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:moving_avg][:foo][:format]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do format 'bar' end end it 'executes the block' do expect(search.to_hash).to eq({ moving_avg: { foo: { format: 'bar' } } }) end end end end percentiles_bucket_spec.rb000066400000000000000000000046141462737751600422430ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::PercentilesBucket do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(percentiles_bucket: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#buckets_path' do before do search.buckets_path('bar') end it 'applies the option' do expect(search.to_hash[:percentiles_bucket][:foo][:buckets_path]).to eq('bar') end end describe '#gap_policy' do before do search.gap_policy('bar') end it 'applies the option' do expect(search.to_hash[:percentiles_bucket][:foo][:gap_policy]).to eq('bar') end end describe '#format' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:percentiles_bucket][:foo][:format]).to eq('bar') end end describe '#percents' do before do search.percents([ 1, 5, 25, 50, 75, 95, 99 ]) end it 'applies the option' do expect(search.to_hash[:percentiles_bucket][:foo][:percents]).to eq([ 1, 5, 25, 50, 75, 95, 99 ]) end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do format 'bar' end end it 'executes the block' do expect(search.to_hash).to eq({ percentiles_bucket: { foo: { format: 'bar' } } }) end end end end serial_diff_spec.rb000066400000000000000000000044261462737751600406410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::SerialDiff do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(serial_diff: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#buckets_path' do before do search.buckets_path('bar') end it 'applies the option' do expect(search.to_hash[:serial_diff][:foo][:buckets_path]).to eq('bar') end end describe '#lag' do before do search.lag(1) end it 'applies the option' do expect(search.to_hash[:serial_diff][:foo][:lag]).to eq(1) end end describe '#gap_policy' do before do search.gap_policy('bar') end it 'applies the option' do expect(search.to_hash[:serial_diff][:foo][:gap_policy]).to eq('bar') end end describe '#format' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:serial_diff][:foo][:format]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do format 'bar' end end it 'executes the block' do expect(search.to_hash).to eq({ serial_diff: { foo: { format: 'bar' } } }) end end end end stats_bucket_spec.rb000066400000000000000000000041351462737751600410620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::StatsBucket do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(stats_bucket: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#buckets_path' do before do search.buckets_path('bar') end it 'applies the option' do expect(search.to_hash[:stats_bucket][:foo][:buckets_path]).to eq('bar') end end describe '#gap_policy' do before do search.gap_policy('bar') end it 'applies the option' do expect(search.to_hash[:stats_bucket][:foo][:gap_policy]).to eq('bar') end end describe '#format' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:stats_bucket][:foo][:format]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do format 'bar' end end it 'executes the block' do expect(search.to_hash).to eq({ stats_bucket: { foo: { format: 'bar' } } }) end end end end sum_bucket_spec.rb000066400000000000000000000041211462737751600405230ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations/pipeline# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::SumBucket do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(sum_bucket: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#buckets_path' do before do search.buckets_path('bar') end it 'applies the option' do expect(search.to_hash[:sum_bucket][:foo][:buckets_path]).to eq('bar') end end describe '#gap_policy' do before do search.gap_policy('bar') end it 'applies the option' do expect(search.to_hash[:sum_bucket][:foo][:gap_policy]).to eq('bar') end end describe '#format' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:sum_bucket][:foo][:format]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do format 'bar' end end it 'executes the block' do expect(search.to_hash).to eq({ sum_bucket: { foo: { format: 'bar' } } }) end end end end range_spec.rb000066400000000000000000000062121462737751600356540ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Range do let(:search) do described_class.new end context '#initialize' do let(:search) do described_class.new(field: 'test', ranges: [ { to: 50 } ]) end it 'takes a hash' do expect(search.to_hash).to eq(range: { field: "test", ranges: [ {to: 50} ] }) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('foo') end it 'applies the option' do expect(search.to_hash[:range][:foo][:field]).to eq('foo') end end describe '#script' do before do search.script('bar*2') end it 'applies the option' do expect(search.to_hash[:range][:foo][:script]).to eq('bar*2') end end end describe '#initialize' do context 'when a block is provided' do context 'when keyed ranges are provided' do let(:search) do described_class.new(field: 'test') do key 'foo', to: 10 key 'bar', from: 10, to: 20 end end it 'sets the values' do expect(search.to_hash).to eq(range: { field: "test", keyed: true, ranges: [ {to: 10, key: 'foo'}, { from: 10, to: 20, key: 'bar'}]}) end end context 'when keyed is set to false explicitly' do let(:search) do described_class.new do keyed false field 'test' key 'foo', to: 10 key 'bar', from: 10, to: 20 end end it 'sets the value' do expect(search.to_hash).to eq(range: { field: "test", keyed: false, ranges: [ {to: 10, key: 'foo'}, { from: 10, to: 20, key: 'bar'}]}) end end context 'when field is defined' do let(:search) do described_class.new do field 'test' key 'foo', to: 10 key 'bar', from: 10, to: 20 end end it 'sets the value' do expect(search.to_hash).to eq(range: { field: "test", keyed: true, ranges: [ {to: 10, key: 'foo'}, { from: 10, to: 20, key: 'bar'}]}) end end end end end reverse_nested_spec.rb000066400000000000000000000020371462737751600375760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::ReverseNested do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(reverse_nested: {}) end end end scripted_metric_spec.rb000066400000000000000000000054061462737751600377440ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::ScriptedMetric do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(scripted_metric: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#init_script' do before do search.init_script('bar') end it 'applies the option' do expect(search.to_hash[:scripted_metric][:foo][:init_script]).to eq('bar') end end describe '#map_script' do before do search.map_script('bar') end it 'applies the option' do expect(search.to_hash[:scripted_metric][:foo][:map_script]).to eq('bar') end end describe '#combine_script' do before do search.combine_script('bar') end it 'applies the option' do expect(search.to_hash[:scripted_metric][:foo][:combine_script]).to eq('bar') end end describe '#reduce_script' do before do search.reduce_script('bar') end it 'applies the option' do expect(search.to_hash[:scripted_metric][:foo][:reduce_script]).to eq('bar') end end describe '#params' do before do search.params('bar') end it 'applies the option' do expect(search.to_hash[:scripted_metric][:foo][:params]).to eq('bar') end end describe '#lang' do before do search.lang('bar') end it 'applies the option' do expect(search.to_hash[:scripted_metric][:foo][:lang]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do init_script 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(scripted_metric: { init_script: 'bar' }) end end end end significant_terms_spec.rb000066400000000000000000000076051462737751600402770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::SignificantTerms do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(significant_terms: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:significant_terms][:foo][:field]).to eq('bar') end end describe '#size' do before do search.size('bar') end it 'applies the option' do expect(search.to_hash[:significant_terms][:foo][:size]).to eq('bar') end end describe '#shard_size' do before do search.shard_size('bar') end it 'applies the option' do expect(search.to_hash[:significant_terms][:foo][:shard_size]).to eq('bar') end end describe '#min_doc_count' do before do search.min_doc_count('bar') end it 'applies the option' do expect(search.to_hash[:significant_terms][:foo][:min_doc_count]).to eq('bar') end end describe '#shard_min_doc_count' do before do search.shard_min_doc_count('bar') end it 'applies the option' do expect(search.to_hash[:significant_terms][:foo][:shard_min_doc_count]).to eq('bar') end end describe '#include' do before do search.include('bar') end it 'applies the option' do expect(search.to_hash[:significant_terms][:foo][:include]).to eq('bar') end end describe '#exclude' do before do search.exclude('bar') end it 'applies the option' do expect(search.to_hash[:significant_terms][:foo][:exclude]).to eq('bar') end end describe '#background_filter' do before do search.background_filter('bar') end it 'applies the option' do expect(search.to_hash[:significant_terms][:foo][:background_filter]).to eq('bar') end end describe '#mutual_information' do before do search.mutual_information('bar') end it 'applies the option' do expect(search.to_hash[:significant_terms][:foo][:mutual_information]).to eq('bar') end end describe '#chi_square' do before do search.chi_square('bar') end it 'applies the option' do expect(search.to_hash[:significant_terms][:foo][:chi_square]).to eq('bar') end end describe '#gnd' do before do search.gnd('bar') end it 'applies the option' do expect(search.to_hash[:significant_terms][:foo][:gnd]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do field 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(significant_terms: { field: 'bar' }) end end end end stats_spec.rb000066400000000000000000000027161462737751600357230ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Stats do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(stats: {}) end end context '#initialize' do let(:search) do described_class.new(foo: 'bar') end it 'takes a hash' do expect(search.to_hash).to eq(stats: { foo: 'bar' }) end context 'when a block is provided' do let(:search) do described_class.new do field 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(stats: { field: 'bar' }) end end end end sum_spec.rb000066400000000000000000000023111462737751600353600ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Sum do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(sum: {}) end end context '#initialize' do let(:search) do described_class.new(foo: 'bar') end it 'takes a hash' do expect(search.to_hash).to eq(sum: { foo: 'bar' }) end end end terms_spec.rb000066400000000000000000000067561462737751600357270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::Terms do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(terms: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:terms][:foo][:field]).to eq('bar') end end describe '#size' do before do search.size('bar') end it 'applies the option' do expect(search.to_hash[:terms][:foo][:size]).to eq('bar') end end describe '#shard_size' do before do search.shard_size('bar') end it 'applies the option' do expect(search.to_hash[:terms][:foo][:shard_size]).to eq('bar') end end describe '#order' do before do search.shard_size('bar') end it 'applies the option' do expect(search.to_hash[:terms][:foo][:shard_size]).to eq('bar') end end describe '#min_doc_count' do before do search.min_doc_count('bar') end it 'applies the option' do expect(search.to_hash[:terms][:foo][:min_doc_count]).to eq('bar') end end describe '#shard_min_doc_count' do before do search.shard_min_doc_count('bar') end it 'applies the option' do expect(search.to_hash[:terms][:foo][:shard_min_doc_count]).to eq('bar') end end describe '#include' do before do search.include('bar') end it 'applies the option' do expect(search.to_hash[:terms][:foo][:include]).to eq('bar') end end describe '#exclude' do before do search.exclude('bar') end it 'applies the option' do expect(search.to_hash[:terms][:foo][:exclude]).to eq('bar') end end describe '#script' do before do search.script('bar') end it 'applies the option' do expect(search.to_hash[:terms][:foo][:script]).to eq('bar') end end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(field: 'test') end it 'sets the value' do expect(search.to_hash).to eq(terms: { field: 'test' }) end end context 'when a block is provided' do let(:search) do described_class.new do field 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(terms: { field: 'bar' }) end end end end top_hits_spec.rb000066400000000000000000000037761462737751600364250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::TopHits do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(top_hits: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#from' do before do search.from('bar') end it 'applies the option' do expect(search.to_hash[:top_hits][:foo][:from]).to eq('bar') end end describe '#size' do before do search.size('bar') end it 'applies the option' do expect(search.to_hash[:top_hits][:foo][:size]).to eq('bar') end end describe '#sort' do before do search.sort('bar') end it 'applies the option' do expect(search.to_hash[:top_hits][:foo][:sort]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do from 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(top_hits: { from: 'bar' }) end end end end value_count_spec.rb000066400000000000000000000023421462737751600371040ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/aggregations# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Aggregations::ValueCount do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(value_count: {}) end end context '#initialize' do let(:search) do described_class.new(foo: 'bar') end it 'sets the value' do expect(search.to_hash).to eq(value_count: { foo: 'bar' }) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters/000077500000000000000000000000001462737751600322755ustar00rootroot00000000000000and_spec.rb000066400000000000000000000037561462737751600343320ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::And do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(and: {}) end end context 'when enumerable methods are called' do before do search << { term: { foo: 'bar' } } search << { term: { moo: 'mam' } } end it 'behaves like an enumerable' do expect(search.size).to eq(2) expect(search[0][:term][:foo]).to eq('bar') expect(search.any? { |d| d[:term] == { foo: 'bar' } }).to be(true) end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(filters: [ { term: { foo: 'bar' } } ]) end it 'applies the hash' do expect(search.to_hash).to eq(and: { filters: [ { term: { foo: 'bar' } } ] }) end end context 'when a block is provided' do let(:search) do described_class.new do term foo: 'bar' term moo: 'mam' end end it 'executes the block' do expect(search.to_hash).to eq(and: [ { term: { foo: 'bar' } }, { term: { moo: 'mam' } } ]) end end end end bool_spec.rb000066400000000000000000000142061462737751600345130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Bool do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(bool: {}) end end describe '#initialize' do context 'when an object instance is provided' do let(:search) do described_class.new.must( Elasticsearch::DSL::Search::Filters::Term.new foo: 'bar') end it 'applies the condition' do expect(search.to_hash).to eq(bool: { must: [ { term: { foo: 'bar' } } ] }) end context 'when the block calls multiple methods' do let(:search) do described_class.new do must(Elasticsearch::DSL::Search::Filters::Term.new foo: 'bar') must_not(Elasticsearch::DSL::Search::Filters::Term.new moo: 'bam') should(Elasticsearch::DSL::Search::Filters::Term.new xoo: 'bax') end end it 'executes the block' do expect(search.to_hash).to eq(bool: { must: [ { term: { foo: 'bar' } } ], must_not: [ { term: { moo: 'bam' } } ], should: [ { term: { xoo: 'bax' } } ] }) end end context 'when the block calls multiple conditions' do let(:search) do described_class.new do must(Elasticsearch::DSL::Search::Filters::Term.new foo: 'bar') must(Elasticsearch::DSL::Search::Filters::Term.new moo: 'bam') should(Elasticsearch::DSL::Search::Filters::Term.new xoo: 'bax') should(Elasticsearch::DSL::Search::Filters::Term.new zoo: 'baz') end end it 'executes the block' do expect(search.to_hash).to eq(bool: { must: [ { term: { foo: 'bar' } }, { term: { moo: 'bam' } } ], should: [ { term: { xoo: 'bax' } }, { term: { zoo: 'baz' } } ] }) end end end context 'when a hash is provided' do let(:search) do described_class.new(must: [ { term: { foo: 'bar' } } ]) end it 'applies the hash' do expect(search.to_hash).to eq(bool: { must: [ { term: { foo: 'bar' } } ] }) end end context 'when a block is provided' do let(:search) do described_class.new do must { term foo: 'bar' } end end it 'executes the block' do expect(search.to_hash).to eq(bool: { must: [ { term: { foo: 'bar' } } ] }) end context 'when the block calls multiple methods' do let(:search) do described_class.new do must { term foo: 'bar' } must_not { term moo: 'bam' } should { term xoo: 'bax' } end end it 'executes the block' do expect(search.to_hash).to eq(bool: { must: [ { term: { foo: 'bar' } } ], must_not: [ { term: { moo: 'bam' } } ], should: [ { term: { xoo: 'bax' } } ] }) end end context 'when the block calls multiple conditions' do let(:search) do described_class.new do must { term foo: 'bar' } must { term moo: 'bam' } should { term xoo: 'bax' } should { term zoo: 'baz' } end end it 'executes the block' do expect(search.to_hash).to eq(bool: { must: [ { term: { foo: 'bar' } }, { term: { moo: 'bam' } } ], should: [ { term: { xoo: 'bax' } }, { term: { zoo: 'baz' } } ] }) end end end end describe '#must' do before do search.must { term foo: 'bar' } end it 'applies the condition' do expect(search.to_hash).to eq(bool: { must: [ { term: { foo: 'bar' } } ] }) end context 'when the method is called more than once' do before do search.must { term foo: 'bar' } search.must { term moo: 'bam' } end it 'applies the conditions' do expect(search.to_hash).to eq(bool: { must: [ { term: { foo: 'bar' } }, { term: { moo: 'bam' } } ] }) end end end describe '#should' do before do search.should { term xoo: 'bax' } end it 'applies the condition' do expect(search.to_hash).to eq(bool: { should: [ { term: { xoo: 'bax' } } ] }) end end context 'when methods are chained' do before do search.must { term foo: 'bar' } search.must { term foo: 'baz' }.must { term moo: 'bam' } search.must_not { term foo: 'biz' } search.should { term foo: 'bor' } end it 'applies all the conditions' do expect(search.to_hash).to eq(bool: { must: [{ term: { foo: 'bar' } }, { term: { foo: 'baz' } }, { term: { moo: 'bam' } }], must_not: [{ term: { foo: 'biz' } }], should: [{ term: { foo: 'bor' } }] }) end end end exists_spec.rb000066400000000000000000000031511462737751600350740ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Exists do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(exists: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:exists][:foo][:field]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do field 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(exists: { field: 'bar' }) end end end end geo_bounding_box_spec.rb000066400000000000000000000062171462737751600370720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::GeoBoundingBox do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(geo_bounding_box: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#top_left' do before do search.top_left('bar') end it 'applies the option' do expect(search.to_hash[:geo_bounding_box][:top_left]).to eq('bar') end end describe '#bottom_right' do before do search.bottom_right('bar') end it 'applies the option' do expect(search.to_hash[:geo_bounding_box][:bottom_right]).to eq('bar') end end describe '#top_right' do before do search.top_right('bar') end it 'applies the option' do expect(search.to_hash[:geo_bounding_box][:top_right]).to eq('bar') end end describe '#bottom_left' do before do search.bottom_left('bar') end it 'applies the option' do expect(search.to_hash[:geo_bounding_box][:bottom_left]).to eq('bar') end end describe '#top' do before do search.top('bar') end it 'applies the option' do expect(search.to_hash[:geo_bounding_box][:top]).to eq('bar') end end describe '#left' do before do search.left('bar') end it 'applies the option' do expect(search.to_hash[:geo_bounding_box][:left]).to eq('bar') end end describe '#bottom' do before do search.bottom('bar') end it 'applies the option' do expect(search.to_hash[:geo_bounding_box][:bottom]).to eq('bar') end end describe '#right' do before do search.right('bar') end it 'applies the option' do expect(search.to_hash[:geo_bounding_box][:right]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do top_left [0,1] bottom_right [3,2] end end it 'executes the block' do expect(search.to_hash).to eq(geo_bounding_box: { top_left: [0,1], bottom_right: [3,2] }) end end end end geo_distance_range_spec.rb000066400000000000000000000050711462737751600373600ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::GeoDistanceRange do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(geo_distance_range: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#lat' do before do search.lat('bar') end it 'applies the option' do expect(search.to_hash[:geo_distance_range][:foo][:lat]).to eq('bar') end end describe '#lon' do before do search.lon('bar') end it 'applies the option' do expect(search.to_hash[:geo_distance_range][:foo][:lon]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do lat 40 lon -70 end end it 'executes the block' do expect(search.to_hash).to eq(geo_distance_range: { lat: 40, lon: -70 }) end context 'when options are also provided' do let(:search) do described_class.new :foo, from: '10km', to: '20km' do lat 40 lon -70 end end it 'executes the block' do expect(search.to_hash).to eq(geo_distance_range: { foo: { lat: 40, lon: -70 }, from: '10km', to: '20km' }) end end end context 'when options are provided' do let(:search) do described_class.new(from: '10km', to: '20km', foo: { lat: 40, lon: -70 }) end it 'executes the block' do expect(search.to_hash).to eq(geo_distance_range: { foo: { lat: 40, lon: -70 }, from: '10km', to: '20km' }) end end end end geo_distance_spec.rb000066400000000000000000000057321462737751600362100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::GeoDistance do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(geo_distance: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#distance' do before do search.distance('bar') end it 'applies the option' do expect(search.to_hash[:geo_distance][:distance]).to eq('bar') end end describe '#distance_type' do before do search.distance_type('bar') end it 'applies the option' do expect(search.to_hash[:geo_distance][:distance_type]).to eq('bar') end end describe '#lat' do before do search.lat('bar') end it 'applies the option' do expect(search.to_hash[:geo_distance][:foo][:lat]).to eq('bar') end end describe '#lon' do before do search.lon('bar') end it 'applies the option' do expect(search.to_hash[:geo_distance][:foo][:lon]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new :foo do distance '1km' lat 40 lon -70 end end it 'executes the block' do expect(search.to_hash).to eq(geo_distance: { distance: '1km', foo: { lat: 40, lon: -70 } }) end context 'when options are also provided' do let(:search) do described_class.new(:foo, distance: '10km') do lat 40 lon -70 end end it 'executes the block' do expect(search.to_hash).to eq(geo_distance: { foo: { lat: 40, lon: -70 }, distance: '10km' }) end end end context 'when options are provided' do let(:search) do described_class.new(distance: '10km', foo: { lat: 40, lon: -70 }) end it 'executes the block' do expect(search.to_hash).to eq(geo_distance: { foo: { lat: 40, lon: -70 }, distance: '10km' }) end end end end geo_polygon_spec.rb000066400000000000000000000032251462737751600361000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::GeoPolygon do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(geo_polygon: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#points' do before do search.points('bar') end it 'applies the option' do expect(search.to_hash[:geo_polygon][:foo][:points]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new :foo do points 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(geo_polygon: { foo: { points: 'bar' } }) end end end end geo_shape_spec.rb000066400000000000000000000035531462737751600355150ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::GeoShape do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(geo_shape: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#shape' do before do search.shape('bar') end it 'applies the option' do expect(search.to_hash[:geo_shape][:foo][:shape]).to eq('bar') end end describe '#indexed_shape' do before do search.indexed_shape('bar') end it 'applies the option' do expect(search.to_hash[:geo_shape][:foo][:indexed_shape]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new :foo do shape 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(geo_shape: { foo: { shape: 'bar' } }) end end end end geohash_cell_spec.rb000066400000000000000000000043721462737751600362000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::GeohashCell do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(geohash_cell: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#precision' do before do search.precision('bar') end it 'applies the option' do expect(search.to_hash[:geohash_cell][:precision]).to eq('bar') end end describe '#neighbors' do before do search.neighbors('bar') end it 'applies the option' do expect(search.to_hash[:geohash_cell][:neighbors]).to eq('bar') end end describe '#lat' do before do search.lat('bar') end it 'applies the option' do expect(search.to_hash[:geohash_cell][:foo][:lat]).to eq('bar') end end describe '#lon' do before do search.lon('bar') end it 'applies the option' do expect(search.to_hash[:geohash_cell][:foo][:lon]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new :foo do lat 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(geohash_cell: { foo: { lat: 'bar' } }) end end end end has_child_spec.rb000066400000000000000000000061251462737751600354770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::HasChild do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(has_child: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#type' do before do search.type('bar') end it 'applies the option' do expect(search.to_hash[:has_child][:foo][:type]).to eq('bar') end end describe '#query' do before do search.query('bar') end it 'applies the option' do expect(search.to_hash[:has_child][:query]).to eq('bar') end end describe '#filter' do before do search.filter('bar') end it 'applies the option' do expect(search.to_hash[:has_child][:filter]).to eq('bar') end end describe '#min_children' do before do search.min_children('bar') end it 'applies the option' do expect(search.to_hash[:has_child][:foo][:min_children]).to eq('bar') end end describe '#max_children' do before do search.max_children('bar') end it 'applies the option' do expect(search.to_hash[:has_child][:foo][:max_children]).to eq('bar') end end describe '#inner_hits' do before do search.inner_hits(size: 1) end it 'applies the option' do expect(search.to_hash[:has_child][:foo][:inner_hits]).to eq(size: 1) end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do type 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(has_child: { foo: { type: 'bar' } }) end end context 'when a block is provided to an option method' do let(:search) do described_class.new do type 'bar' query do match :foo do query 'bar' end end end end it 'executes the block' do expect(search.to_hash).to eq(has_child: { type: 'bar', query: { match: { foo: { query: 'bar'} } } }) end end end end has_parent_spec.rb000066400000000000000000000056511462737751600357100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::HasParent do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(has_parent: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#parent_type' do before do search.parent_type('bar') end it 'applies the option' do expect(search.to_hash[:has_parent][:foo][:parent_type]).to eq('bar') end end describe '#query' do before do search.query('bar') end it 'applies the option' do expect(search.to_hash[:has_parent][:query]).to eq('bar') end end describe '#filter' do before do search.filter('bar') end it 'applies the option' do expect(search.to_hash[:has_parent][:filter]).to eq('bar') end end describe '#score_mode' do before do search.score_mode('bar') end it 'applies the option' do expect(search.to_hash[:has_parent][:foo][:score_mode]).to eq('bar') end end describe '#inner_hits' do before do search.inner_hits(size: 1) end it 'applies the option' do expect(search.to_hash[:has_parent][:foo][:inner_hits]).to eq(size: 1) end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do parent_type 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(has_parent: { foo: { parent_type: 'bar' } }) end end context 'when a block is provided to an option method' do let(:search) do described_class.new do parent_type 'bar' query do match :foo do query 'bar' end end end end it 'executes the block' do expect(search.to_hash).to eq(has_parent: { parent_type: 'bar', query: { match: { foo: { query: 'bar'} } } }) end end end end ids_spec.rb000066400000000000000000000035401462737751600343360ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Ids do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(ids: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#type' do before do search.type('bar') end it 'applies the option' do expect(search.to_hash[:ids][:foo][:type]).to eq('bar') end end describe '#values' do before do search.values('bar') end it 'applies the option' do expect(search.to_hash[:ids][:foo][:values]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do type 'bar' values ['1', '2', '3'] end end it 'executes the block' do expect(search.to_hash).to eq(ids: { type: 'bar', values: ['1', '2', '3'] }) end end end end indices_spec.rb000066400000000000000000000050641462737751600352000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Indices do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(indices: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#indices' do before do search.indices('bar') end it 'applies the option' do expect(search.to_hash[:indices][:indices]).to eq('bar') end end describe '#filter' do before do search.filter('bar') end it 'applies the option' do expect(search.to_hash[:indices][:filter]).to eq('bar') end end describe '#no_match_filter' do before do search.no_match_filter('bar') end it 'applies the option' do expect(search.to_hash[:indices][:no_match_filter]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do indices 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(indices: { indices: 'bar' }) end end context 'when a block is provided to an option method' do let(:search) do described_class.new do indices 'bar' filter do term foo: 'bar' end no_match_filter do term foo: 'bam' end end end it 'executes the block' do expect(search.to_hash).to eq(indices: { indices: 'bar', filter: { term: { foo: 'bar' } }, no_match_filter: { term: { foo: 'bam' } } }) end end end end limit_spec.rb000066400000000000000000000031451462737751600346760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Limit do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(limit: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#value' do before do search.value('bar') end it 'applies the option' do expect(search.to_hash[:limit][:foo][:value]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do value 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(limit: { value: 'bar' }) end end end end match_all_spec.rb000066400000000000000000000020201462737751600354730ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::MatchAll do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(match_all: {}) end end end missing_spec.rb000066400000000000000000000031551462737751600352320ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Missing do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(missing: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:missing][:foo][:field]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do field 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(missing: { field: 'bar' }) end end end end nested_spec.rb000066400000000000000000000040771462737751600350470ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Nested do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(nested: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#path' do before do search.path('bar') end it 'applies the option' do expect(search.to_hash[:nested][:path]).to eq('bar') end end describe '#query' do before do search.query('bar') end it 'applies the option' do expect(search.to_hash[:nested][:query]).to eq('bar') end end describe '#filter' do before do search.filter('bar') end it 'applies the option' do expect(search.to_hash[:nested][:filter]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do path 'bar' filter do term foo: 'bar' end end end it 'executes the block' do expect(search.to_hash).to eq(nested: { path: 'bar', filter: { term: { foo: 'bar' } } }) end end end end not_spec.rb000066400000000000000000000031061462737751600343550ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Not do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(not: {}) end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(filters: [ { term: { foo: 'bar' } } ]) end it 'applies the hash' do expect(search.to_hash).to eq(not: { filters: [ { term: { foo: 'bar' } } ] }) end end context 'when a block is provided' do let(:search) do described_class.new do term foo: 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(not: { term: { foo: 'bar' } }) end end end end or_spec.rb000066400000000000000000000036571462737751600342100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Or do let(:search) do described_class.new end it 'responds to enumerable methods' do expect(search.empty?).to be(true) end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(or: {}) end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(filters: [ { term: { foo: 'bar' } } ]) end it 'applies the hash' do expect(search.to_hash).to eq(or: { filters: [ { term: { foo: 'bar' } } ] }) end end context 'when a block is provided' do let(:search) do described_class.new do term foo: 'bar' term moo: 'mam' end end it 'executes the block' do expect(search.to_hash).to eq(or: [ {term: { foo: 'bar'}}, {term: { moo: 'mam'}} ]) end end end context 'when the filter is appended to' do before do search << { term: { foo: 'bar' } } end it 'appends the predicate' do expect(search.to_hash).to eq(or: [ { term: { foo: 'bar' } } ]) end end end prefix_spec.rb000066400000000000000000000024201462737751600350500ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Prefix do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(prefix: {}) end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(foo: 'bar') end it 'applies the hash' do expect(search.to_hash).to eq(prefix: { foo: 'bar' }) end end end end query_spec.rb000066400000000000000000000031021462737751600347160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Query do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(query: {}) end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(query_string: { query: 'foo' }) end it 'applies the hash' do expect(search.to_hash).to eq(query: { query_string: { query: 'foo' } }) end end context 'when a block is provided' do let(:search) do described_class.new do match foo: 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(query: { match: { foo: 'bar' } }) end end end end range_spec.rb000066400000000000000000000047331462737751600346600ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Range do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(range: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#gte' do before do search.gte('bar') end it 'applies the option' do expect(search.to_hash[:range][:foo][:gte]).to eq('bar') end end describe '#lte' do before do search.lte('bar') end it 'applies the option' do expect(search.to_hash[:range][:foo][:lte]).to eq('bar') end end describe '#time_zone' do before do search.time_zone('bar') end it 'applies the option' do expect(search.to_hash[:range][:foo][:time_zone]).to eq('bar') end end describe '#format' do before do search.format('bar') end it 'applies the option' do expect(search.to_hash[:range][:foo][:format]).to eq('bar') end end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(age: { gte: 10, lte: 20 }) end it 'applies the hash' do expect(search.to_hash).to eq(range: { age: { gte: 10, lte: 20 } }) end end context 'when a block is provided' do let(:search) do described_class.new(:age) do gte 10 lte 20 end end it 'executes the block' do expect(search.to_hash).to eq(range: { age: { gte: 10, lte: 20 } }) end end end end regexp_spec.rb000066400000000000000000000040441462737751600350510ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Regexp do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(regexp: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#value' do before do search.value('bar') end it 'applies the option' do expect(search.to_hash[:regexp][:foo][:value]).to eq('bar') end end describe '#flags' do before do search.flags('bar') end it 'applies the option' do expect(search.to_hash[:regexp][:foo][:flags]).to eq('bar') end end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(foo: 'b.*r') end it 'applies the hash' do expect(search.to_hash).to eq(regexp: { foo: 'b.*r' }) end end context 'when a block is provided' do let(:search) do described_class.new(:foo) do value 'b*r' end end it 'executes the block' do expect(search.to_hash).to eq(regexp: { foo: { value: 'b*r' } }) end end end end script_spec.rb000066400000000000000000000035221462737751600350630ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Script do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(script: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#script' do before do search.script('bar') end it 'applies the option' do expect(search.to_hash[:script][:foo][:script]).to eq('bar') end end describe '#params' do before do search.params(foo: 'bar') end it 'applies the option' do expect(search.to_hash[:script][:foo][:params]).to eq(foo: 'bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do script 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(script: { foo: { script: 'bar' } }) end end end end term_spec.rb000066400000000000000000000030241462737751600345230ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Term do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(term: {}) end end describe '#initialize' do context 'when a scalar is specified' do let(:search) do described_class.new(message: 'test') end it 'sets the value' do expect(search.to_hash).to eq(term: { message: 'test' }) end end context 'when a hash is specified' do let(:search) do described_class.new(message: { query: 'test' }) end it 'sets the value' do expect(search.to_hash).to eq(term: { message: { query: 'test' } }) end end end end terms_spec.rb000066400000000000000000000024361462737751600347140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Terms do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(terms: {}) end end describe '#initialize' do context 'when a hash is specified' do let(:search) do described_class.new(foo: ['abc', 'xyz']) end it 'sets the value' do expect(search.to_hash).to eq(terms: { foo: ['abc', 'xyz'] }) end end end end type_spec.rb000066400000000000000000000031601462737751600345360ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/filters# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Filters::Type do let(:search) do described_class.new end describe '#to_hash' do it 'can be converted to a hash' do expect(search.to_hash).to eq(type: {}) end end context 'when options methods are called' do let(:search) do described_class.new(:foo) end describe '#value' do before do search.value('bar') end it 'applies the option' do expect(search.to_hash[:type][:foo][:value]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do value 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(type: { foo: { value: 'bar' } }) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries/000077500000000000000000000000001462737751600323025ustar00rootroot00000000000000bool_spec.rb000066400000000000000000000166701462737751600345270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Bool do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(bool: {}) end end describe '#initialize' do context 'when an object instance is provided' do let(:search) do described_class.new.must(Elasticsearch::DSL::Search::Queries::Match.new foo: 'bar') end it 'applies the condition' do expect(search.to_hash).to eq(bool: {must: [ {match: { foo: 'bar' }} ] }) end context 'when multiple option methods are called' do let(:search) do described_class.new do should(Elasticsearch::DSL::Search::Queries::Term.new(tag: 'wow')) should(Elasticsearch::DSL::Search::Queries::Term.new(tag: 'elasticsearch')) minimum_should_match 1 boost 1.0 end end it 'defines all the options' do expect(search.to_hash).to eq(bool: { minimum_should_match: 1, boost: 1.0, should: [ {term: { tag: 'wow' }}, {term: { tag: 'elasticsearch' }} ]}) end end context 'when multiple conditions are provided' do let(:search) do described_class.new do must(Elasticsearch::DSL::Search::Queries::Match.new foo: 'bar') must(Elasticsearch::DSL::Search::Queries::Match.new moo: 'bam') should(Elasticsearch::DSL::Search::Queries::Match.new xoo: 'bax') should(Elasticsearch::DSL::Search::Queries::Match.new zoo: 'baz') end end it 'applies each condition' do expect(search.to_hash).to eq(bool: { must: [ {match: { foo: 'bar' }}, {match: { moo: 'bam' }} ], should: [ {match: { xoo: 'bax' }}, {match: { zoo: 'baz' }} ] }) end context 'when #to_hash is called more than once' do it 'does not alter the hash' do expect(search.to_hash).to eq(search.to_hash) end end end end context 'when a block is provided' do let(:search) do described_class.new do must { match foo: 'bar' } end end it 'executes the block' do expect(search.to_hash).to eq(bool: {must: [ {match: { foo: 'bar' }} ] }) end context 'when multiple option methods are called' do let(:search) do described_class.new do should { term tag: 'wow' } should { term tag: 'elasticsearch' } minimum_should_match 1 boost 1.0 end end it 'defines all the options' do expect(search.to_hash).to eq(bool: { minimum_should_match: 1, boost: 1.0, should: [ {term: { tag: 'wow' }}, {term: { tag: 'elasticsearch' }} ]}) end end context 'when multiple conditions are provided' do let(:search) do described_class.new do must do match foo: 'bar' end must do match moo: 'bam' end should do match xoo: 'bax' end should do match zoo: 'baz' end end end it 'applies each condition' do expect(search.to_hash).to eq(bool: { must: [ {match: { foo: 'bar' }}, {match: { moo: 'bam' }} ], should: [ {match: { xoo: 'bax' }}, {match: { zoo: 'baz' }} ] }) end context 'when #to_hash is called more than once' do it 'does not alter the hash' do expect(search.to_hash).to eq(search.to_hash) end end end end end context 'when options methods are called' do let(:search) do described_class.new end before do search.must { match foo: 'bar' } search.must { match moo: 'bam' } search.should { match xoo: 'bax' } end it 'applies the option' do expect(search.to_hash).to eq(bool: { must: [ {match: { foo: 'bar' }}, {match: { moo: 'bam' }} ], should: [ {match: { xoo: 'bax' }} ] }) end end context 'when the filter method is called multiple times' do let(:search) do described_class.new end before do search.filter { term foo: 'bar' } search.filter { term zoo: 'baz' } end it 'combines the filter clauses' do expect(search.to_hash).to eq(bool: { filter: [ { term: { foo: "bar"}}, { term: { zoo: "baz"}} ] }) end end context 'when methods are chained' do let(:search) do described_class.new end before do search.must { match foo: 'bar' }.must { match moo: 'bam' }.should { match xoo: 'bax' } end it 'applies the option' do expect(search.to_hash).to eq(bool: { must: [ {match: { foo: 'bar' }}, {match: { moo: 'bam' }} ], should: [ {match: { xoo: 'bax' }} ] }) end end describe '#filter' do context 'when a block is used to define the filter' do let(:search) do described_class.new do filter do term foo: 'Foo!' end end end it 'applies the filter' do expect(search.to_hash).to eq(bool: { filter: [{ term: { foo: 'Foo!' } }] }) end end context 'when a filter is passed as an argument' do context 'when the filter is a hash' do let(:search) do described_class.new do filter(term: { foo: 'Foo!' }) end end it 'applies the filter' do expect(search.to_hash).to eq(bool: { filter: [{ term: { foo: 'Foo!' } }] }) end end context 'when the filter is a `Elasticsearch::DSL::Search::Filter` object' do let(:search) do filter_object = Elasticsearch::DSL::Search::Filter.new do term bar: 'Bar!' end described_class.new do filter(filter_object) end end it 'applies the filter' do expect(search.to_hash).to eq(bool: { filter: [{ term: { bar: 'Bar!' } }] }) end end end end end boosting_spec.rb000066400000000000000000000042251462737751600354110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Boosting do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(boosting: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#positive' do before do search.positive('bar') end it 'applies the option' do expect(search.to_hash[:boosting][:positive]).to eq('bar') end end describe '#negative' do before do search.negative('bar') end it 'applies the option' do expect(search.to_hash[:boosting][:negative]).to eq('bar') end end describe '#negative_boost' do before do search.negative_boost('bar') end it 'applies the option' do expect(search.to_hash[:boosting][:negative_boost]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do positive foo: 'bar' negative moo: 'xoo' end end it 'executes the block' do expect(search.to_hash[:boosting][:positive][:foo]).to eq('bar') expect(search.to_hash[:boosting][:negative][:moo]).to eq('xoo') end end end end common_spec.rb000066400000000000000000000056001462737751600350530ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Common do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(common: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#query' do before do search.query('bar') end it 'applies the option' do expect(search.to_hash[:common][:query]).to eq('bar') end end describe '#cutoff_frequency' do before do search.cutoff_frequency('bar') end it 'applies the option' do expect(search.to_hash[:common][:cutoff_frequency]).to eq('bar') end end describe '#low_freq_operator' do before do search.low_freq_operator('bar') end it 'applies the option' do expect(search.to_hash[:common][:low_freq_operator]).to eq('bar') end end describe '#minimum_should_match' do before do search.minimum_should_match('bar') end it 'applies the option' do expect(search.to_hash[:common][:minimum_should_match]).to eq('bar') end end describe '#boost' do before do search.boost('bar') end it 'applies the option' do expect(search.to_hash[:common][:boost]).to eq('bar') end end describe '#analyzer' do before do search.analyzer('bar') end it 'applies the option' do expect(search.to_hash[:common][:analyzer]).to eq('bar') end end describe '#disable_coord' do before do search.disable_coord('bar') end it 'applies the option' do expect(search.to_hash[:common][:disable_coord]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do query 'bar' end end it 'executes the block' do expect(search.to_hash[:common][:query]).to eq('bar') end end end end constant_score_spec.rb000066400000000000000000000041131462737751600366050ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::ConstantScore do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(constant_score: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#query' do before do search.query('bar') end it 'applies the option' do expect(search.to_hash[:constant_score][:query]).to eq('bar') end end describe '#filter' do before do search.filter('bar') end it 'applies the option' do expect(search.to_hash[:constant_score][:filter]).to eq('bar') end end describe '#boost' do before do search.boost('bar') end it 'applies the option' do expect(search.to_hash[:constant_score][:boost]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do query do term foo: 'bar' end end end it 'executes the block' do expect(search.to_hash[:constant_score][:query][:term][:foo]).to eq('bar') end end end end dis_max_spec.rb000066400000000000000000000040161462737751600352070ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::DisMax do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(dis_max: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#tie_breaker' do before do search.tie_breaker('bar') end it 'applies the option' do expect(search.to_hash[:dis_max][:tie_breaker]).to eq('bar') end end describe '#boost' do before do search.boost('bar') end it 'applies the option' do expect(search.to_hash[:dis_max][:boost]).to eq('bar') end end describe '#queries' do before do search.queries('bar') end it 'applies the option' do expect(search.to_hash[:dis_max][:queries]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do tie_breaker 'bar' end end it 'executes the block' do expect(search.to_hash[:dis_max][:tie_breaker]).to eq('bar') end end end end exists_spec.rb000066400000000000000000000031411462737751600351000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Exists do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(exists: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#field' do before do search.field('bar') end it 'applies the option' do expect(search.to_hash[:exists][:field]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do field 'bar' end end it 'executes the block' do expect(search.to_hash[:exists][:field]).to eq('bar') end end end end filtered_spec.rb000066400000000000000000000042371462737751600353660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Filtered do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(filtered: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#query' do before do search.query('bar') end it 'applies the option' do expect(search.to_hash[:filtered][:query]).to eq('bar') end end describe '#filter' do before do search.filter('bar') end it 'applies the option' do expect(search.to_hash[:filtered][:filter]).to eq('bar') end end describe '#strategy' do before do search.strategy('bar') end it 'applies the option' do expect(search.to_hash[:filtered][:strategy]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do query do match foo: 'BLAM' end filter do term bar: 'slam' end end end it 'executes the block' do expect(search.to_hash).to eq(filtered: { query: { match: { foo: 'BLAM' } }, filter: { term: { bar: 'slam' } } }) end end end end function_score_spec.rb000066400000000000000000000073441462737751600366120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::FunctionScore do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(function_score: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#query' do before do search.query('bar') end it 'applies the option' do expect(search.to_hash[:function_score][:query]).to eq('bar') end end describe '#filter' do before do search.filter('bar') end it 'applies the option' do expect(search.to_hash[:function_score][:filter]).to eq('bar') end end describe '#functions' do before do search.functions('bar') end it 'applies the option' do expect(search.to_hash[:function_score][:functions]).to eq('bar') end context 'when the option is called as a setter' do before do search.functions = [ {foo: { abc: '123' }} ] end it 'applies the option' do expect(search.to_hash).to eq(function_score: { functions: [ {foo: { abc: '123' }} ] }) end end end describe '#script_score' do before do search.script_score('bar') end it 'applies the option' do expect(search.to_hash[:function_score][:script_score]).to eq('bar') end end describe '#boost' do before do search.boost('bar') end it 'applies the option' do expect(search.to_hash[:function_score][:boost]).to eq('bar') end end describe '#max_boost' do before do search.max_boost('bar') end it 'applies the option' do expect(search.to_hash[:function_score][:max_boost]).to eq('bar') end end describe '#score_mode' do before do search.score_mode('bar') end it 'applies the option' do expect(search.to_hash[:function_score][:score_mode]).to eq('bar') end end describe '#boost_mode' do before do search.boost_mode('bar') end it 'applies the option' do expect(search.to_hash[:function_score][:boost_mode]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do query do match foo: 'BLAM' end filter do term bar: 'slam' end functions << { foo: { abc: '123' } } functions << { foo: { xyz: '456' } } end end it 'executes the block' do expect(search.to_hash).to eq(function_score: { query: { match: { foo: 'BLAM' } }, filter: { term: { bar: 'slam' } }, functions: [ { foo: { abc: '123' } }, { foo: { xyz: '456' } } ] }) end end end end fuzzy_like_this_field_spec.rb000066400000000000000000000057531462737751600401610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::FuzzyLikeThisField do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(fuzzy_like_this_field: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#like_text' do before do search.like_text('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy_like_this_field][:like_text]).to eq('bar') end end describe '#fuzziness' do before do search.fuzziness('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy_like_this_field][:fuzziness]).to eq('bar') end end describe '#analyzer' do before do search.analyzer('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy_like_this_field][:analyzer]).to eq('bar') end end describe '#max_query_terms' do before do search.max_query_terms('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy_like_this_field][:max_query_terms]).to eq('bar') end end describe '#prefix_length' do before do search.prefix_length('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy_like_this_field][:prefix_length]).to eq('bar') end end describe '#boost' do before do search.boost('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy_like_this_field][:boost]).to eq('bar') end end describe '#ignore_tf' do before do search.ignore_tf('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy_like_this_field][:ignore_tf]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do like_text 'bar' end end it 'executes the block' do expect(search.to_hash[:fuzzy_like_this_field][:like_text]).to eq('bar') end end end end fuzzy_like_this_spec.rb000066400000000000000000000060111462737751600370020ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::FuzzyLikeThis do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(fuzzy_like_this: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#fields' do before do search.fields('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy_like_this][:fields]).to eq('bar') end end describe '#like_text' do before do search.like_text('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy_like_this][:like_text]).to eq('bar') end end describe '#fuzziness' do before do search.fuzziness('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy_like_this][:fuzziness]).to eq('bar') end end describe '#analyzer' do before do search.analyzer('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy_like_this][:analyzer]).to eq('bar') end end describe '#max_query_terms' do before do search.max_query_terms('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy_like_this][:max_query_terms]).to eq('bar') end end describe '#prefix_length' do before do search.prefix_length('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy_like_this][:prefix_length]).to eq('bar') end end describe '#boost' do before do search.boost('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy_like_this][:boost]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do fields ['foo'] like_text 'bar' end end it 'executes the block' do expect(search.to_hash[:fuzzy_like_this][:like_text]).to eq('bar') expect(search.to_hash[:fuzzy_like_this][:fields]).to eq(['foo']) end end end end fuzzy_spec.rb000066400000000000000000000046401462737751600347550ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Fuzzy do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(fuzzy: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#value' do before do search.value('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy][:value]).to eq('bar') end end describe '#boost' do before do search.boost('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy][:boost]).to eq('bar') end end describe '#fuzziness' do before do search.fuzziness('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy][:fuzziness]).to eq('bar') end end describe '#prefix_length' do before do search.prefix_length('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy][:prefix_length]).to eq('bar') end end describe '#max_expansions' do before do search.max_expansions('bar') end it 'applies the option' do expect(search.to_hash[:fuzzy][:max_expansions]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do value 'bar' end end it 'executes the block' do expect(search.to_hash[:fuzzy][:value]).to eq('bar') end end end end geo_shape_spec.rb000066400000000000000000000035251462737751600355210ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::GeoShape do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(geo_shape: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#shape' do before do search.shape('bar') end it 'applies the option' do expect(search.to_hash[:geo_shape][:shape]).to eq('bar') end end describe '#indexed_shape' do before do search.indexed_shape('bar') end it 'applies the option' do expect(search.to_hash[:geo_shape][:indexed_shape]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do shape 'bar' end end it 'executes the block' do expect(search.to_hash[:geo_shape][:foo][:shape]).to eq('bar') end end end end has_child_spec.rb000066400000000000000000000054371462737751600355110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::HasChild do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(has_child: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#type' do before do search.type('bar') end it 'applies the option' do expect(search.to_hash[:has_child][:type]).to eq('bar') end end describe '#query' do before do search.query('bar') end it 'applies the option' do expect(search.to_hash[:has_child][:query]).to eq('bar') end end describe '#score_mode' do before do search.score_mode('bar') end it 'applies the option' do expect(search.to_hash[:has_child][:score_mode]).to eq('bar') end end describe '#min_children' do before do search.min_children('bar') end it 'applies the option' do expect(search.to_hash[:has_child][:min_children]).to eq('bar') end end describe '#max_children' do before do search.max_children('bar') end it 'applies the option' do expect(search.to_hash[:has_child][:max_children]).to eq('bar') end end describe '#inner_hits' do before do search.inner_hits(size: 1) end it 'applies the option' do expect(search.to_hash[:has_child][:inner_hits]).to eq(size: 1) end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do type 'bar' query do match :foo do query 'bar' end end end end it 'executes the block' do expect(search.to_hash).to eq(has_child: { type: 'bar', query: { match: { foo: { query: 'bar'} } } }) end end end end has_parent_spec.rb000066400000000000000000000045141462737751600357120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::HasParent do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(has_parent: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#parent_type' do before do search.parent_type('bar') end it 'applies the option' do expect(search.to_hash[:has_parent][:parent_type]).to eq('bar') end end describe '#query' do before do search.query('bar') end it 'applies the option' do expect(search.to_hash[:has_parent][:query]).to eq('bar') end end describe '#score_mode' do before do search.score_mode('bar') end it 'applies the option' do expect(search.to_hash[:has_parent][:score_mode]).to eq('bar') end end describe '#inner_hits' do before do search.inner_hits(size: 1) end it 'applies the option' do expect(search.to_hash[:has_parent][:inner_hits]).to eq(size: 1) end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do parent_type 'bar' query match: { foo: 'bar' } end end it 'executes the block' do expect(search.to_hash).to eq(has_parent: { parent_type: 'bar', query: { match: { foo: 'bar' } } }) end end end end ids_spec.rb000066400000000000000000000035021462737751600343410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Ids do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(ids: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#type' do before do search.type('bar') end it 'applies the option' do expect(search.to_hash[:ids][:type]).to eq('bar') end end describe '#values' do before do search.values('bar') end it 'applies the option' do expect(search.to_hash[:ids][:values]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do type 'bar' values [1, 2, 3] end end it 'executes the block' do expect(search.to_hash).to eq(ids: { type: 'bar', values: [1, 2, 3] }) end end end end indices_spec.rb000066400000000000000000000041311462737751600351770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Indices do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(indices: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#indices' do before do search.indices('bar') end it 'applies the option' do expect(search.to_hash[:indices][:indices]).to eq('bar') end end describe '#query' do before do search.query('bar') end it 'applies the option' do expect(search.to_hash[:indices][:query]).to eq('bar') end end describe '#no_match_query' do before do search.no_match_query('bar') end it 'applies the option' do expect(search.to_hash[:indices][:no_match_query]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do indices 'bar' query term: { foo: 'bar' } end end it 'executes the block' do expect(search.to_hash).to eq(indices: { indices: 'bar', query: { term: { foo: 'bar' } } } ) end end end end match_all_spec.rb000066400000000000000000000031561462737751600355130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::MatchAll do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(match_all: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#boost' do before do search.boost('bar') end it 'applies the option' do expect(search.to_hash[:match_all][:boost]).to eq('bar') end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do boost 'bar' end end it 'executes the block' do expect(search.to_hash).to eq(match_all: { boost: 'bar' }) end end end end match_phrase_prefix_spec.rb000066400000000000000000000050131462737751600375740ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::MatchPhrasePrefix do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(match_phrase_prefix: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#query' do before do search.query('bar') end it 'applies the option' do expect(search.to_hash[:match_phrase_prefix][:query]).to eq('bar') end end describe '#boost' do before do search.boost(10) end it 'applies the option' do expect(search.to_hash[:match_phrase_prefix][:boost]).to eq(10) end end describe '#max_expansions' do before do search.max_expansions(2) end it 'applies the option' do expect(search.to_hash[:match_phrase_prefix][:max_expansions]).to eq(2) end end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(message: 'test') end it 'sets the value' do expect(search.to_hash).to eq(match_phrase_prefix: { message: 'test' }) end end context 'when a block is provided' do let(:search) do described_class.new do query 'test' boost 2 max_expansions 1 end end it 'executes the block' do expect(search.to_hash[:match_phrase_prefix][:query]).to eq('test') expect(search.to_hash[:match_phrase_prefix][:boost]).to eq(2) expect(search.to_hash[:match_phrase_prefix][:max_expansions]).to eq(1) end end end end match_phrase_spec.rb000066400000000000000000000051761462737751600362310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::MatchPhrase do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(match_phrase: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#query' do before do search.query('bar') end it 'applies the option' do expect(search.to_hash[:match_phrase][:query]).to eq('bar') end end describe '#analyzer' do before do search.analyzer('standard') end it 'applies the option' do expect(search.to_hash[:match_phrase][:analyzer]).to eq('standard') end end describe '#boost' do before do search.boost(10) end it 'applies the option' do expect(search.to_hash[:match_phrase][:boost]).to eq(10) end end describe '#slop' do before do search.slop(1) end it 'applies the option' do expect(search.to_hash[:match_phrase][:slop]).to eq(1) end end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(message: { query: 'test' }) end it 'sets the value' do expect(search.to_hash).to eq(match_phrase: { message: { query: 'test' } }) end end context 'when a block is provided' do let(:search) do described_class.new do query 'test' slop 1 boost 2 end end it 'executes the block' do expect(search.to_hash[:match_phrase][:query]).to eq('test') expect(search.to_hash[:match_phrase][:boost]).to eq(2) expect(search.to_hash[:match_phrase][:slop]).to eq(1) end end end end match_spec.rb000066400000000000000000000051321462737751600346570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Match do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(match: {}) end end context 'when options methods are called' do let(:search) do described_class.new end describe '#query' do before do search.query('bar') end it 'applies the option' do expect(search.to_hash[:match][:query]).to eq('bar') end end describe '#operator' do before do search.operator('standard') end it 'applies the option' do expect(search.to_hash[:match][:operator]).to eq('standard') end end describe '#type' do before do search.type(10) end it 'applies the option' do expect(search.to_hash[:match][:type]).to eq(10) end end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(message: { query: 'test' }) end it 'sets the value' do expect(search.to_hash).to eq(match: { message: { query: 'test' } }) end end context 'when a block is provided' do let(:search) do described_class.new do query 'test' operator 'and' type 'phrase_prefix' boost 2 fuzziness 'AUTO' end end it 'executes the block' do expect(search.to_hash[:match][:query]).to eq('test') expect(search.to_hash[:match][:operator]).to eq('and') expect(search.to_hash[:match][:type]).to eq('phrase_prefix') expect(search.to_hash[:match][:boost]).to eq(2) expect(search.to_hash[:match][:fuzziness]).to eq('AUTO') end end end end more_like_this_spec.rb000066400000000000000000000042131462737751600365570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::MoreLikeThis do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(more_like_this: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'fields', 'like_text', 'min_term_freq', 'max_query_terms', 'docs', 'ids', 'include', 'exclude', 'percent_terms_to_match', 'stop_words', 'min_doc_freq', 'max_doc_freq', 'min_word_length', 'max_word_length', 'boost_terms', 'boost', 'analyzer' ].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:more_like_this][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do fields ['foo', 'bar'] like_text 'abc' end end it 'executes the block' do expect(search.to_hash[:more_like_this][:fields]).to eq(['foo', 'bar']) expect(search.to_hash[:more_like_this][:like_text]).to eq('abc') end end end end multi_match_spec.rb000066400000000000000000000035271462737751600360770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::MultiMatch do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(multi_match: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'query', 'fields', 'type', 'use_dis_max' ].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:multi_match][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do query 'bar' fields ['a', 'b'] end end it 'executes the block' do expect(search.to_hash[:multi_match][:fields]).to eq(['a', 'b']) expect(search.to_hash[:multi_match][:query]).to eq('bar') end end end end nested_spec.rb000066400000000000000000000045031462737751600350460ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Nested do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(nested: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'path', 'score_mode', 'score_mode', 'query' ].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:nested][option.to_sym]).to eq('bar') end end describe '#inner_hits' do before do search.inner_hits(size: 1) end it 'applies the option' do expect(search.to_hash[:nested][:inner_hits]).to eq(size: 1) end end describe '#query' do before do search.query(match: { foo: 'bar' }) end it 'applies the option' do expect(search.to_hash[:nested][:query]).to eq(match: { foo: 'bar' }) end end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do path 'bar' query do match foo: 'bar' end end end it 'executes the block' do expect(search.to_hash[:nested][:path]).to eq('bar') expect(search.to_hash[:nested][:query]).to eq(match: { foo: 'bar' }) end end end end prefix_spec.rb000066400000000000000000000032731462737751600350640ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Prefix do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(prefix: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'value', 'boost'].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:prefix][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do value 'bar' end end it 'executes the block' do expect(search.to_hash[:prefix][:value]).to eq('bar') end end end end query_string_spec.rb000066400000000000000000000042661462737751600363250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::QueryString do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(query_string: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'query', 'fields', 'type', 'default_field', 'default_operator', 'allow_leading_wildcard', 'lowercase_expanded_terms', 'enable_position_increments', 'fuzzy_max_expansions', 'fuzziness', 'fuzzy_prefix_length', 'phrase_slop', 'boost', 'analyze_wildcard', 'auto_generate_phrase_queries', 'minimum_should_match', 'lenient', 'locale', 'use_dis_max', 'tie_breaker', 'time_zone'].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:query_string][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do query 'foo AND bar' end end it 'executes the block' do expect(search.to_hash[:query_string][:query]).to eq('foo AND bar') end end end end range_spec.rb000066400000000000000000000037001462737751600346560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Range do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(range: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'gte', 'lte', 'boost', 'format'].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:range][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do gte 10 lte 20 boost 2 format 'mm/dd/yyyy' end end it 'executes the block' do expect(search.to_hash[:range][:gte]).to eq(10) expect(search.to_hash[:range][:lte]).to eq(20) expect(search.to_hash[:range][:boost]).to eq(2) expect(search.to_hash[:range][:format]).to eq('mm/dd/yyyy') end end end end regexp_spec.rb000066400000000000000000000036661462737751600350670ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Regexp do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(regexp: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'value', 'boost', 'flags'].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:regexp][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(foo: 'b.*r') end it 'sets the value' do expect(search.to_hash[:regexp][:foo]).to eq('b.*r') end end context 'when a block is provided' do let(:search) do described_class.new(:foo) do value 'bar' end end it 'executes the block' do expect(search.to_hash[:regexp][:foo][:value]).to eq('bar') end end end end simple_query_string_spec.rb000066400000000000000000000035061462737751600376720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::SimpleQueryString do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(simple_query_string: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'query', 'fields', 'default_operator', 'analyzer', 'flags', 'lenient'].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:simple_query_string][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new(:foo) do query 'bar' end end it 'executes the block' do expect(search.to_hash[:simple_query_string][:foo][:query]).to eq('bar') end end end end span_first_spec.rb000066400000000000000000000032741462737751600357400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::SpanFirst do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(span_first: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'match' ].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:span_first][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do match 'bar' end end it 'executes the block' do expect(search.to_hash[:span_first][:match]).to eq('bar') end end end end span_multi_spec.rb000066400000000000000000000032741462737751600357430ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::SpanMulti do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(span_multi: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'match' ].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:span_multi][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do match 'bar' end end it 'executes the block' do expect(search.to_hash[:span_multi][:match]).to eq('bar') end end end end span_near_spec.rb000066400000000000000000000033761462737751600355410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::SpanNear do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(span_near: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'span_near', 'slop', 'in_order', 'collect_payloads' ].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:span_near][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do span_near 'bar' end end it 'executes the block' do expect(search.to_hash[:span_near][:span_near]).to eq('bar') end end end end span_not_spec.rb000066400000000000000000000033641462737751600354110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::SpanNot do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(span_not: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'include', 'exclude', 'pre', 'post', 'dist' ].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:span_not][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do include 'bar' end end it 'executes the block' do expect(search.to_hash[:span_not][:include]).to eq('bar') end end end end span_or_spec.rb000066400000000000000000000032661462737751600352320ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::SpanOr do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(span_or: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'clauses' ].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:span_or][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do clauses 'bar' end end it 'executes the block' do expect(search.to_hash[:span_or][:clauses]).to eq('bar') end end end end span_term_spec.rb000066400000000000000000000024321462737751600355530ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::SpanTerm do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(span_term: {}) end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(foo: 'bar') end it 'sets the value' do expect(search.to_hash[:span_term][:foo]).to eq('bar') end end end end template_spec.rb000066400000000000000000000041511462737751600353760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Template do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(template: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'query', 'params' ].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:template][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(query: 'bar', params: { foo: 'abc' }) end it 'sets the value' do expect(search.to_hash[:template][:query]).to eq('bar') expect(search.to_hash[:template][:params][:foo]).to eq('abc') end end context 'when a block is provided' do let(:search) do described_class.new do query 'bar' params foo: 'abc' end end it 'executes the block' do expect(search.to_hash[:template][:query]).to eq('bar') expect(search.to_hash[:template][:params][:foo]).to eq('abc') end end end end term_spec.rb000066400000000000000000000030501462737751600345270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Term do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(term: {}) end end describe '#initialize' do context 'when a String is provided' do let(:search) do described_class.new(message: 'test') end it 'executes the block' do expect(search.to_hash[:term][:message]).to eq('test') end end context 'when a hash is provided' do let(:search) do described_class.new(message: { query: 'test', boost: 2 }) end it 'sets the value' do expect(search.to_hash[:term][:message]).to eq(query: 'test', boost: 2) end end end end terms_spec.rb000066400000000000000000000024401462737751600347140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Terms do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(terms: {}) end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(foo: ['abc', 'xyz']) end it 'sets the value' do expect(search.to_hash[:terms]).to eq(foo: ['abc', 'xyz']) end end end end top_children_spec.rb000066400000000000000000000044161462737751600362410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::TopChildren do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(top_children: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'type', 'query', 'score', 'factor', 'incremental_factor', '_scope' ].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:top_children][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a block is provided' do let(:search) do described_class.new do type 'bar' query 'foo' end end it 'executes the block' do expect(search.to_hash[:top_children][:type]).to eq('bar') expect(search.to_hash[:top_children][:query]).to eq('foo') end end context 'when nested blocks are provided' do let(:search) do described_class.new do type 'bar' query do match foo: 'BLAM' end end end it 'executes the block' do expect(search.to_hash[:top_children][:type]).to eq('bar') expect(search.to_hash[:top_children][:query][:match][:foo]).to eq('BLAM') end end end end wildcard_spec.rb000066400000000000000000000036441462737751600353620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/elasticsearch/dsl/search/queries# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::DSL::Search::Queries::Wildcard do describe '#to_hash' do let(:search) do described_class.new end it 'can be converted to a hash' do expect(search.to_hash).to eq(wildcard: {}) end end context 'when options methods are called' do let(:search) do described_class.new end [ 'value', 'boost' ].each do |option| describe "##{option}" do before do search.send(option, 'bar') end it 'applies the option' do expect(search.to_hash[:wildcard][option.to_sym]).to eq('bar') end end end end describe '#initialize' do context 'when a hash is provided' do let(:search) do described_class.new(foo: 'bar') end it 'sets the value' do expect(search.to_hash[:wildcard][:foo]).to eq('bar') end end context 'when a block is provided' do let(:search) do described_class.new do value 'bar' end end it 'executes the block' do expect(search.to_hash[:wildcard][:value]).to eq('bar') end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/spec/spec_helper.rb000066400000000000000000000016301462737751600266020ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'elasticsearch' require 'elasticsearch-dsl' RSpec.configure do |config| config.formatter = 'documentation' config.color = true end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/000077500000000000000000000000001462737751600240115ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/integration/000077500000000000000000000000001462737751600263345ustar00rootroot00000000000000search_aggregation_children_test.rb000066400000000000000000000075201462737751600353310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/integration# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class ChildrenAggregationIntegrationTest < ::Elasticsearch::Test::IntegrationTestCase include Elasticsearch::DSL::Search context "A children aggregation" do startup do Elasticsearch::Extensions::Test::Cluster.start(number_of_nodes: 1) if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?(number_of_nodes: 1) end setup do @client.indices.create index: 'articles-and-comments', body: { mappings: { properties: { title: {type: 'text'}, category: {type: 'keyword'}, join_field: {type: 'join', relations: {article: 'comment'}}, author: {type: 'keyword'} } } } @client.index index: 'articles-and-comments', id: 1, body: { title: 'A', category: 'one', join_field: 'article' } @client.index index: 'articles-and-comments', id: 2, body: { title: 'B', category: 'one', join_field: 'article' } @client.index index: 'articles-and-comments', id: 3, body: { title: 'C', category: 'two', join_field: 'article' } @client.index index: 'articles-and-comments', routing: '1', body: { author: 'John', join_field: { name: 'comment', parent: 1 } } @client.index index: 'articles-and-comments', routing: '1', body: { author: 'Mary', join_field: { name: 'comment', parent: 1 } } @client.index index: 'articles-and-comments', routing: '2', body: { author: 'John', join_field: { name: 'comment', parent: 2 } } @client.index index: 'articles-and-comments', routing: '2', body: { author: 'Dave', join_field: { name: 'comment', parent: 2 } } @client.index index: 'articles-and-comments', routing: '3', body: { author: 'Ruth', join_field: { name: 'comment', parent: 3 } } @client.indices.refresh index: 'articles-and-comments' end should "return the top commenters per article category" do response = @client.search index: 'articles-and-comments', size: 0, body: search { aggregation :top_categories do terms field: 'category' do aggregation :comments do children type: 'comment' do aggregation :top_authors do terms field: 'author' end end end end end }.to_hash assert_equal 'one', response['aggregations']['top_categories']['buckets'][0]['key'] assert_equal 3, response['aggregations']['top_categories']['buckets'][0]['comments']['top_authors']['buckets'].size assert_equal 'John', response['aggregations']['top_categories']['buckets'][0]['comments']['top_authors']['buckets'][0]['key'] end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/integration/search_aggregation_geo_test.rb000066400000000000000000000101611462737751600343650ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class GeoAggregationIntegrationTest < ::Elasticsearch::Test::IntegrationTestCase include Elasticsearch::DSL::Search context "A geo aggregation" do startup do Elasticsearch::Extensions::Test::Cluster.start(number_of_nodes: 1) if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?(number_of_nodes: 1) end setup do @client.indices.create index: 'venues-test', body: { mappings: { properties: { location: {type: 'geo_point'} } } } @client.index index: 'venues-test', body: { name: 'Space', location: "38.886214,1.403889" } @client.index index: 'venues-test', body: { name: 'Pacha', location: "38.9184427,1.4433646" } @client.index index: 'venues-test', body: { name: 'Amnesia', location: "38.948045,1.408341" } @client.index index: 'venues-test', body: { name: 'Privilege', location: "38.958082,1.408288" } @client.index index: 'venues-test', body: { name: 'Es Paradis', location: "38.979071,1.307394" } @client.indices.refresh index: 'venues-test' end should "return the geo distances from a location" do response = @client.search index: 'venues-test', size: 0, body: search { aggregation :venue_distances do geo_distance do field :location origin '38.9126352,1.4350621' unit 'km' ranges [ { to: 1 }, { from: 1, to: 5 }, { from: 5, to: 10 }, { from: 10 } ] aggregation :top_venues do top_hits _source: { include: 'name' } end end end }.to_hash result = response['aggregations']['venue_distances'] assert_equal 4, result['buckets'].size assert_equal 1, result['buckets'][0]['doc_count'] assert_equal 'Pacha', result['buckets'][0]['top_venues']['hits']['hits'][0]['_source']['name'] assert_equal 2, result['buckets'][1]['top_venues']['hits']['total']['value'] end should "return the geohash grid distribution" do # # See the geohash plot eg. at http://openlocation.org/geohash/geohash-js/ # See the locations visually eg. at http://geohash.org/sncj8h17r2 # response = @client.search index: 'venues-test', size: 0, body: search { aggregation :venue_distributions do geohash_grid do field :location precision 5 aggregation :top_venues do top_hits _source: { include: 'name' } end end end }.to_hash result = response['aggregations']['venue_distributions'] assert_equal 4, result['buckets'].size assert_equal 'sncj8', result['buckets'][0]['key'] assert_equal 2, result['buckets'][0]['doc_count'] assert_same_elements %w[ Privilege Amnesia ], result['buckets'][0]['top_venues']['hits']['hits'].map { |h| h['_source']['name'] } end end end end end search_aggregation_nested_test.rb000066400000000000000000000107531462737751600350250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/integration# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class NestedAggregationIntegrationTest < ::Elasticsearch::Test::IntegrationTestCase include Elasticsearch::DSL::Search context "A nested aggregation" do startup do Elasticsearch::Extensions::Test::Cluster.start(number_of_nodes: 1) if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?(number_of_nodes: 1) end setup do @client.indices.create index: 'products-test', body: { mappings: { properties: { title: {type: 'text'}, category: {type: 'keyword'}, offers: { type: 'nested', properties: { name: {type: 'text'}, price: {type: 'double'} } } } } } @client.index index: 'products-test', body: { title: 'A', category: 'audio', offers: [ { name: 'A1', price: 100 }, { name: 'A2', price: 120 } ] } @client.index index: 'products-test', body: { title: 'B', category: 'audio', offers: [ { name: 'B1', price: 200 }, { name: 'B2', price: 180 } ] } @client.index index: 'products-test', body: { title: 'C', category: 'video', offers: [ { name: 'C1', price: 300 }, { name: 'C2', price: 350 } ] } @client.indices.refresh index: 'products-test' end should "return the minimal price from offers" do response = @client.search index: 'products-test', body: search { query { match title: 'A' } aggregation :offers do nested do path 'offers' aggregation :min_price do min field: 'offers.price' end end end }.to_hash assert_equal 100, response['aggregations']['offers']['min_price']['value'].to_i end should "return the top categories for offer price range" do response = @client.search index: 'products-test', body: search { query do bool do must do nested do path 'offers' query do bool do filter do range 'offers.price' do gte 100 lte 300 end end end end end end end end aggregation :offers do nested do path 'offers' aggregation :top_categories do reverse_nested do aggregation :top_category_per_offer do terms field: 'category' end end end end end }.to_hash assert_equal 2, response['aggregations']['offers']['top_categories']['top_category_per_offer']['buckets'].size assert_equal 'audio', response['aggregations']['offers']['top_categories']['top_category_per_offer']['buckets'][0]['key'] assert_equal 'video', response['aggregations']['offers']['top_categories']['top_category_per_offer']['buckets'][1]['key'] end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/integration/search_aggregations_test.rb000066400000000000000000000246031462737751600337240ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class AggregationsIntegrationTest < ::Elasticsearch::Test::IntegrationTestCase include Elasticsearch::DSL::Search context "Aggregations integration" do setup do @client.indices.create index: 'test', body: { mappings: { properties: { tags: {type: 'keyword'} } } } @client.index index: 'test', id: '1', body: { title: 'A', tags: %w[one], clicks: 5 } @client.index index: 'test', id: '2', body: { title: 'B', tags: %w[one two], clicks: 15 } @client.index index: 'test', id: '3', body: { title: 'C', tags: %w[one three], clicks: 20 } @client.indices.refresh index: 'test' end context "with a terms aggregation" do should "return tag counts" do response = @client.search index: 'test', body: search { aggregation :tags do terms field: 'tags' end }.to_hash assert_equal 3, response['aggregations']['tags']['buckets'].size assert_equal 'one', response['aggregations']['tags']['buckets'][0]['key'] end should "return approximate tag counts" do response = @client.search index: 'test', body: search { aggregation :tags do cardinality field: 'tags' end }.to_hash assert_equal 3, response['aggregations']['tags']['value'] end should "return tag counts per clicks range as an inner (nested) aggregation" do response = @client.search index: 'test', body: search { aggregation :clicks do range field: 'clicks' do key :low, to: 10 key :mid, from: 10, to: 20 aggregation :tags do terms field: 'tags' end end end }.to_hash assert_equal 2, response['aggregations']['clicks']['buckets'].size assert_equal 1, response['aggregations']['clicks']['buckets']['low']['doc_count'] assert_equal 'one', response['aggregations']['clicks']['buckets']['low']['tags']['buckets'][0]['key'] end should "define multiple aggregations" do response = @client.search index: 'test', body: search { aggregation :clicks do range field: 'clicks' do key :low, to: 10 key :mid, from: 10, to: 20 aggregation :tags do terms { field 'tags' } end end end aggregation :min_clicks do min field: 'clicks' end aggregation :max_clicks do max field: 'clicks' end aggregation :sum_clicks do sum field: 'clicks' end aggregation :avg_clicks do avg field: 'clicks' end }.to_hash assert_equal 2, response['aggregations']['clicks']['buckets'].size assert_equal 1, response['aggregations']['clicks']['buckets']['low']['doc_count'] assert_equal 'one', response['aggregations']['clicks']['buckets']['low']['tags']['buckets'][0]['key'] assert_equal 5, response['aggregations']['min_clicks']['value'] assert_equal 20, response['aggregations']['max_clicks']['value'] assert_equal 40, response['aggregations']['sum_clicks']['value'] assert_equal 13, response['aggregations']['avg_clicks']['value'].to_i end should "define a global aggregation" do response = @client.search index: 'test', body: search { query do bool filter: { terms: { tags: ['two'] } } end aggregation :avg_clicks do avg field: 'clicks' end aggregation :all_documents do global do aggregation :avg_clicks do avg field: 'clicks' end end end }.to_hash assert_equal 15, response['aggregations']['avg_clicks']['value'].to_i assert_equal 13, response['aggregations']['all_documents']['avg_clicks']['value'].to_i end should "return statistics on clicks" do response = @client.search index: 'test', body: search { aggregation :stats_clicks do stats field: 'clicks' end aggregation :value_count do value_count field: 'clicks' end }.to_hash assert_equal 3, response['aggregations']['stats_clicks']['count'] assert_equal 5, response['aggregations']['stats_clicks']['min'] assert_equal 20, response['aggregations']['stats_clicks']['max'] assert_equal 40, response['aggregations']['stats_clicks']['sum'] assert_equal 13, response['aggregations']['stats_clicks']['avg'].to_i assert_equal 3, response['aggregations']['value_count']['value'] end should "return percentiles on clicks" do response = @client.search index: 'test', body: search { aggregation :percentiles do percentiles field: 'clicks' end }.to_hash assert_equal 20, response['aggregations']['percentiles']['values']['99.0'].round end should "return percentile ranks on clicks" do response = @client.search index: 'test', body: search { aggregation :percentiles do percentile_ranks field: 'clicks', values: [5] end }.to_hash assert_equal 17, response['aggregations']['percentiles']['values']['5.0'].round end should "return top hits per tag" do response = @client.search index: 'test', body: search { aggregation :tags do terms do field 'tags' size 5 aggregation :top_hits do top_hits sort: [ clicks: { order: 'desc' } ], _source: { include: 'title' } end end end }.to_hash assert_equal 3, response['aggregations']['tags']['buckets'][0]['top_hits']['hits']['hits'].size assert_equal 'C', response['aggregations']['tags']['buckets'][0]['top_hits']['hits']['hits'][0]['_source']['title'] end should "calculate clicks for a tag" do response = @client.search index: 'test', body: search { aggregation :clicks_for_one do scripted_metric do init_script "state.transactions = []" map_script "if (doc['tags'].value.contains('one')) { state.transactions.add(doc['clicks'].value) }" combine_script "double sum = 0; for (t in state.transactions) { sum += t } return sum" reduce_script "double sum = 0; for (a in states) { sum += a } return sum" end end }.to_hash assert_equal 40, response['aggregations']['clicks_for_one']['value'] end should "limit the scope with a filter" do response = @client.search index: 'test', body: search { aggregation :clicks_for_one do filter terms: { tags: ['one'] } do aggregation :sum_clicks do sum field: 'clicks' end end end }.to_hash assert_equal 40, response['aggregations']['clicks_for_one']['sum_clicks']['value'] end end should "return aggregations for multiple filters" do response = @client.search index: 'test', body: search { aggregation :avg_clicks_per_tag do filters do filters one: { terms: { tags: ['one'] } }, two: { terms: { tags: ['two'] } } aggregation :avg do avg field: 'clicks' end end end }.to_hash assert_equal 13, response['aggregations']['avg_clicks_per_tag']['buckets']['one']['avg']['value'].to_i assert_equal 15, response['aggregations']['avg_clicks_per_tag']['buckets']['two']['avg']['value'].to_i end should "return a histogram on clicks" do response = @client.search index: 'test', body: search { aggregation :clicks_histogram do histogram do field 'clicks' interval 10 end end }.to_hash assert_equal 3, response['aggregations']['clicks_histogram']['buckets'].size assert_equal 10, response['aggregations']['clicks_histogram']['buckets'][1]['key'] assert_equal 1, response['aggregations']['clicks_histogram']['buckets'][1]['doc_count'] end should "return a histogram with empty buckets on clicks" do response = @client.search index: 'test', body: search { aggregation :clicks_histogram do histogram do field 'clicks' interval 2 min_doc_count 0 end end }.to_hash assert_equal 9, response['aggregations']['clicks_histogram']['buckets'].size end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/integration/search_filters_test.rb000066400000000000000000000233171462737751600327230ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # encoding: UTF-8 require 'test_helper' module Elasticsearch module Test class FiltersIntegrationTest < ::Elasticsearch::Test::IntegrationTestCase include Elasticsearch::DSL::Search context "Filters integration" do startup do Elasticsearch::Extensions::Test::Cluster.start(number_of_nodes: 1) if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?(number_of_nodes: 1) end setup do @client.indices.create index: 'test' @client.index index: 'test', id: 1, body: { name: 'Original', color: 'red', size: 'xxl', category: 'unisex', manufacturer: 'a' } @client.index index: 'test', id: 2, body: { name: 'Original', color: 'red', size: 'xl', category: 'unisex', manufacturer: 'a' } @client.index index: 'test', id: 3, body: { name: 'Original', color: 'red', size: 'l', category: 'unisex', manufacturer: 'a' } @client.index index: 'test', id: 4, body: { name: 'Western', color: 'red', size: 'm', category: 'men', manufacturer: 'c' } @client.index index: 'test', id: 5, body: { name: 'Modern', color: 'grey', size: 'l', category: 'men', manufacturer: 'b' } @client.index index: 'test', id: 6, body: { name: 'Modern', color: 'grey', size: 's', category: 'men', manufacturer: 'b' } @client.index index: 'test', id: 7, body: { name: 'Modern', color: 'grey', size: 's', category: 'women', manufacturer: 'b' } @client.indices.refresh index: 'test' end context "term filter" do should "return matching documents" do response = @client.search index: 'test', body: search { query do bool do filter do term color: 'red' end end end }.to_hash assert_equal 4, response['hits']['total']['value'] assert response['hits']['hits'].all? { |h| h['_source']['color'] == 'red' }, response.inspect end end context "terms filter" do should "return matching documents" do response = @client.search index: 'test', body: search { query do bool do filter do terms color: ['red', 'grey', 'gold'] end end end }.to_hash assert_equal 7, response['hits']['total']['value'] end end context "bool filter" do should "return correct documents" do response = @client.search index: 'test', body: search { query do bool do filter do bool do must do term size: 'l' end should do term color: 'red' end should do term category: 'men' end must_not do term manufacturer: 'b' end end end end end }.to_hash assert_equal 1, response['hits']['hits'].size assert_equal '3', response['hits']['hits'][0]['_id'].to_s end end context "geographical filters" do setup do @client.indices.create index: 'places', body: { mappings: { properties: { location: { type: 'geo_point' } } } } @client.index index: 'places', id: 1, body: { name: 'Vyšehrad', location: '50.064399, 14.420018'} @client.index index: 'places', id: 2, body: { name: 'Karlštejn', location: '49.939518, 14.188046'} @client.indices.refresh index: 'places' end should "find documents within the bounding box" do response = @client.search index: 'places', body: search { query do bool do filter do geo_bounding_box :location do top_right "50.1815123678,14.7149200439" bottom_left "49.9415476869,14.2162566185" end end end end }.to_hash assert_equal 1, response['hits']['hits'].size assert_equal 'Vyšehrad', response['hits']['hits'][0]['_source']['name'] end should "find documents within the distance specified with a hash" do response = @client.search index: 'places', body: search { query do bool do filter do geo_distance location: '50.090223,14.399590', distance: '5km' end end end }.to_hash assert_equal 1, response['hits']['hits'].size assert_equal 'Vyšehrad', response['hits']['hits'][0]['_source']['name'] end should "find documents within the distance specified with a block" do response = @client.search index: 'places', body: search { query do bool do filter do geo_distance :location do lat '50.090223' lon '14.399590' distance '5km' end end end end }.to_hash assert_equal 1, response['hits']['hits'].size assert_equal 'Vyšehrad', response['hits']['hits'][0]['_source']['name'] end should "find documents within the geographical distance range" do response = @client.search index: 'places', body: search { query do bool do filter do geo_distance location: { lat: '50.090223', lon: '14.399590' }, distance: '50km' end end end aggregation :distance_ranges do geo_distance do field :location origin '50.090223,14.399590' unit 'km' ranges [ { from: 10, to: 50 } ] aggregation :results do top_hits _source: { include: 'name' } end end end }.to_hash assert_equal 2, response['hits']['hits'].size bucket = response['aggregations']['distance_ranges']['buckets'][0] assert_equal 1, bucket['doc_count'] assert_equal 1, bucket['results']['hits']['hits'].size assert_equal 'Karlštejn', bucket['results']['hits']['hits'][0]['_source']['name'] end should "find documents within the polygon" do response = @client.search index: 'places', body: search { query do bool do filter do geo_polygon :location do points [ [14.2244355,49.9419006], [14.2244355,50.1774301], [14.7067869,50.1774301], [14.7067869,49.9419006], [14.2244355,49.9419006] ] end end end end }.to_hash assert_equal 1, response['hits']['hits'].size assert_equal 'Vyšehrad', response['hits']['hits'][0]['_source']['name'] end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/integration/search_options_test.rb000066400000000000000000000031341462737751600327410ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class SearchOptionsIntegrationTest < ::Elasticsearch::Test::IntegrationTestCase include Elasticsearch::DSL::Search context "Search options" do setup do @client.indices.create index: 'test' @client.index index: 'test', id: '1', body: { title: 'Test' } @client.index index: 'test', id: '2', body: { title: 'Rest' } @client.indices.refresh index: 'test' end should "explain the match" do response = @client.search index: 'test', body: search { query { match title: 'test' } explain true }.to_hash assert_equal 1, response['hits']['total']['value'] assert_not_nil response['hits']['hits'][0]['_explanation'] end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/integration/search_query_test.rb000066400000000000000000000067071462737751600324240ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class QueryIntegrationTest < ::Elasticsearch::Test::IntegrationTestCase include Elasticsearch::DSL::Search context "Queries integration" do startup do Elasticsearch::Extensions::Test::Cluster.start(number_of_nodes: 1) if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?(number_of_nodes: 1) end setup do @client.indices.create index: 'test' @client.index index: 'test', id: '1', body: { title: 'Test', tags: ['one'] } @client.index index: 'test', id: '2', body: { title: 'Rest', tags: ['one', 'two'] } @client.indices.refresh index: 'test' end context "for match query" do should "find the document" do response = @client.search index: 'test', body: search { query { match title: 'test' } }.to_hash assert_equal 1, response['hits']['total']['value'] end end context "for match_phrase_prefix query" do should "find the document" do response = @client.search index: 'test', body: search { query { match_phrase_prefix title: 'te' } }.to_hash assert_equal 1, response['hits']['total']['value'] end end context "for query_string query" do should "find the document" do response = @client.search index: 'test', body: search { query { query_string { query 'te*' } } }.to_hash assert_equal 1, response['hits']['total']['value'] end end context "for the bool query" do should "find the document" do response = @client.search index: 'test', body: search { query do bool do must { terms tags: ['one'] } should { match title: 'Test' } end end }.to_hash assert_equal 2, response['hits']['total']['value'] assert_equal 'Test', response['hits']['hits'][0]['_source']['title'] end should "find the document with a filter" do skip "Not supported on this Elasticsearch version" unless @version > '2' response = @client.search index: 'test', body: search { query do bool do filter { terms tags: ['one'] } filter { terms tags: ['two'] } end end }.to_hash assert_equal 1, response['hits']['total']['value'] assert_equal 'Rest', response['hits']['hits'][0]['_source']['title'] end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/integration/search_size_from_test.rb000066400000000000000000000044251462737751600332470ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class SizeIntegrationTest < ::Elasticsearch::Test::IntegrationTestCase include Elasticsearch::DSL::Search context "Search results pagination" do setup do @client.indices.create index: 'test', body: { mappings: { properties: { title: { type: 'text', fields: { keyword: { type: 'keyword' } } } } } } 25.times { |i| @client.index index: 'test', id: i, body: { title: "Test #{sprintf('%03d', i)}" } } @client.indices.refresh index: 'test' end should "find the correct number of documents" do response = @client.search index: 'test', body: search { query { match title: 'test' } size 15 }.to_hash assert_equal 25, response['hits']['total']['value'] assert_equal 15, response['hits']['hits'].size end should "move the offset" do response = @client.search index: 'test', body: search { query { match(:title) { query 'test' } } size 5 from 5 sort { by 'title.keyword' } }.to_hash assert_equal 25, response['hits']['total']['value'] assert_equal 5, response['hits']['hits'].size assert_equal 'Test 005', response['hits']['hits'][0]['_source']['title'] assert_equal 'Test 009', response['hits']['hits'][4]['_source']['title'] end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/integration/search_sort_test.rb000066400000000000000000000037201462737751600322360ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class SortingIntegrationTest < ::Elasticsearch::Test::IntegrationTestCase include Elasticsearch::DSL::Search context "Sorting integration" do startup do Elasticsearch::Extensions::Test::Cluster.start(number_of_nodes: 1) if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?(number_of_nodes: 1) end setup do @client.indices.create index: 'test' @client.index index: 'test', id: '1', body: { tags: ['one'], clicks: 15 } @client.index index: 'test', id: '2', body: { tags: ['one', 'two'], clicks: 5 } @client.index index: 'test', id: '3', body: { tags: ['one', 'three'], clicks: 20 } @client.indices.refresh index: 'test' end context "sorting by clicks" do should "return documents in order" do response = @client.search index: 'test', body: search { sort do by :clicks, order: 'desc' end }.to_hash assert_same_elements ['3', '1', '2'], response['hits']['hits'].map { |d| d['_id'] } end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/integration/search_suggest_test.rb000066400000000000000000000065121462737751600327320ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # encoding: UTF-8 require 'test_helper' module Elasticsearch module Test class SuggestIntegrationTest < ::Elasticsearch::Test::IntegrationTestCase include Elasticsearch::DSL::Search context "Suggest integration" do startup do Elasticsearch::Extensions::Test::Cluster.start(number_of_nodes: 1) if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?(number_of_nodes: 1) end setup do @client.indices.create index: 'test', body: { mappings: { properties: { title: {type: 'text'}, suggest: { type: 'object', properties: { title: {type: 'completion'}, payload: {type: 'object', enabled: false} } } } } } @client.index index: 'test', id: '1', body: { title: 'One', suggest: { title: { input: ['one', 'uno', 'jedna'] }, payload: { id: '1' } } } @client.index index: 'test', id: '2', body: { title: 'Two', suggest: { title: { input: ['two', 'due', 'dvě'] }, payload: { id: '2' } } } @client.index index: 'test', id: '3', body: { title: 'Three', suggest: { title: { input: ['three', 'tres', 'tři'] }, payload: { id: '3' } } } @client.indices.refresh index: 'test' end should "return suggestions" do s = search do suggest :title, text: 't', completion: { field: 'suggest.title' } end response = @client.search index: 'test', body: s.to_hash assert_equal 2, response['suggest']['title'][0]['options'].size assert_same_elements %w[2 3], response['suggest']['title'][0]['options'].map { |d| d['_source']['suggest']['payload']['id'] } end should "return a single suggestion" do s = search do suggest :title, text: 'th', completion: { field: 'suggest.title' } end response = @client.search index: 'test', body: s.to_hash assert_equal 1, response['suggest']['title'][0]['options'].size assert_same_elements %w[3], response['suggest']['title'][0]['options'].map { |d| d['_source']['suggest']['payload']['id'] } end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/integration/search_test.rb000066400000000000000000000050021462737751600311620ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class SearchIntegrationTest < ::Elasticsearch::Test::IntegrationTestCase include Elasticsearch::DSL::Search class MySearch include Elasticsearch::DSL::Search def initialize(q) @q = q end def tags %w[ one two ] end def search_definition search do |q| q.query do |q| q.bool do |q| q.must do |q| q.match title: @q end q.must do |q| q.terms tags: tags end end end end end end context "The Search class" do startup do Elasticsearch::Extensions::Test::Cluster.start(number_of_nodes: 1) if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?(number_of_nodes: 1) end setup do @client.indices.create index: 'test' @client.index index: 'test', id: '1', body: { title: 'Test', tags: ['one'] } @client.index index: 'test', id: '2', body: { title: 'Test', tags: ['one', 'two'] } @client.index index: 'test', id: '3', body: { title: 'Test', tags: ['three'] } @client.indices.refresh index: 'test' end should "have access to the calling context" do s = MySearch.new('test') response = @client.search index: 'test', body: s.search_definition.to_hash assert_equal 2, response['hits']['total']['value'] assert_equal 'Test', response['hits']['hits'][0]['_source']['title'] assert_same_elements ['1', '2'], response['hits']['hits'].map { |d| d['_id'] } end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/test_helper.rb000066400000000000000000000065261462737751600266650ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. ELASTICSEARCH_HOSTS = if hosts = ENV['TEST_ES_SERVER'] || ENV['ELASTICSEARCH_HOSTS'] hosts.split(',').map do |host| /(http\:\/\/)?(\S+)/.match(host)[2] end else ['localhost:9200'] end.freeze TEST_HOST, TEST_PORT = ELASTICSEARCH_HOSTS.first.split(':') if ELASTICSEARCH_HOSTS JRUBY = defined?(JRUBY_VERSION) if ENV['COVERAGE'] || ENV['CI'] require 'simplecov' SimpleCov.start { add_filter "/test|test_" } end at_exit { Elasticsearch::Test::IntegrationTestCase.__run_at_exit_hooks } require 'minitest/autorun' require 'shoulda-context' require 'mocha/setup' require 'minitest/reporters' Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new require 'elasticsearch' require 'elasticsearch/extensions/test/cluster' require 'elasticsearch/extensions/test/startup_shutdown' require 'elasticsearch/dsl' module Elasticsearch module Test module Assertions def assert_nothing_raised(*) yield end end class UnitTestCase < ::Minitest::Test include Assertions alias_method :assert_not_nil, :refute_nil alias_method :assert_raise, :assert_raises end class IntegrationTestCase < ::Minitest::Test include Assertions alias_method :assert_not_nil, :refute_nil alias_method :assert_raise, :assert_raises include Elasticsearch::Extensions::Test extend StartupShutdown startup do Cluster.start(number_of_nodes: 1) if ENV['SERVER'] \ && ! Elasticsearch::Extensions::Test::Cluster.running?(number_of_nodes: 1) end shutdown do Cluster.stop if ENV['SERVER'] \ && started? \ && Elasticsearch::Extensions::Test::Cluster.running? end def setup @port = (ENV['TEST_CLUSTER_PORT'] || 9250).to_i @logger = Logger.new(STDERR) @logger.formatter = proc do |severity, datetime, progname, msg| color = case severity when /INFO/ then :green when /ERROR|WARN|FATAL/ then :red when /DEBUG/ then :cyan else :white end ANSI.ansi(severity[0] + ' ', color, :faint) + ANSI.ansi(msg, :white, :faint) + "\n" end @client = Elasticsearch::Client.new(host: "#{TEST_HOST}:#{TEST_PORT}", logger: (ENV['QUIET'] ? nil : @logger)) @version = @client.info['version']['number'] end def teardown @client.indices.delete index: '_all' end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/unit/000077500000000000000000000000001462737751600247705ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/unit/dsl_test.rb000066400000000000000000000023511462737751600271370ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class DSLTest < ::Elasticsearch::Test::UnitTestCase context "The DSL" do class DummyDSLReceiver include Elasticsearch::DSL end should "include the module in receiver" do assert_contains DummyDSLReceiver.included_modules, Elasticsearch::DSL assert_contains DummyDSLReceiver.included_modules, Elasticsearch::DSL::Search end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/unit/search_aggregation_test.rb000066400000000000000000000057761462737751600322070ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class SearchAggregationTest < ::Elasticsearch::Test::UnitTestCase subject { Elasticsearch::DSL::Search::Aggregation.new } context "Search Aggregation" do should "be serializable to a Hash" do assert_equal( {}, subject.to_hash ) subject = Elasticsearch::DSL::Search::Aggregation.new subject.instance_variable_set(:@value, { foo: 'bar' }) assert_equal( { foo: 'bar' }, subject.to_hash ) end should "evaluate the block and return itself" do block = Proc.new { 1+1 } subject = Elasticsearch::DSL::Search::Aggregation.new &block subject.expects(:instance_eval) assert_instance_of Elasticsearch::DSL::Search::Aggregation, subject.call end should "call the block and return itself" do block = Proc.new { |s| 1+1 } subject = Elasticsearch::DSL::Search::Aggregation.new &block block.expects(:call) assert_instance_of Elasticsearch::DSL::Search::Aggregation, subject.call end should "define the value with DSL methods" do assert_nothing_raised do subject.terms field: 'foo' assert_instance_of Hash, subject.to_hash assert_equal( { terms: { field: 'foo' } }, subject.to_hash ) end end should "raise an exception for unknown DSL method" do assert_raise(NoMethodError) { subject.foofoo } end should "return the aggregations" do subject.expects(:call) subject.instance_variable_set(:@value, mock(aggregations: { foo: 'bar' })) subject.aggregations end should "define a nested aggregation" do subject.instance_variable_set(:@value, mock(aggregation: true)) subject.aggregation(:foo) { 1+1 } end should "return a non-hashy value directly" do subject.instance_variable_set(:@value, 'FOO') assert_equal 'FOO', subject.to_hash end should "return an empty Hash when it has no value set" do subject.instance_variable_set(:@value, nil) assert_equal({}, subject.to_hash) end end end end end search_base_aggregation_component_test.rb000066400000000000000000000041321462737751600351650ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/unit# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class BaseAggregationComponentTest < ::Elasticsearch::Test::UnitTestCase context "BaseAggregationComponent" do class DummyAggregationComponent include ::Elasticsearch::DSL::Search::BaseAggregationComponent end class ::Elasticsearch::DSL::Search::Aggregations::Dummy include ::Elasticsearch::DSL::Search::BaseAggregationComponent end subject { DummyAggregationComponent.new } should "return an instance of the aggregation by name" do assert_instance_of ::Elasticsearch::DSL::Search::Aggregations::Dummy, subject.dummy end should "raise an exception when unknown aggregation is called" do assert_raise(NoMethodError) { subject.foobar } end should "add a nested aggregation" do subject.aggregation :inner do dummy field: 'foo' end assert ! subject.aggregations.empty?, "#{subject.aggregations.inspect} is empty" assert_instance_of Elasticsearch::DSL::Search::Aggregation, subject.aggregations[:inner] assert_equal( {:dummy=>{:field=>"foo"}}, subject.aggregations[:inner].to_hash ) assert_equal 'foo', subject.to_hash[:aggregations][:inner][:dummy][:field] end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/unit/search_base_component_test.rb000066400000000000000000000152121462737751600326760ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class BaseComponentTest < ::Elasticsearch::Test::UnitTestCase context "BaseComponent" do class DummyComponent include Elasticsearch::DSL::Search::BaseComponent end class DummyComponentWithAName include Elasticsearch::DSL::Search::BaseComponent name :foo end class DummyComponentWithNewName include Elasticsearch::DSL::Search::BaseComponent end class DummyCompoundFilter include Elasticsearch::DSL::Search::BaseCompoundFilterComponent end subject { DummyComponent.new :foo } should "have a name" do assert_equal :dummy_component, DummyComponent.new.name end should "have a custom name" do assert_equal :foo, DummyComponentWithAName.new.name end should "allow to set a name" do DummyComponentWithNewName.name :foo assert_equal :foo, DummyComponentWithNewName.new.name assert_equal :foo, DummyComponentWithNewName.name DummyComponentWithNewName.name = :bar assert_equal :bar, DummyComponentWithNewName.name assert_equal :bar, DummyComponentWithNewName.new.name end should "initialize the hash" do assert_instance_of Hash, subject.to_hash end should "have an empty Hash as args by default" do subject = DummyComponentWithNewName.new assert_equal({}, subject.instance_variable_get(:@args)) end should "have an option method with args" do class DummyComponentWithOptionMethod include Elasticsearch::DSL::Search::BaseComponent option_method :bar end subject = DummyComponentWithOptionMethod.new :foo assert_respond_to subject, :bar subject.bar 'BAM' assert_equal({ dummy_component_with_option_method: { foo: { bar: 'BAM' } } }, subject.to_hash) end should "keep track of option methods" do class DummyComponentWithCustomOptionMethod include Elasticsearch::DSL::Search::BaseComponent option_method :foo end subject = DummyComponentWithCustomOptionMethod assert_includes subject.option_methods, :foo end should "have an option method without args" do class DummyComponentWithOptionMethod include Elasticsearch::DSL::Search::BaseComponent option_method :bar end subject = DummyComponentWithOptionMethod.new assert_respond_to subject, :bar subject.bar 'BAM' assert_equal({ dummy_component_with_option_method: { bar: 'BAM' } }, subject.to_hash) end should "define a custom option method" do class DummyComponentWithCustomOptionMethod include Elasticsearch::DSL::Search::BaseComponent option_method :bar, lambda { |*args| @hash = { :foo => 'bar' } } end subject = DummyComponentWithCustomOptionMethod.new subject.bar assert_equal 'bar', subject.instance_variable_get(:@hash)[:foo] end should "execute the passed block" do subject = DummyComponent.new(:foo) { @foo = 'BAR' } assert_respond_to subject, :call assert_instance_of DummyComponent, subject.call assert_equal 'BAR', subject.instance_variable_get(:@foo) end should "respond to empty?" do assert DummyComponent.new.empty? assert DummyComponent.new(:foo).empty? subject = DummyComponent.new(:foo) { @hash = { foo: 'bar' } } assert ! subject.empty? end context "to_hash conversion" do should "build the hash with the block with args" do subject = DummyComponent.new :foo do @hash[:dummy_component][:foo].update moo: 'xoo' end assert_equal({dummy_component: { foo: { moo: 'xoo' } } }, subject.to_hash ) end should "build the hash with the block without args" do subject = DummyComponent.new do @hash[:dummy_component].update moo: 'xoo' end assert_equal({dummy_component: { moo: 'xoo' } }, subject.to_hash ) end should "build the hash with the option method" do class DummyComponentWithOptionMethod include Elasticsearch::DSL::Search::BaseComponent option_method :foo end subject = DummyComponentWithOptionMethod.new do foo 'bar' end assert_equal({ dummy_component_with_option_method: { foo: 'bar' } }, subject.to_hash) end should "build the hash with the passed args" do subject = DummyComponent.new foo: 'bar' assert_equal({ dummy_component: { foo: 'bar' } }, subject.to_hash) end should "merge the top-level options to the hash" do class DummyComponentWithOptionMethod include Elasticsearch::DSL::Search::BaseComponent option_method :bar end subject = DummyComponentWithOptionMethod.new :foo, xoo: 'X' do bar 'B' end assert_equal({ dummy_component_with_option_method: { xoo: 'X', foo: { bar: 'B' } } }, subject.to_hash) end should "return the already built hash" do subject = DummyComponent.new subject.instance_variable_set(:@hash, { foo: 'bar' }) assert_equal({ foo: 'bar' }, subject.to_hash) end end context "compound filter" do subject { DummyCompoundFilter.new } should "raise an exception for unknown DSL method" do assert_raise(NoMethodError) { subject.foofoo } end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/unit/search_filter_test.rb000066400000000000000000000051451462737751600311730ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class SearchFilterTest < ::Elasticsearch::Test::UnitTestCase subject { Elasticsearch::DSL::Search::Filter.new } context "Search Filter" do should "be serializable to a Hash" do assert_equal( {}, subject.to_hash ) subject = Elasticsearch::DSL::Search::Filter.new subject.instance_variable_set(:@value, { foo: 'bar' }) assert_equal( { foo: 'bar' }, subject.to_hash ) end should "evaluate the block and return itself" do block = Proc.new { 1+1 } subject = Elasticsearch::DSL::Search::Filter.new &block subject.expects(:instance_eval) assert_instance_of Elasticsearch::DSL::Search::Filter, subject.call end should "call the block and return itself" do block = Proc.new { |s| 1+1 } subject = Elasticsearch::DSL::Search::Filter.new &block block.expects(:call) assert_instance_of Elasticsearch::DSL::Search::Filter, subject.call end should "define the value with filter methods" do assert_nothing_raised do subject.term foo: 'bar' assert_instance_of Hash, subject.to_hash assert_equal( { term: { foo: 'bar' } }, subject.to_hash ) end end should "redefine the value with filter methods" do assert_nothing_raised do subject.term foo: 'bar' subject.term foo: 'bam' subject.to_hash subject.to_hash assert_instance_of Hash, subject.to_hash assert_equal({ term: { foo: 'bam' } }, subject.to_hash) end end should "raise an exception for unknown filter" do assert_raise(NoMethodError) { subject.foofoo } end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/unit/search_highlight_test.rb000066400000000000000000000064071462737751600316570ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class HighlightTest < ::Elasticsearch::Test::UnitTestCase context "Search highlight" do subject { Elasticsearch::DSL::Search::Highlight.new } should "take a Hash" do subject = Elasticsearch::DSL::Search::Highlight.new fields: { 'foo' => {} }, pre_tags: ['*'], post_tags: ['*'] assert_equal({ fields: { 'foo' => {} }, pre_tags: ['*'], post_tags: ['*'] }, subject.to_hash) end should "encode fields as an array" do subject.fields ['foo', 'bar'] assert_equal({ fields: { foo: {}, bar: {} } }, subject.to_hash) end should "encode fields as a Hash" do subject.fields foo: { bar: 1 }, xoo: { bar: 2 } assert_equal({ fields: { foo: { bar: 1 }, xoo: { bar: 2 } } }, subject.to_hash) end should "encode a field" do subject.field 'foo' assert_equal({ fields: { foo: {} } }, subject.to_hash) end should "be additive on multiple calls" do subject.fields ['foo', 'bar'] subject.field 'bam' subject.field 'baz', { xoo: 10 } assert_equal({ fields: { foo: {}, bar: {}, bam: {}, baz: { xoo: 10 } } }, subject.to_hash) end should "encode pre_tags" do subject.pre_tags '*' assert_equal({ pre_tags: ['*'] }, subject.to_hash) end should "encode post_tags" do subject.post_tags '*' assert_equal({ post_tags: ['*'] }, subject.to_hash) end should "encode pre_tags as an array" do subject.pre_tags ['*', '**'] assert_equal({ pre_tags: ['*', '**'] }, subject.to_hash) end should "encode post_tags as an array" do subject.post_tags ['*', '**'] assert_equal({ post_tags: ['*', '**'] }, subject.to_hash) end should "encode the encoder option" do subject.encoder 'foo' assert_equal({ encoder: 'foo' }, subject.to_hash) end should "encode the tags_schema option" do subject.tags_schema 'foo' assert_equal({ tags_schema: 'foo' }, subject.to_hash) end should "combine the options" do subject.fields ['foo', 'bar'] subject.field 'bam' subject.pre_tags '*' subject.post_tags '*' assert_equal({ fields: { foo: {}, bar: {}, bam: {} }, pre_tags: ['*'], post_tags: ['*'] }, subject.to_hash) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/unit/search_options_test.rb000066400000000000000000000066461462737751600314100ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class SearchOptionsTest < ::Elasticsearch::Test::UnitTestCase subject { Elasticsearch::DSL::Search::Options.new } context "Search options" do should "combine different options" do subject.version true subject.min_score 0.5 assert_equal({version: true, min_score: 0.5}, subject.to_hash) end should "encode _source" do subject._source false assert_equal( { _source: false }, subject.to_hash ) subject._source 'foo.*' assert_equal( { _source: 'foo.*' }, subject.to_hash ) subject._source ['foo', 'bar'] assert_equal( { _source: ['foo', 'bar'] }, subject.to_hash ) subject._source include: ['foo.*'], exclude: ['bar.*'] assert_equal( { _source: { include: ['foo.*'], exclude: ['bar.*'] } }, subject.to_hash ) subject.source false assert_equal( { _source: false }, subject.to_hash ) end should "encode fields" do subject.fields ['foo'] assert_equal( { fields: ['foo'] }, subject.to_hash ) end should "encode script_fields" do subject.script_fields ['foo'] assert_equal( { script_fields: ['foo'] }, subject.to_hash ) end should "encode fielddata_fields" do subject.fielddata_fields ['foo'] assert_equal( { fielddata_fields: ['foo'] }, subject.to_hash ) end should "encode rescore" do subject.rescore foo: 'bar' assert_equal( { rescore: { foo: 'bar' } }, subject.to_hash ) end should "encode explain" do subject.explain true assert_equal( { explain: true }, subject.to_hash ) end should "encode version" do subject.version true assert_equal( { version: true }, subject.to_hash ) end should "encode track_total_hits" do subject.track_total_hits 123 assert_equal( { track_total_hits: 123 }, subject.to_hash ) subject.track_total_hits true assert_equal( { track_total_hits: true }, subject.to_hash ) end should "encode indices_boost" do subject.indices_boost foo: 'bar' assert_equal( { indices_boost: { foo: 'bar' } }, subject.to_hash ) end should "encode track_scores" do subject.track_scores true assert_equal( { track_scores: true }, subject.to_hash ) end should "encode min_score" do subject.min_score 0.5 assert_equal( { min_score: 0.5 }, subject.to_hash ) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/unit/search_query_test.rb000066400000000000000000000052741462737751600310560ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class SearchQueryTest < ::Elasticsearch::Test::UnitTestCase subject { Elasticsearch::DSL::Search::Query.new } context "Search Query" do should "be serializable to a Hash" do assert_equal( {}, subject.to_hash ) subject = Elasticsearch::DSL::Search::Query.new subject.instance_variable_set(:@value, {}) assert_equal( {}, subject.to_hash ) end should "evaluate the block and return itself" do block = Proc.new { 1+1 } subject = Elasticsearch::DSL::Search::Query.new &block subject.expects(:instance_eval) assert_instance_of Elasticsearch::DSL::Search::Query, subject.call end should "call the block and return itself" do block = Proc.new { |s| 1+1 } subject = Elasticsearch::DSL::Search::Query.new &block block.expects(:call) assert_instance_of Elasticsearch::DSL::Search::Query, subject.call end should "define the value with query methods" do assert_nothing_raised do subject.match foo: 'bar' assert_instance_of Hash, subject.to_hash assert_equal( { match: { foo: 'bar' } }, subject.to_hash ) end end should "redefine the value with query methods" do assert_nothing_raised do subject.match foo: 'bar' subject.match foo: 'bam' subject.to_hash subject.to_hash assert_instance_of Hash, subject.to_hash assert_equal({ match: { foo: 'bam' } }, subject.to_hash) end end should "have the query methods" do assert_nothing_raised { subject.match foo: 'bar' } end should "raise an exception for unknown query" do assert_raise(NoMethodError) { subject.foofoo } end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/unit/search_size_from_test.rb000066400000000000000000000037201462737751600317000ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class SearchSizeTest < ::Elasticsearch::Test::UnitTestCase context "Search pagination" do should "encode the size parameter" do subject = Elasticsearch::DSL::Search::Search.new do size 5 end assert_equal( { size: 5 }, subject.to_hash ) end should "encode the from parameter" do subject = Elasticsearch::DSL::Search::Search.new do from 5 end assert_equal( { from: 5 }, subject.to_hash ) end should "have getter methods" do subject = Elasticsearch::DSL::Search::Search.new assert_nil subject.size assert_nil subject.from subject.size = 5 subject.from = 5 assert_equal 5, subject.size assert_equal 5, subject.from end should "have setter methods" do subject = Elasticsearch::DSL::Search::Search.new subject.size = 5 subject.from = 5 assert_equal 5, subject.size assert_equal 5, subject.from assert_equal( { size: 5, from: 5 }, subject.to_hash ) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/unit/search_sort_test.rb000066400000000000000000000052671462737751600307020ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class SearchSortTest < ::Elasticsearch::Test::UnitTestCase subject { Elasticsearch::DSL::Search::Sort.new } context "Search sort" do should "add a single field" do subject = Elasticsearch::DSL::Search::Sort.new :foo assert_equal( [:foo], subject.to_hash ) end should "add multiple fields" do subject = Elasticsearch::DSL::Search::Sort.new [:foo, :bar] assert_equal( [:foo, :bar], subject.to_hash ) end should "add a field with options" do subject = Elasticsearch::DSL::Search::Sort.new foo: { order: 'desc', mode: 'avg' } assert_equal( [ { foo: { order: 'desc', mode: 'avg' } } ], subject.to_hash ) end should "add fields with the DSL method" do subject = Elasticsearch::DSL::Search::Sort.new do by :foo by :bar, order: 'desc' end assert_equal( [ :foo, { bar: { order: 'desc' } }, ], subject.to_hash ) end should "be empty" do subject = Elasticsearch::DSL::Search::Sort.new assert_equal subject.empty?, true end should "not be empty" do subject = Elasticsearch::DSL::Search::Sort.new foo: { order: 'desc' } assert_equal subject.empty?, false end context "#to_hash" do should "not duplicate values when defined by arguments" do subject = Elasticsearch::DSL::Search::Sort.new foo: { order: 'desc' } assert_equal(subject.to_hash, subject.to_hash) end should "not duplicate values when defined by a block" do subject = Elasticsearch::DSL::Search::Sort.new do by :foo end assert_equal(subject.to_hash, subject.to_hash) end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/unit/search_suggest_test.rb000066400000000000000000000024621462737751600313660ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class SearchSuggestTest < ::Elasticsearch::Test::UnitTestCase subject { Elasticsearch::DSL::Search::Suggest.new :foo } context "Search suggest" do should "be an empty hash by default" do assert_equal({ foo: {} }, subject.to_hash) end should "contain options" do subject = Elasticsearch::DSL::Search::Suggest.new :foo, boo: 'bam' assert_equal({ foo: { boo: 'bam' } }, subject.to_hash) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/unit/search_test.rb000066400000000000000000000215711462737751600276270ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class SearchTest < ::Elasticsearch::Test::UnitTestCase subject { Elasticsearch::DSL::Search::Search.new } context "The Search module" do should "have the search method on instance" do class DummySearchReceiver include Elasticsearch::DSL::Search end assert_instance_of Elasticsearch::DSL::Search::Search, DummySearchReceiver.new.search end should "have the search method on module" do class DummySearchReceiver include Elasticsearch::DSL::Search end assert_instance_of Elasticsearch::DSL::Search::Search, Elasticsearch::DSL::Search.search end should "have access to the calling context" do class DummySearchReceiver include Elasticsearch::DSL::Search def initialize @other_value = 'foo' end def value 42 end def search_definition search do |q| q.from value q.size @other_value q.stored_fields ['term'] q.filter do |q| q._and do |q| q.term thang: @other_value q.term attributes: value end end end end end assert_equal({from: 42, size: 'foo', stored_fields: ['term'], filter: { and: [ { term: { thang: 'foo' } }, { term: { attributes: 42 } }]}}, DummySearchReceiver.new.search_definition.to_hash) end end context "The Search class" do context "with query" do should "take the query as a literal value" do subject.query foo: 'bar' assert_equal({query: { foo: 'bar' }}, subject.to_hash) end should "take the query as a block" do Elasticsearch::DSL::Search::Query.expects(:new).returns({foo: 'bar'}) subject.query do; end assert_equal({query: { foo: 'bar' }}, subject.to_hash) end should "allow chaining" do assert_instance_of Elasticsearch::DSL::Search::Search, subject.query(:foo) assert_instance_of Elasticsearch::DSL::Search::Search, subject.query(:foo).query(:bar) end should "be converted to hash" do assert_equal({}, subject.to_hash) subject.query foo: 'bar' assert_equal({query: { foo: 'bar' }}, subject.to_hash) end should "have a getter/setter method" do assert_nil subject.query subject.query = Object.new assert_not_nil subject.query end end context "with filter" do should "take the filter as a literal value" do subject.filter foo: 'bar' assert_equal({filter: { foo: 'bar' }}, subject.to_hash) end should "take the filter as a block" do Elasticsearch::DSL::Search::Filter.expects(:new).returns({foo: 'bar'}) subject.filter do; end assert_equal({filter: { foo: 'bar' }}, subject.to_hash) end should "allow chaining" do assert_instance_of Elasticsearch::DSL::Search::Search, subject.filter(:foo) assert_instance_of Elasticsearch::DSL::Search::Search, subject.filter(:foo).filter(:bar) end should "be converted to hash" do assert_equal({}, subject.to_hash) subject.filter foo: 'bar' assert_equal({filter: { foo: 'bar' }}, subject.to_hash) end should "have a getter/setter method" do assert_nil subject.filter subject.filter = Object.new assert_not_nil subject.filter end end context "with post_filter" do should "take the filter as a literal value" do subject.post_filter foo: 'bar' assert_equal({post_filter: { foo: 'bar' }}, subject.to_hash) end should "take the filter as a block" do Elasticsearch::DSL::Search::Filter.expects(:new).returns({foo: 'bar'}) subject.post_filter do; end assert_equal({post_filter: { foo: 'bar' }}, subject.to_hash) end should "allow chaining" do assert_instance_of Elasticsearch::DSL::Search::Search, subject.post_filter(:foo) assert_instance_of Elasticsearch::DSL::Search::Search, subject.post_filter(:foo).post_filter(:bar) end should "be converted to hash" do assert_equal({}, subject.to_hash) subject.post_filter foo: 'bar' assert_equal({post_filter: { foo: 'bar' }}, subject.to_hash) end should "have a getter/setter method" do assert_nil subject.post_filter subject.post_filter = Object.new assert_not_nil subject.post_filter end end context "with aggregations" do should "take the aggregation as a literal value" do subject.aggregation :foo, terms: 'bar' assert_equal({aggregations: { foo: { terms: "bar" } } }, subject.to_hash) end should "take the aggregation as a block" do Elasticsearch::DSL::Search::Aggregation.expects(:new).returns({tam: 'tam'}) subject.aggregation :foo do; end assert_equal({aggregations: { foo: { tam: 'tam' } } }, subject.to_hash) end should "allow chaining" do assert_instance_of Elasticsearch::DSL::Search::Search, subject.aggregation(:foo) assert_instance_of Elasticsearch::DSL::Search::Search, subject.aggregation(:foo).aggregation(:bar) end should "be converted to hash" do assert_equal({}, subject.to_hash) subject.post_filter foo: 'bar' assert_equal({post_filter: { foo: 'bar' }}, subject.to_hash) end should "have a getter/setter method" do assert_nil subject.aggregations subject.aggregations = { foo: Object.new } assert_not_nil subject.aggregations end end context "with sorting" do should "be converted to hash" do subject.sort :foo assert_equal( { sort: [ :foo ] }, subject.to_hash ) end should "have a getter method" do assert_nil subject.sort subject.sort :foo assert_instance_of Elasticsearch::DSL::Search::Sort, subject.sort end should "have a setter method" do sort_object = Elasticsearch::DSL::Search::Sort.new foo: { order: 'desc' }, bar: { order: 'asc' } subject.sort = sort_object assert_not_nil subject.sort assert_equal( { sort: [ { foo: { order: "desc" }, bar: { order: "asc" } } ] }, subject.to_hash ) end end context "with suggest" do should "be converted to hash" do subject.suggest :foo, { bar: 'bam' } assert_equal( { suggest: { foo: { bar: 'bam' } } }, subject.to_hash ) end should "have a getter/setter method" do assert_nil subject.suggest subject.suggest = Object.new assert_not_nil subject.suggest end end context "with highlighting" do should "be converted to a hash" do subject.highlight foo: 'bar' assert_not_nil subject.highlight assert_equal( { highlight: { foo: 'bar' } }, subject.to_hash ) end end context "with options" do should "encode options" do subject.explain true subject.fields [:foo, :bar] assert_equal( { explain: true, fields: [:foo, :bar] }, subject.to_hash ) end should "raise an exception for unknown method" do assert_raise(NoMethodError) { subject.foobar true } end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-dsl/test/unit/utils_test.rb000066400000000000000000000025301462737751600275140ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class UtilsTest < ::Elasticsearch::Test::UnitTestCase context "Utils" do should "convert a string to camelcase" do assert_equal 'Foo', Elasticsearch::DSL::Utils.__camelize('foo') end should "convert an underscored string to camelcase" do assert_equal 'FooBar', Elasticsearch::DSL::Utils.__camelize('foo_bar') end should "convert a symbol" do assert_equal 'FooBar', Elasticsearch::DSL::Utils.__camelize(:foo_bar) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/000077500000000000000000000000001462737751600244475ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/.gitignore000066400000000000000000000002321462737751600264340ustar00rootroot00000000000000*.gem *.rbc .bundle .config .yardoc Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/Gemfile000066400000000000000000000027171462737751600257510ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. source 'https://rubygems.org' # Specify your gem's dependencies in elasticsearch-extensions.gemspec gemspec if File.exist? File.expand_path('../../elasticsearch-api/elasticsearch-api.gemspec', __FILE__) gem 'elasticsearch-api', path: File.expand_path('../../elasticsearch-api', __FILE__), require: false end if File.exist? File.expand_path('../../elasticsearch-transport/elasticsearch-transport.gemspec', __FILE__) gem 'elasticsearch-transport', path: File.expand_path('../../elasticsearch-transport', __FILE__), require: false end if File.exist? File.expand_path('../../elasticsearch/elasticsearch.gemspec', __FILE__) gem 'elasticsearch', path: File.expand_path('../../elasticsearch/', __FILE__) end elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/LICENSE000066400000000000000000000261361462737751600254640ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/README.md000066400000000000000000000174001462737751600257300ustar00rootroot00000000000000> :warning: **This library will be deprecated in the future** :warning: > > You'll still be able to use previous versions of this gem, but there will be no new releases following to the [0.0.33](https://rubygems.org/gems/elasticsearch-extensions/versions/0.0.33) one. > > The feature set of this gem will be migrated into the `elasticsearch` gem. > # Elasticsearch::Extensions This library provides a set of extensions to the [`elasticsearch`](https://github.com/elasticsearch/elasticsearch-ruby) Rubygem. ## Installation Install the package from [Rubygems](https://rubygems.org): gem install elasticsearch-extensions To use an unreleased version, either add it to your `Gemfile` for [Bundler](http://gembundler.com): gem 'elasticsearch-extensions', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git' or install it from a source code checkout: git clone https://github.com/elasticsearch/elasticsearch-ruby.git cd elasticsearch-ruby/elasticsearch-extensions bundle install rake install ## Extensions ### Backup Backup Elasticsearch indices as flat JSON files on the disk via integration with the [_Backup_](http://backup.github.io/backup/v4/) gem. Use the Backup gem's DSL to configure the backup: require 'elasticsearch/extensions/backup' Model.new(:elasticsearch_backup, 'Elasticsearch') do database Elasticsearch do |db| db.url = 'http://localhost:9200' db.indices = 'test' end store_with Local do |local| local.path = '/tmp/backups' end compress_with Gzip end Perform the backup with the Backup gem's command line utility: $ backup perform -t elasticsearch_backup See more information in the [`Backup::Database::Elasticsearch`](lib/elasticsearch/extensions/backup.rb) class documentation. ### ANSI Colorize and format selected Elasticsearch response parts in terminal: Display formatted search results: require 'elasticsearch/extensions/ansi' puts Elasticsearch::Client.new.search.to_ansi Display a table with the output of the `_analyze` API: require 'elasticsearch/extensions/ansi' puts Elasticsearch::Client.new.indices.analyze(text: 'Quick Brown Fox Jumped').to_ansi [Full documentation](http://rubydoc.info/gems/elasticsearch-extensions/Elasticsearch/Extensions/ANSI) ### Test::Cluster Allows to programatically start and stop an Elasticsearch cluster suitable for isolating tests. The HTTP service is running on ports `9250-*` by default. Start and stop the default cluster: require 'elasticsearch/extensions/test/cluster' Elasticsearch::Extensions::Test::Cluster.start Elasticsearch::Extensions::Test::Cluster.stop Start the cluster on specific port, with a specific Elasticsearch version, number of nodes and cluster name: require 'elasticsearch/extensions/test/cluster' Elasticsearch::Extensions::Test::Cluster.start \ cluster_name: "my-testing-cluster", command: "/usr/local/Cellar/elasticsearch/0.90.10/bin/elasticsearch", port: 9350, number_of_nodes: 3 # Starting 3 Elasticsearch nodes..................... # -------------------------------------------------------------------------------- # Cluster: my-testing-cluster # Status: green # Nodes: 3 # - node-1 | version: 1.0.0.Beta2, pid: 54469 # + node-2 | version: 1.0.0.Beta2, pid: 54470 # - node-3 | version: 1.0.0.Beta2, pid: 54468 # => true Stop this cluster: require 'elasticsearch/extensions/test/cluster' Elasticsearch::Extensions::Test::Cluster.stop port: 9350 # Stopping Elasticsearch nodes... stopped PID 54469. stopped PID 54470. stopped PID 54468. # # => [54469, 54470, 54468] You can control the cluster configuration with environment variables as well: TEST_CLUSTER_NAME=my-testing-cluster \ TEST_CLUSTER_COMMAND=/usr/local/Cellar/elasticsearch/0.90.10/bin/elasticsearch \ TEST_CLUSTER_PORT=9350 \ TEST_CLUSTER_NODES=3 \ TEST_CLUSTER_NAME=my_testing_cluster \ ruby -r elasticsearch -e "require 'elasticsearch/extensions/test/cluster'; Elasticsearch::Extensions::Test::Cluster.start" To prevent deleting data and configurations when the cluster is started, for example in a development environment, use the `clear_cluster: false` option or the `TEST_CLUSTER_CLEAR=false` environment variable. [Full documentation](http://rubydoc.info/gems/elasticsearch-extensions/Elasticsearch/Extensions/Test/Cluster) ### Test::StartupShutdown Allows to register `startup` and `shutdown` hooks for Test::Unit, similarly to RSpec's `before(:all)`, compatible with the [Test::Unit 2](https://github.com/test-unit/test-unit/blob/master/lib/test/unit/testcase.rb) syntax. The extension is useful for e.g. starting the testing Elasticsearch cluster before the test suite is executed, and stopping it afterwards. ** IMPORTANT NOTE ** You have to register the handler for `shutdown` hook before requiring 'test/unit': # File: test_helper.rb at_exit { MyTest.__run_at_exit_hooks } require 'test/unit' Example of handler registration: class MyTest < Test::Unit::TestCase extend Elasticsearch::Extensions::Test::StartupShutdown startup { puts "Suite starting up..." } shutdown { puts "Suite shutting down..." } end [Full documentation](http://rubydoc.info/gems/elasticsearch-extensions/Elasticsearch/Extensions/Test/StartupShutdown) Examples in the Elasticsearch gem test suite: [1](https://github.com/elasticsearch/elasticsearch-ruby/blob/master/elasticsearch-transport/test/integration/client_test.rb#L4-L6), [2](https://github.com/elasticsearch/elasticsearch-ruby/blob/master/elasticsearch-transport/test/test_helper.rb#L44) ### Test::Profiling Allows to define and execute profiling tests within [Shoulda](https://github.com/thoughtbot/shoulda) contexts. Measures operations and reports statistics, including code profile. Let's define a simple profiling test in a `profiling_test.rb` file: require 'test/unit' require 'shoulda/context' require 'elasticsearch/extensions/test/profiling' class ProfilingTest < Test::Unit::TestCase extend Elasticsearch::Extensions::Test::Profiling context "Mathematics" do measure "divide numbers", count: 10_000 do assert_nothing_raised { 1/2 } end end end Let's run it: $ QUIET=y ruby profiling_test.rb ... ProfilingTest ------------------------------------------------------------------------------- Context: Mathematics should divide numbers (10000x) mean: 0.03ms | avg: 0.03ms | max: 0.14ms ------------------------------------------------------------------------------- PASS (0:00:00.490) test: Mathematics should divide numbers (10000x). ... When using the `QUIET` option, only the statistics on operation throughput are printed. When omitted, the full code profile by [RubyProf](https://github.com/ruby-prof/ruby-prof) is printed. [Full documentation](http://rubydoc.info/gems/elasticsearch-extensions/Elasticsearch/Extensions/Test/StartupShutdown) [Example in the Elasticsearch gem](https://github.com/elasticsearch/elasticsearch-ruby/blob/master/elasticsearch-transport/test/profile/client_benchmark_test.rb) ## Development To work on the code, clone and bootstrap the main repository first -- please see instructions in the main [README](../README.md#development). To run tests, launch a testing cluster -- again, see instructions in the main [README](../README.md#development) -- and use the Rake tasks: ``` time rake test:unit time rake test:integration ``` Unit tests have to use Ruby 1.8 compatible syntax, integration tests can use Ruby 2.x syntax and features. ## License This software is licensed under the [Apache 2 license](./LICENSE). elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/Rakefile000066400000000000000000000052721462737751600261220ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'bundler/gem_tasks' desc 'Run unit tests' task default: 'test:unit' task test: 'test:unit' # ----- Test tasks ------------------------------------------------------------ require 'rake/testtask' namespace :test do Rake::TestTask.new(:unit) do |test| test.libs << 'lib' << 'test' test.test_files = FileList["test/**/unit/**/*_test.rb"] test.verbose = false test.warning = false end Rake::TestTask.new(:integration) do |test| test.libs << 'lib' << 'test' test.test_files = FileList["test/**/integration/**/*_test.rb"] test.verbose = false test.warning = false end Rake::TestTask.new(:all) do |test| test.libs << 'lib' << 'test' test.test_files = FileList["test/**/unit/**/*_test.rb", "test/**/integration/**/*_test.rb"] end Rake::TestTask.new(:profile) do |test| test.libs << 'lib' << 'test' test.test_files = FileList["test/profile/**/*_test.rb"] end namespace :cluster do desc "Start Elasticsearch nodes for tests" task :start do $LOAD_PATH << File.expand_path('../lib', __FILE__) << File.expand_path('../test', __FILE__) require 'elasticsearch/extensions/test/cluster' Elasticsearch::Extensions::Test::Cluster.start end desc "Stop Elasticsearch nodes for tests" task :stop do $LOAD_PATH << File.expand_path('../lib', __FILE__) << File.expand_path('../test', __FILE__) require 'elasticsearch/extensions/test/cluster' Elasticsearch::Extensions::Test::Cluster.stop end end end # ----- Documentation tasks --------------------------------------------------- require 'yard' YARD::Rake::YardocTask.new(:doc) do |t| t.options = %w| --embed-mixins --markup=markdown | end # ----- Code analysis tasks --------------------------------------------------- if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9' require 'cane/rake_task' Cane::RakeTask.new(:quality) do |cane| cane.abc_max = 15 cane.no_style = true end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/elasticsearch-extensions.gemspec000066400000000000000000000054111462737751600330240ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'elasticsearch/extensions/version' Gem::Specification.new do |s| s.name = 'elasticsearch-extensions' s.version = Elasticsearch::Extensions::VERSION s.authors = ['Karel Minarik'] s.email = ['karel.minarik@elasticsearch.org'] s.description = %q{Extensions for the Elasticsearch Rubygem} s.summary = %q{Extensions for the Elasticsearch Rubygem} s.homepage = 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.x/index.html' s.license = 'Apache-2.0' s.metadata = { 'homepage_uri' => 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.x/index.html', 'changelog_uri' => 'https://github.com/elastic/elasticsearch-ruby/blob/7.x/CHANGELOG.md', 'source_code_uri' => 'https://github.com/elastic/elasticsearch-ruby/tree/7.x/elasticsearch-extensions', 'bug_tracker_uri' => 'https://github.com/elastic/elasticsearch-ruby/issues' } s.files = `git ls-files`.split($/) s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } s.test_files = s.files.grep(%r{^(test|spec|features)/}) s.require_paths = ['lib'] s.add_dependency 'ansi' s.add_dependency 'elasticsearch' s.add_development_dependency 'awesome_print' s.add_development_dependency 'bundler' s.add_development_dependency 'cane' s.add_development_dependency 'minitest', '~> 5' s.add_development_dependency 'minitest-reporters', '~> 1' s.add_development_dependency 'mocha' s.add_development_dependency 'pry' s.add_development_dependency 'rake', '~> 13' s.add_development_dependency 'ruby-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius) s.add_development_dependency 'shoulda-context' s.add_development_dependency 'simplecov', '~> 0.17', '< 0.18' s.add_development_dependency 'yard' unless defined?(JRUBY_VERSION) s.add_development_dependency 'oj' s.add_development_dependency 'patron' end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/000077500000000000000000000000001462737751600252155ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch-extensions.rb000066400000000000000000000014531462737751600325540ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'elasticsearch/extensions' elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/000077500000000000000000000000001462737751600300275ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions.rb000066400000000000000000000016221462737751600325540ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # encoding: utf-8 require 'elasticsearch' require 'elasticsearch/extensions/version' module Elasticsearch module Extensions end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions/000077500000000000000000000000001462737751600322265ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions/ansi.rb000066400000000000000000000033311462737751600335050ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # encoding: utf-8 require 'elasticsearch/extensions' require 'ansi' require 'ansi/table' require 'ansi/terminal' require 'delegate' require 'elasticsearch/transport/transport/response' require 'elasticsearch/extensions/ansi/helpers' require 'elasticsearch/extensions/ansi/actions' require 'elasticsearch/extensions/ansi/response' module Elasticsearch module Extensions # This extension provides a {ResponseBody#to_ansi} method for the Elasticsearch response body, # which colorizes and formats the output with the `ansi` gem. # # @example Display formatted search results # # require 'elasticsearch/extensions/ansi' # puts Elasticsearch::Client.new.search.to_ansi # # @example Display a table with the output of the `_analyze` API # # require 'elasticsearch/extensions/ansi' # puts Elasticsearch::Client.new.indices.analyze(text: 'Quick Brown Fox Jumped').to_ansi # module ANSI end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions/ansi/000077500000000000000000000000001462737751600331605ustar00rootroot00000000000000actions.rb000066400000000000000000000220611462737751600350670ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions/ansi# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # encoding: utf-8 module Elasticsearch module Extensions module ANSI module Actions # Display shard allocation # def display_allocation_on_nodes(json, options={}) return unless json['routing_nodes'] output = [] << '' json['routing_nodes']['nodes'].each do |id, shards| output << (json['nodes'][id]['name'] || id).to_s.ansi(:bold) + " [#{id}]".ansi(:faint) if shards.empty? output << "No shards".ansi(:cyan) else output << Helpers.table(shards.map do |shard| [ shard['index'], shard['shard'].to_s.ansi( shard['primary'] ? :bold : :clear ), shard['primary'] ? '◼'.ansi(:green) : '◻'.ansi(:yellow) ] end) end end unless json['routing_nodes']['unassigned'].empty? output << 'Unassigned: '.ansi(:faint, :yellow) + "#{json['routing_nodes']['unassigned'].size} shards" output << Helpers.table( json['routing_nodes']['unassigned'].map do |shard| primary = shard['primary'] [ shard['index'], shard['shard'].to_s.ansi( primary ? :bold : :clear ), primary ? '◼'.ansi(:red) : '◻'.ansi(:yellow) ] end, border: false) end output.join("\n") end # Display search results # def display_hits(json, options={}) return unless json['hits'] && json['hits']['hits'] output = [] << '' hits = json['hits']['hits'] source = json['hits']['hits'].any? { |h| h['fields'] } ? 'fields' : '_source' properties = hits.map { |h| h[source] ? h[source].keys : nil }.compact.flatten.uniq max_property_length = properties.map { |d| d.to_s.size }.compact.max.to_i + 1 hits.each_with_index do |hit, i| title = hit[source] && hit[source].select { |k, v| ['title', 'name'].include?(k) }.to_a.first size_length = hits.size.to_s.size+2 padding = size_length output << "#{i+1}. ".rjust(size_length).ansi(:faint) + " <#{hit['_id']}> " + (title ? title.last.to_s.ansi(:bold) : '') output << Helpers.___ ['_score', '_index', '_type'].each do |property| output << ' '*padding + "#{property}: ".rjust(max_property_length+1).ansi(:faint) + hit[property].to_s if hit[property] end hit[source].each do |property, value| output << ' '*padding + "#{property}: ".rjust(max_property_length+1).ansi(:faint) + value.to_s end if hit[source] # Highlight if hit['highlight'] output << "" output << ' '*(padding+max_property_length+1) + "Highlights".ansi(:faint) + "\n" + ' '*(padding+max_property_length+1) + ('─'*10).ansi(:faint) hit['highlight'].each do |property, matches| line = "" line << ' '*padding + "#{property}: ".rjust(max_property_length+1).ansi(:faint) matches.each_with_index do |match, e| line << ' '*padding + ''.rjust(max_property_length+1) if e > 0 line << '…'.ansi(:faint) unless hit[source][property] && hit[source][property].size <= match.size line << match.strip.ansi(:faint).gsub(/\n/, ' ') .gsub(/([^<]+)<\/em>/, '\1'.ansi(:clear, :bold)) .ansi(:faint) line << '…'.ansi(:faint) unless hit[source][property] && hit[source][property].size <= match.size line << ' '*padding + ''.rjust(max_property_length+1) if e > 0 line << "\n" end output << line end end output << "" end output << Helpers.___ output << "#{hits.size.to_s.ansi(:bold)} of #{json['hits']['total']['value'].to_s.ansi(:bold)} results".ansi(:faint) output.join("\n") end # Display terms facets # def display_terms_facets(json, options={}) return unless json['facets'] output = [] << '' facets = json['facets'].select { |name, values| values['_type'] == 'terms' } facets.each do |name, values| longest = values['terms'].map { |t| t['term'].size }.max max = values['terms'].map { |t| t['count'] }.max padding = longest.to_i + max.to_s.size + 5 ratio = ((Helpers.width)-padding)/max.to_f output << "#{'Facet: '.ansi(:faint)}#{Helpers.humanize(name)}" << Helpers.___ values['terms'].each_with_index do |value, i| output << value['term'].ljust(longest).ansi(:bold) + " [" + value['count'].to_s.rjust(max.to_s.size) + "] " + " " + '█' * (value['count']*ratio).ceil end end output.join("\n") end # Display date histogram facets # def display_date_histogram_facets(json, options={}) return unless json['facets'] output = [] << '' facets = json['facets'].select { |name, values| values['_type'] == 'date_histogram' } facets.each do |name, values| max = values['entries'].map { |t| t['count'] }.max padding = 27 ratio = ((Helpers.width)-padding)/max.to_f interval = options[:interval] || 'day' output << "#{'Facet: '.ansi(:faint)}#{Helpers.humanize(name)} #{interval ? ('(by ' + interval + ')').ansi(:faint) : ''}" output << Helpers.___ values['entries'].each_with_index do |value, i| output << Helpers.date(Time.at(value['time'].to_i/1000).utc, interval).rjust(21).ansi(:bold) + " [" + value['count'].to_s.rjust(max.to_s.size) + "] " + " " + '█' * (value['count']*ratio).ceil end end output.join("\n") end # Display histogram facets # def display_histogram_facets(json, options={}) return unless json['facets'] output = [] << '' facets = json['facets'].select { |name, values| values['_type'] == 'histogram' } facets.each do |name, values| max = values['entries'].map { |t| t['count'] }.max padding = 27 ratio = ((Helpers.width)-padding)/max.to_f histogram = values['entries'] histogram.each_with_index do |segment, i| key = (i == 0) ? "<#{histogram[1]['key']}ms" : "#{segment['key']}ms" output << key.rjust(7) + ' ' + '█' * (segment['count']*ratio).ceil + " [#{segment['count']}]" end end output.join("\n") end # Display statistical facets # def display_statistical_facets(json, options={}) return unless json['facets'] output = [] << '' facets = json['facets'].select { |name, values| values['_type'] == 'statistical' } facets.each do |name, facet| output << "#{'Facet: '.ansi(:faint)}#{Helpers.humanize(name)}" << Helpers.___ output << Helpers.table(facet.reject { |k,v| ['_type'].include? k }.to_a.map do |pair| [ Helpers.humanize(pair[0]), pair[1] ] end) end output.join("\n") end # Display the analyze output # def display_analyze_output(json, options={}) return unless json['tokens'] output = [] << '' max_length = json['tokens'].map { |d| d['token'].to_s.size }.max output << Helpers.table(json['tokens'].map do |t| [ t['position'], t['token'].ljust(max_length+5).ansi(:bold), "#{t['start_offset']}–#{t['end_offset']}", t['type'] ] end).to_s output.join("\n") end extend self end end end end helpers.rb000066400000000000000000000046341462737751600350770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions/ansi# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # encoding: utf-8 module Elasticsearch module Extensions module ANSI module Helpers # Shortcut for {::ANSI::Table.new} # def table(data, options={}, &format) ::ANSI::Table.new(data, options, &format) end # Terminal width, based on {::ANSI::Terminal.terminal_width} # def width ::ANSI::Terminal.terminal_width-5 end # Humanize a string # def humanize(string) string.to_s.gsub(/\_/, ' ').split.map { |s| s.capitalize}.join(' ') end # Return date formatted by interval # def date(date, interval='day') case interval when 'minute' date.strftime('%a %m/%d %H:%M') + ' – ' + (date+60).strftime('%H:%M') when 'hour' date.strftime('%a %m/%d %H:%M') + ' – ' + (date+60*60).strftime('%H:%M') when 'day' date.strftime('%a %m/%d') when 'week' days_to_monday = date.wday!=0 ? date.wday-1 : 6 days_to_sunday = date.wday!=0 ? 7-date.wday : 0 start = (date - days_to_monday*24*60*60).strftime('%a %m/%d') stop = (date+(days_to_sunday*24*60*60)).strftime('%a %m/%d') "#{start} – #{stop}" when 'month' date.strftime('%B %Y') when 'year' date.strftime('%Y') else date.strftime('%Y-%m-%d %H:%M') end end # Output divider # def ___ ('─'*Helpers.width).ansi(:faint) end extend self end end end end response.rb000066400000000000000000000046531462737751600352740ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions/ansi# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Extensions module ANSI # Wrapper for the Elasticsearch response body, which adds a {#to_ansi} method # class ResponseBody < DelegateClass(Hash) def initialize(body) super(body) end # Return a [colorized and formatted](http://en.wikipedia.org/wiki/ANSI_escape_code) # representation of the Elasticsearch response for: # # * Search results (hits and highlights) # * Facets (terms, statistical, histogram, date_histogram) # * Analyze API output # * Shard allocation # # @example Display formatted search results # # require 'elasticsearch/extensions/ansi' # puts Elasticsearch::Client.new.search.to_ansi # # @todo Add all facets and handlers for remaining response parts / types # def to_ansi(options={}) output = Actions.public_methods.select do |m| m.to_s =~ /^display_/ end.map do |m| Actions.send(m, self, options) end unless output.compact.empty? output.compact.join("\n") else self.respond_to?(:awesome_inspect) ? self.awesome_inspect : self.inspect end end end end end end module Elasticsearch module Transport module Transport class Response # Wrap the response body in the {Extensions::ANSI::ResponseBody} class # def body_to_ansi Extensions::ANSI::ResponseBody.new @body end alias_method :body_original, :body alias_method :body, :body_to_ansi end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions/backup.rb000066400000000000000000000134361462737751600340270ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # encoding: utf-8 require 'pathname' require 'fileutils' require 'multi_json' begin require 'oj' rescue LoadError warn('The "oj" gem could not be loaded. JSON parsing and serialization performance may not be optimal.') end begin require 'patron' rescue LoadError warn('The "patron" gem could not be loaded. HTTP requests may not be performed optimally.') end require 'elasticsearch' module Backup module Database # Integration with the Backup gem [http://backup.github.io/backup/v4/] # # This extension allows to backup Elasticsearch indices as flat JSON files on the disk. # # @example Use the Backup gem's DSL to configure the backup # # require 'elasticsearch/extensions/backup' # # Model.new(:elasticsearch_backup, 'Elasticsearch') do # # database Elasticsearch do |db| # db.url = 'http://localhost:9200' # db.indices = 'articles,people' # db.size = 500 # db.scroll = '10m' # end # # store_with Local do |local| # local.path = '/tmp/backups' # local.keep = 3 # end # # compress_with Gzip # end # # Perform the backup with the Backup gem's command line utility: # # $ backup perform -t elasticsearch_backup # # The Backup gem can store your backup files on S3, Dropbox and other # cloud providers, send notifications about the operation, and so on; # read more in the gem documentation. # # @example Use the integration as a standalone script (eg. in a Rake task) # # require 'backup' # require 'elasticsearch/extensions/backup' # # Backup::Logger.configure do # logfile.enabled = true # logfile.log_path = '/tmp/backups/log' # end; Backup::Logger.start! # # backup = Backup::Model.new(:elasticsearch, 'Backup Elasticsearch') do # database Backup::Database::Elasticsearch do |db| # db.indices = 'test' # end # # store_with Backup::Storage::Local do |local| # local.path = '/tmp/backups' # end # end # # backup.perform! # # @example A simple recover script for the backup created in the previous examples # # PATH = '/path/to/backup/' # # require 'elasticsearch' # client = Elasticsearch::Client.new log: true # payload = [] # # Dir[ File.join( PATH, '**', '*.json' ) ].each do |file| # document = MultiJson.load(File.read(file)) # item = document.merge(data: document['_source']) # document.delete('_source') # document.delete('_score') # # payload << { index: item } # # if payload.size == 100 # client.bulk body: payload # payload = [] # end # # client.bulk body: payload # end # # @see http://backup.github.io/backup/v4/ # class Elasticsearch < Base class Error < ::Backup::Error; end attr_accessor :url, :indices, :size, :scroll attr_accessor :mode def initialize(model, database_id = nil, &block) super @url ||= 'http://localhost:9200' @indices ||= '_all' @size ||= 100 @scroll ||= '10m' @mode ||= 'single' instance_eval(&block) if block_given? end def perform! super case mode when 'single' __perform_single else raise Error, "Unsupported mode [#{mode}]" end log!(:finished) end def client @client ||= ::Elasticsearch::Client.new url: url, logger: logger end def path Pathname.new File.join(dump_path , dump_filename.downcase) end def logger logger = Backup::Logger.__send__(:logger) logger.instance_eval do def debug(*args);end # alias :debug :info alias :fatal :warn end logger end def __perform_single r = client.search index: indices, search_type: 'scan', scroll: scroll, size: size raise Error, "No scroll_id returned in response:\n#{r.inspect}" unless r['_scroll_id'] while r = client.scroll(scroll_id: r['_scroll_id'], scroll: scroll) and not r['hits']['hits'].empty? do r['hits']['hits'].each do |hit| FileUtils.mkdir_p "#{path.join hit['_index'], hit['_type']}" File.open("#{path.join hit['_index'], hit['_type'], __sanitize_filename(hit['_id'])}.json", 'w') do |file| file.write MultiJson.dump(hit) end end end end def __sanitize_filename name name .encode(Encoding::UTF_8, invalid: :replace, undef: :replace, replace: "�") .strip .tr("\u{202E}%$|:;/\t\r\n\\", "-") end end end end ::Backup::Config::DSL::Elasticsearch = ::Backup::Database::Elasticsearch elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions/test/000077500000000000000000000000001462737751600332055ustar00rootroot00000000000000cluster.rb000066400000000000000000000667111462737751600351470ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions/test# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'timeout' require 'net/http' require 'fileutils' require 'socket' require 'uri' require 'json' require 'ansi' STDOUT.sync = true STDERR.sync = true class String # Redefine the ANSI method: do not print ANSI when not running in the terminal # def ansi(*args) STDOUT.tty? ? ANSI.ansi(self, *args) : self end end module Elasticsearch module Extensions module Test # A convenience Ruby class for starting and stopping an Elasticsearch cluster, # eg. for integration tests # # @example Start a cluster with default configuration, # assuming `elasticsearch` is on $PATH. # # require 'elasticsearch/extensions/test/cluster' # Elasticsearch::Extensions::Test::Cluster.start # # @example Start a cluster with a specific Elasticsearch launch script, # eg. from a downloaded `.tar.gz` distribution # # system 'wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.1.1.tar.gz' # system 'tar -xvf elasticsearch-5.1.1.tar.gz' # # require 'elasticsearch/extensions/test/cluster' # Elasticsearch::Extensions::Test::Cluster.start command: 'elasticsearch-5.1.1/bin/elasticsearch' # # @see Cluster#initialize # module Cluster # Starts a cluster # # @see Cluster#start # def start(arguments = {}) Cluster.new(arguments).start end # Stops a cluster # # @see Cluster#stop # def stop(arguments = {}) Cluster.new(arguments).stop end # Returns true when a specific test node is running within the cluster # # @see Cluster#running? # def running?(arguments = {}) Cluster.new(arguments).running? end # Waits until the cluster is green and prints information # # @see Cluster#wait_for_green # def wait_for_green(arguments = {}) Cluster.new(arguments).wait_for_green end module_function :start, :stop, :running?, :wait_for_green class Cluster attr_reader :arguments COMMANDS = { '0.90' => lambda { |arguments, node_number| <<-COMMAND.gsub(/ /, '').gsub(/\n$/, '') #{arguments[:command]} \ -f \ -D es.cluster.name=#{arguments[:cluster_name]} \ -D es.node.name=#{arguments[:node_name]}-#{node_number} \ -D es.http.port=#{arguments[:port].to_i + (node_number-1)} \ -D es.path.data=#{arguments[:path_data]} \ -D es.path.work=#{arguments[:path_work]} \ -D es.path.logs=#{arguments[:path_logs]} \ -D es.cluster.routing.allocation.disk.threshold_enabled=false \ -D es.network.host=#{arguments[:network_host]} \ -D es.discovery.zen.ping.multicast.enabled=#{arguments[:multicast_enabled]} \ -D es.script.inline=true \ -D es.script.indexed=true \ -D es.node.test=true \ -D es.node.testattr=test \ -D es.node.bench=true \ -D es.path.repo=/tmp \ -D es.repositories.url.allowed_urls=http://snapshot.test* \ -D es.logger.level=#{ENV['DEBUG'] ? 'DEBUG' : 'INFO'} \ #{arguments[:es_params]} COMMAND }, '1.0' => lambda { |arguments, node_number| <<-COMMAND.gsub(/ /, '').gsub(/\n$/, '') #{arguments[:command]} \ -D es.foreground=yes \ -D es.cluster.name=#{arguments[:cluster_name]} \ -D es.node.name=#{arguments[:node_name]}-#{node_number} \ -D es.http.port=#{arguments[:port].to_i + (node_number-1)} \ -D es.path.data=#{arguments[:path_data]} \ -D es.path.work=#{arguments[:path_work]} \ -D es.path.logs=#{arguments[:path_logs]} \ -D es.cluster.routing.allocation.disk.threshold_enabled=false \ -D es.network.host=#{arguments[:network_host]} \ -D es.discovery.zen.ping.multicast.enabled=#{arguments[:multicast_enabled]} \ -D es.script.inline=on \ -D es.script.indexed=on \ -D es.node.test=true \ -D es.node.testattr=test \ -D es.node.bench=true \ -D es.path.repo=/tmp \ -D es.repositories.url.allowed_urls=http://snapshot.test* \ -D es.logger.level=#{ENV['DEBUG'] ? 'DEBUG' : 'INFO'} \ #{arguments[:es_params]} COMMAND }, '2.0' => lambda { |arguments, node_number| <<-COMMAND.gsub(/ /, '').gsub(/\n$/, '') #{arguments[:command]} \ -D es.foreground=yes \ -D es.cluster.name=#{arguments[:cluster_name]} \ -D es.node.name=#{arguments[:node_name]}-#{node_number} \ -D es.http.port=#{arguments[:port].to_i + (node_number-1)} \ -D es.path.data=#{arguments[:path_data]} \ -D es.path.work=#{arguments[:path_work]} \ -D es.path.logs=#{arguments[:path_logs]} \ -D es.cluster.routing.allocation.disk.threshold_enabled=false \ -D es.network.host=#{arguments[:network_host]} \ -D es.script.inline=true \ -D es.script.stored=true \ -D es.node.attr.testattr=test \ -D es.path.repo=/tmp \ -D es.repositories.url.allowed_urls=http://snapshot.test* \ -D es.logger.level=#{ENV['DEBUG'] ? 'DEBUG' : 'INFO'} \ #{arguments[:es_params]} COMMAND }, '5.0' => lambda { |arguments, node_number| <<-COMMAND.gsub(/ /, '').gsub(/\n$/, '') #{arguments[:command]} \ -E cluster.name=#{arguments[:cluster_name]} \ -E node.name=#{arguments[:node_name]}-#{node_number} \ -E http.port=#{arguments[:port].to_i + (node_number-1)} \ -E path.data=#{arguments[:path_data]} \ -E path.logs=#{arguments[:path_logs]} \ -E cluster.routing.allocation.disk.threshold_enabled=false \ -E network.host=#{arguments[:network_host]} \ -E script.inline=true \ -E script.stored=true \ -E node.attr.testattr=test \ -E path.repo=/tmp \ -E repositories.url.allowed_urls=http://snapshot.test* \ -E discovery.zen.minimum_master_nodes=#{arguments[:number_of_nodes]-1} \ -E node.max_local_storage_nodes=#{arguments[:number_of_nodes]} \ -E logger.level=#{ENV['DEBUG'] ? 'DEBUG' : 'INFO'} \ #{arguments[:es_params]} COMMAND }, '6.0' => lambda { |arguments, node_number| <<-COMMAND.gsub(/ /, '').gsub(/\n$/, '') #{arguments[:command]} \ -E cluster.name=#{arguments[:cluster_name]} \ -E node.name=#{arguments[:node_name]}-#{node_number} \ -E http.port=#{arguments[:port].to_i + (node_number-1)} \ -E path.data=#{arguments[:path_data]} \ -E path.logs=#{arguments[:path_logs]} \ -E cluster.routing.allocation.disk.threshold_enabled=false \ -E network.host=#{arguments[:network_host]} \ -E node.attr.testattr=test \ -E path.repo=/tmp \ -E repositories.url.allowed_urls=http://snapshot.test* \ -E discovery.zen.minimum_master_nodes=#{arguments[:number_of_nodes]-1} \ -E xpack.security.enabled=false \ -E node.max_local_storage_nodes=#{arguments[:number_of_nodes]} \ -E logger.level=#{ENV['DEBUG'] ? 'DEBUG' : 'INFO'} \ #{arguments[:es_params]} COMMAND } } COMMANDS['7.0'] = COMMANDS['6.0'].clone COMMANDS['8.0'] = COMMANDS['7.0'].clone COMMANDS.freeze # Create a new instance of the Cluster class # # @option arguments [String] :cluster_name Cluster name (default: `elasticsearch_test`) # @option arguments [Integer] :number_of_nodes Number of desired nodes (default: 2) # @option arguments [String] :command Elasticsearch command (default: `elasticsearch`) # @option arguments [String] :port Starting port number; will be auto-incremented (default: 9250) # @option arguments [String] :node_name The node name (will be appended with a number) # @option arguments [String] :path_data Path to the directory to store data in # @option arguments [String] :path_work Path to the directory with auxiliary files # @option arguments [String] :path_logs Path to the directory with log files # @option arguments [Boolean] :multicast_enabled Whether multicast is enabled (default: true) # @option arguments [Integer] :timeout Timeout when starting the cluster (default: 60) # @option arguments [Integer] :timeout_version Timeout when waiting for `elasticsearch --version` (default: 15) # @option arguments [String] :network_host The host that nodes will bind on and publish to # @option arguments [Boolean] :clear_cluster Wipe out cluster content on startup (default: true) # @option arguments [Boolean] :quiet Disable printing to STDERR (default: false) # # You can also use environment variables to set the constructor options (see source). # # @see Cluster#start # def initialize(arguments={}) @arguments = arguments.dup @arguments[:command] ||= ENV.fetch('TEST_CLUSTER_COMMAND', 'elasticsearch') @arguments[:port] ||= ENV.fetch('TEST_CLUSTER_PORT', 9250).to_i @arguments[:cluster_name] ||= ENV.fetch('TEST_CLUSTER_NAME', __default_cluster_name).chomp @arguments[:node_name] ||= ENV.fetch('TEST_CLUSTER_NODE_NAME', 'node') @arguments[:path_data] ||= ENV.fetch('TEST_CLUSTER_DATA', '/tmp/elasticsearch_test') @arguments[:path_work] ||= ENV.fetch('TEST_CLUSTER_TMP', '/tmp') @arguments[:path_logs] ||= ENV.fetch('TEST_CLUSTER_LOGS', '/tmp/log/elasticsearch') @arguments[:es_params] ||= ENV.fetch('TEST_CLUSTER_PARAMS', '') @arguments[:multicast_enabled] ||= ENV.fetch('TEST_CLUSTER_MULTICAST', 'true') @arguments[:timeout] ||= ENV.fetch('TEST_CLUSTER_TIMEOUT', 60).to_i @arguments[:timeout_version] ||= ENV.fetch('TEST_CLUSTER_TIMEOUT_VERSION', 15).to_i @arguments[:number_of_nodes] ||= ENV.fetch('TEST_CLUSTER_NODES', 2).to_i @arguments[:network_host] ||= ENV.fetch('TEST_CLUSTER_NETWORK_HOST', __default_network_host) @arguments[:quiet] ||= ! ENV.fetch('QUIET', '').empty? @clear_cluster = if @arguments[:clear_cluster].nil? (ENV.fetch('TEST_CLUSTER_CLEAR', 'true') != 'false') else !!@arguments[:clear_cluster] end # Make sure `cluster_name` is not dangerous raise ArgumentError, "The `cluster_name` argument cannot be empty string or a slash" \ if @arguments[:cluster_name] =~ /^[\/\\]?$/ end # Starts a cluster # # Launches the specified number of nodes in a test-suitable configuration and prints # information about the cluster -- unless this specific cluster is already running. # # @example Start a cluster with the default configuration (2 nodes, installed version, etc) # Elasticsearch::Extensions::Test::Cluster::Cluster.new.start # # @example Start a cluster with a custom configuration # Elasticsearch::Extensions::Test::Cluster::Cluster.new( # cluster_name: 'my-cluster', # number_of_nodes: 3, # node_name: 'my-node', # port: 9350 # ).start # # @example Start a cluster with a different Elasticsearch version # Elasticsearch::Extensions::Test::Cluster::Cluster.new( # command: "/usr/local/Cellar/elasticsearch/1.0.0.Beta2/bin/elasticsearch" # ).start # # @return Boolean,Array # @see Cluster#stop # def start if self.running? __log "[!] Elasticsearch cluster already running".ansi(:red) return false end __remove_cluster_data if @clear_cluster __log "Starting ".ansi(:faint) + arguments[:number_of_nodes].to_s.ansi(:bold, :faint) + " Elasticsearch #{arguments[:number_of_nodes] < 2 ? 'node' : 'nodes'}..".ansi(:faint), :print pids = [] __log "\nUsing Elasticsearch version [#{version}]" if ENV['DEBUG'] arguments[:number_of_nodes].times do |n| n += 1 command = __command(version, arguments, n) command += '> /dev/null' unless ENV['DEBUG'] __log command.gsub(/ {1,}/, ' ').ansi(:bold) if ENV['DEBUG'] pid = Process.spawn(command) Process.detach pid pids << pid sleep 1 end __check_for_running_processes(pids) wait_for_green __log __cluster_info return true end # Stops the cluster # # Fetches the PID numbers from "Nodes Info" API and terminates matching nodes. # # @example Stop the default cluster # Elasticsearch::Extensions::Test::Cluster::Cluster.new.stop # # @example Stop the cluster reachable on specific port # Elasticsearch::Extensions::Test::Cluster::Cluster.new(port: 9350).stop # # @return Boolean,Array # @see Cluster#start # def stop begin nodes = __get_nodes rescue Exception => e __log "[!] Exception raised when stopping the cluster: #{e.inspect}".ansi(:red) nil end return false if nodes.nil? or nodes.empty? pids = nodes['nodes'].map { |id, info| info['process']['id'] } unless pids.empty? __log "Stopping Elasticsearch nodes... ".ansi(:faint), :print pids.each_with_index do |pid, i| ['INT','KILL'].each do |signal| begin Process.kill signal, pid rescue Exception => e __log "[#{e.class}] PID #{pid} not found. ".ansi(:red), :print end # Give the system some breathing space to finish... Kernel.sleep 1 # Check that pid really is dead begin Process.getpgid pid # `getpgid` will raise error if pid is dead, so if we get here, try next signal next rescue Errno::ESRCH __log "Stopped PID #{pid}".ansi(:green) + (ENV['DEBUG'] ? " with #{signal} signal".ansi(:green) : '') + ". ".ansi(:green), :print break # pid is dead end end end __log "\n" else return false end return pids end # Returns true when a specific test node is running within the cluster # # @return Boolean # def running? if cluster_health = Timeout::timeout(0.25) { __get_cluster_health } rescue nil return cluster_health['cluster_name'] == arguments[:cluster_name] && \ cluster_health['number_of_nodes'] == arguments[:number_of_nodes] end return false end # Waits until the cluster is green and prints information about it # # @return Boolean # def wait_for_green __wait_for_status('green', arguments[:timeout]) end # Returns the major version of Elasticsearch # # @return String # @see __determine_version # def version @version ||= __determine_version end # Returns default `:network_host` setting based on the version # # @api private # # @return String # def __default_network_host case version when /^0|^1/ '0.0.0.0' when /^2/ '_local_' when /^5|^6|^7|^8/ '_local_' else raise RuntimeError, "Cannot determine default network host from version [#{version}]" end end # Returns a reasonably unique cluster name # # @api private # # @return String # def __default_cluster_name "elasticsearch-test-#{Socket.gethostname.downcase}" end # Returns the HTTP URL for the cluster based on `:network_host` setting # # @api private # # @return String # def __cluster_url if '_local_' == arguments[:network_host] "http://localhost:#{arguments[:port]}" else "http://#{arguments[:network_host]}:#{arguments[:port]}" end end # Determine Elasticsearch version to be launched # # Tries to get the version from the arguments passed, # if not available, it parses the version number from the `lib/elasticsearch-X.Y.Z.jar` file, # if that is not available, uses `elasticsearch --version` or `elasticsearch -v` # # @api private # # @return String # def __determine_version path_to_lib = File.dirname(arguments[:command]) + '/../lib/' version = if arguments[:version] arguments[:version] elsif File.exist?(path_to_lib) && !(jar = Dir.entries(path_to_lib).select { |f| f =~ /^elasticsearch\-\d/ }.first).nil? __log "Determining version from [#{jar}]" if ENV['DEBUG'] if m = jar.match(/elasticsearch\-(\d+\.\d+\.\d+).*/) m[1] else raise RuntimeError, "Cannot determine Elasticsearch version from jar [#{jar}]" end else __log "[!] Cannot find Elasticsearch .jar from path to command [#{arguments[:command]}], using `#{arguments[:command]} --version`" if ENV['DEBUG'] unless File.exist? arguments[:command] __log "File [#{arguments[:command]}] does not exists, checking full path by `which`: ", :print if ENV['DEBUG'] begin full_path = `which #{arguments[:command]}`.strip __log "#{full_path.inspect}\n", :print if ENV['DEBUG'] rescue Exception => e raise RuntimeError, "Cannot determine full path to [#{arguments[:command]}] with 'which'" end if full_path.empty? raise Errno::ENOENT, "Cannot find Elasticsearch launch script from [#{arguments[:command]}] -- did you pass a correct path?" end end output = '' begin # First, try the new `--version` syntax... __log "Running [#{arguments[:command]} --version] to determine version" if ENV['DEBUG'] io = IO.popen("#{arguments[:command]} --version") pid = io.pid Timeout::timeout(arguments[:timeout_version]) do Process.wait(pid) output = io.read end rescue Timeout::Error # ...else, the old `-v` syntax __log "Running [#{arguments[:command]} -v] to determine version" if ENV['DEBUG'] output = `#{arguments[:command]} -v` ensure if pid Process.kill('INT', pid) rescue Errno::ESRCH # Most likely the process has terminated already end io.close unless io.closed? end STDERR.puts "> #{output}" if ENV['DEBUG'] if output.empty? raise RuntimeError, "Cannot determine Elasticsearch version from [#{arguments[:command]} --version] or [#{arguments[:command]} -v]" end if m = output.match(/Version: (\d\.\d.\d).*,/) m[1] else raise RuntimeError, "Cannot determine Elasticsearch version from elasticsearch --version output [#{output}]" end end case version when /^0\.90.*/ '0.90' when /^1\..*/ '1.0' when /^2\..*/ '2.0' when /^5\..*/ '5.0' when /^6\..*/ '6.0' when /^7\..*/ '7.0' when /^8\..*/ '8.0' else raise RuntimeError, "Cannot determine major version from [#{version}]" end end # Returns the launch command for a specific version # # @api private # # @return String # def __command(version, arguments, node_number) if command = COMMANDS[version] command.call(arguments, node_number) else raise ArgumentError, "Cannot find command for version [#{version}]" end end # Blocks the process and waits for the cluster to be in a "green" state # # Prints information about the cluster on STDOUT if the cluster is available. # # @param status [String] The status to wait for (yellow, green) # @param timeout [Integer] The explicit timeout for the operation # # @api private # # @return Boolean # def __wait_for_status(status='green', timeout=30) begin Timeout::timeout(timeout) do loop do response = __get_cluster_health(status) __log response if ENV['DEBUG'] if response && response['status'] == status && ( arguments[:number_of_nodes].nil? || arguments[:number_of_nodes].to_i == response['number_of_nodes'].to_i ) break end __log '.'.ansi(:faint), :print sleep 1 end end rescue Timeout::Error => e message = "\nTimeout while waiting for cluster status [#{status}]" message += " and [#{arguments[:number_of_nodes]}] nodes" if arguments[:number_of_nodes] __log message.ansi(:red, :bold) raise e end return true end # Return information about the cluster # # @api private # # @return String # def __cluster_info health = JSON.parse(Net::HTTP.get(URI("#{__cluster_url}/_cluster/health"))) nodes = if version == '0.90' JSON.parse(Net::HTTP.get(URI("#{__cluster_url}/_nodes/?process&http"))) else JSON.parse(Net::HTTP.get(URI("#{__cluster_url}/_nodes/process,http"))) end master = JSON.parse(Net::HTTP.get(URI("#{__cluster_url}/_cluster/state")))['master_node'] result = ["\n", ('-'*80).ansi(:faint), 'Cluster: '.ljust(20).ansi(:faint) + health['cluster_name'].to_s.ansi(:faint), 'Status: '.ljust(20).ansi(:faint) + health['status'].to_s.ansi(:faint), 'Nodes: '.ljust(20).ansi(:faint) + health['number_of_nodes'].to_s.ansi(:faint)].join("\n") nodes['nodes'].each do |id, info| m = id == master ? '*' : '-' result << "\n" + ''.ljust(20) + "#{m} ".ansi(:faint) + "#{info['name'].ansi(:bold)} ".ansi(:faint) + "| version: #{info['version'] rescue 'N/A'}, ".ansi(:faint) + "pid: #{info['process']['id'] rescue 'N/A'}, ".ansi(:faint) + "address: #{info['http']['bound_address'] rescue 'N/A'}".ansi(:faint) end result end # Tries to load cluster health information # # @api private # # @return Hash,Nil # def __get_cluster_health(status=nil) uri = URI("#{__cluster_url}/_cluster/health") uri.query = "wait_for_status=#{status}" if status begin response = Net::HTTP.get(uri) rescue Exception => e STDERR.puts e.inspect if ENV['DEBUG'] return nil end JSON.parse(response) end # Remove the data directory # # @api private # def __remove_cluster_data FileUtils.rm_rf arguments[:path_data] end # Check whether process for PIDs are running # # @api private # def __check_for_running_processes(pids) if `ps -p #{pids.join(' ')}`.split("\n").size < arguments[:number_of_nodes]+1 __log "\n[!!!] Process failed to start (see output above)".ansi(:red) exit(1) end end # Get the information about nodes # # @api private # def __get_nodes JSON.parse(Net::HTTP.get(URI("#{__cluster_url}/_nodes/process"))) end # Print to STDERR # def __log(message, mode=:puts) STDERR.__send__ mode, message unless @arguments[:quiet] end end end end end end cluster/000077500000000000000000000000001462737751600346075ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions/testtasks.rb000066400000000000000000000021111462737751600362540ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions/test/cluster# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'elasticsearch/extensions/test/cluster' namespace :elasticsearch do desc "Start Elasticsearch cluster for tests" task :start do Elasticsearch::Extensions::Test::Cluster.start end desc "Stop Elasticsearch cluster for tests" task :stop do Elasticsearch::Extensions::Test::Cluster.stop end end profiling.rb000066400000000000000000000107151462737751600354500ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions/test# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'ruby-prof' require 'benchmark' require 'ansi' module Elasticsearch module Extensions module Test # Allows to define and execute profiling tests within [Shoulda](https://github.com/thoughtbot/shoulda) contexts. # # Measures operations and reports statistics, including code profile. # # Uses the "benchmark" standard library and the "ruby-prof" gem. # # File: profiling_test.rb # # require 'test/unit' # require 'shoulda/context' # require 'elasticsearch/extensions/test/profiling' # # class ProfilingTest < Test::Unit::TestCase # extend Elasticsearch::Extensions::Test::Profiling # # context "Mathematics" do # measure "divide numbers", count: 10_000 do # assert_nothing_raised { 1/2 } # end # end # # end # # $ QUIET=y ruby profiling_test.rb # # ... # ProfilingTest # # ------------------------------------------------------------------------------- # Context: Mathematics should divide numbers (10000x) # mean: 0.03ms | avg: 0.03ms | max: 0.14ms # ------------------------------------------------------------------------------- # PASS (0:00:00.490) test: Mathematics should divide numbers (10000x). # ... # module Profiling # Profiles the passed block of code. # # measure "divide numbers", count: 10_000 do # assert_nothing_raised { 1/2 } # end # # @todo Try to make progress bar not to interfere with tests # def measure(name, options={}, &block) ___ = '-'*ANSI::Terminal.terminal_width test_name = name suite_name = self.name.split('::').last context_name = self.context(nil) {}.first.parent.name count = Integer(ENV['COUNT'] || options[:count] || 1_000) ticks = [] progress = ANSI::Progressbar.new(suite_name, count) unless ENV['QUIET'] || options[:quiet] should "#{test_name} (#{count}x)" do RubyProf.start begin count.times do ticks << Benchmark.realtime { self.instance_eval(&block) } if progress RubyProf.pause progress.inc RubyProf.resume end end ensure result = RubyProf.stop progress.finish if progress end total = result.threads.reduce(0) { |t,info| t += info.total_time; t } mean = (ticks.sort[(ticks.size/2).round-1])*1000 avg = (ticks.inject {|sum,el| sum += el; sum}.to_f/ticks.size)*1000 min = ticks.min*1000 max = ticks.max*1000 result.eliminate_methods!([/Integer#times|Benchmark.realtime|ANSI::Code#.*|ANSI::ProgressBar#.*/]) printer = RubyProf::FlatPrinter.new(result) # printer = RubyProf::GraphPrinter.new(result) puts "\n", ___, "#{suite_name}: " + ANSI.bold(context_name) + ' should ' + ANSI.bold(name) + " (#{count}x)", "total: #{sprintf('%.2f', total)}s | " + "mean: #{sprintf('%.2f', mean)}ms | " + "avg: #{sprintf('%.2f', avg)}ms | " + "min: #{sprintf('%.2f', min)}ms | " + "max: #{sprintf('%.2f', max)}ms", ___ printer.print(STDOUT, {}) unless ENV['QUIET'] || options[:quiet] end end end end end end startup_shutdown.rb000066400000000000000000000043631462737751600371160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions/test# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Extensions module Test # Startup/shutdown support for test suites # # Example: # # class MyTest < Test::Unit::TestCase # extend Elasticsearch::Extensions::Test::StartupShutdown # # startup { puts "Suite starting up..." } # shutdown { puts "Suite shutting down..." } # end # # *** IMPORTANT NOTE: ********************************************************** # # You have to register the handler for shutdown before requiring 'test/unit': # # # File: test_helper.rb # at_exit { MyTest.__run_at_exit_hooks } # require 'test/unit' # # The API follows Test::Unit 2.0 # # module StartupShutdown @@started = false @@shutdown_blocks ||= [] def startup &block return if started? @@started = true yield block if block_given? end def shutdown &block @@shutdown_blocks << block if block_given? end def started? !! @@started end def __run_at_exit_hooks return unless started? STDERR.puts ANSI.faint("Running at_exit hooks...") puts ANSI.faint('-'*80) @@shutdown_blocks.each { |b| b.call } puts ANSI.faint('-'*80) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/lib/elasticsearch/extensions/version.rb000066400000000000000000000015221462737751600342400ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Extensions VERSION = "0.0.31" end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/test/000077500000000000000000000000001462737751600254265ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/test/ansi/000077500000000000000000000000001462737751600263605ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/test/ansi/unit/000077500000000000000000000000001462737751600273375ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/test/ansi/unit/ansi_test.rb000066400000000000000000000054101462737751600316550ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' require 'elasticsearch/extensions/ansi' class Elasticsearch::Extensions::AnsiTest < Elasticsearch::Test::UnitTestCase context "The ANSI extension" do setup do @client = Elasticsearch::Client.new @client.stubs(:perform_request).returns \ Elasticsearch::Transport::Transport::Response.new(200, { "ok" => true, "status" => 200, "name" => "Hit-Maker", "version" => { "number" => "0.90.7", "build_hash" => "abc123", "build_timestamp"=>"2013-11-13T12:06:54Z", "build_snapshot"=>false, "lucene_version"=>"4.5.1" }, "tagline"=>"You Know, for Search" }) end should "wrap the response" do response = @client.info assert_instance_of Elasticsearch::Extensions::ANSI::ResponseBody, response assert_instance_of Hash, response.to_hash end should "extend the response object with `to_ansi`" do response = @client.info assert_respond_to response, :to_ansi assert_instance_of String, response.to_ansi end should "call the 'awesome_inspect' method when available and no handler found" do @client.stubs(:perform_request).returns \ Elasticsearch::Transport::Transport::Response.new(200, {"index-1"=>{"aliases"=>{}}}) response = @client.cat.aliases response.instance_eval do def awesome_inspect; "---PRETTY---"; end end assert_equal '---PRETTY---', response.to_ansi end should "call `to_s` method when no pretty printer or handler found" do @client.stubs(:perform_request).returns \ Elasticsearch::Transport::Transport::Response.new(200, {"index-1"=>{"aliases"=>{}}}) response = @client.cat.aliases assert_equal '{"index-1"=>{"aliases"=>{}}}', response.to_ansi end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/test/backup/000077500000000000000000000000001462737751600266735ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/test/backup/unit/000077500000000000000000000000001462737751600276525ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/test/backup/unit/backup_test.rb000066400000000000000000000072011462737751600325030ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' require 'logger' # Mock the Backup modules and classes so we're not depending on the gem in the unit test # module Backup class Error < StandardError; end class Logger < ::Logger def self.logger self.new($stderr) end end module Config module DSL end end module Database class Base def initialize(model, database_id = nil) end def dump_path; 'dump_path'; end def dump_filename; 'dump_filename'; end def log!(*args) puts "LOGGING..." if ENV['DEBUG'] end def perform! puts "PERFORMING..." if ENV['DEBUG'] end end end end require 'elasticsearch/extensions/backup' class Elasticsearch::Extensions::BackupTest < Elasticsearch::Test::UnitTestCase context "The Backup gem extension" do setup do @model = stub trigger: true @subject = ::Backup::Database::Elasticsearch.new(@model) end should "have a client" do assert_instance_of Elasticsearch::Transport::Client, @subject.client end should "have a path" do assert_instance_of Pathname, @subject.path end should "have defaults" do assert_equal 'http://localhost:9200', @subject.url assert_equal '_all', @subject.indices end should "be configurable" do @subject = ::Backup::Database::Elasticsearch.new(@model) do |db| db.url = 'https://example.com' db.indices = 'foo,bar' end assert_equal 'https://example.com', @subject.url assert_equal 'foo,bar', @subject.indices assert_equal 'example.com', @subject.client.transport.connections.first.host[:host] end should "perform the backup" do @subject.expects(:__perform_single) @subject.perform! end should "raise an expection for an unsupported type of backup" do @subject = ::Backup::Database::Elasticsearch.new(@model) { |db| db.mode = 'foobar' } assert_raise ::Backup::Database::Elasticsearch::Error do @subject.perform! end end should "scan and scroll the index" do @subject = ::Backup::Database::Elasticsearch.new(@model) { |db| db.indices = 'test' } @subject.client .expects(:search) .with do |params| assert_equal 'test', params[:index] true # Thanks, Ruby 2.2 end .returns({"_scroll_id" => "abc123"}) @subject.client .expects(:scroll) .twice .returns({"_scroll_id" => "def456", "hits" => { "hits" => [ {"_index"=>"test", "_type"=>"doc", "_id"=>"1", "_source"=>{"title"=>"Test"}} ] } }) .then .returns({"_scroll_id" => "ghi789", "hits" => { "hits" => [] } }) @subject.__perform_single end should "sanitize filename" do assert_equal "foo-bar-baz", @subject.__sanitize_filename("foo/bar\nbaz") end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/test/test/000077500000000000000000000000001462737751600264055ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/test/test/cluster/000077500000000000000000000000001462737751600300665ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/test/test/cluster/integration/000077500000000000000000000000001462737751600324115ustar00rootroot00000000000000cluster_test.rb000066400000000000000000000046721462737751600354100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/test/test/cluster/integration# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' require 'pathname' require 'elasticsearch/extensions/test/cluster' class Elasticsearch::Extensions::TestClusterIntegrationTest < Elasticsearch::Test::IntegrationTestCase context "The Test::Cluster" do PATH_TO_BUILDS = if ENV['PATH_TO_BUILDS'] Pathname(ENV['PATH_TO_BUILDS']) else Pathname(File.expand_path('../../../../../../tmp/builds', __FILE__)) end unless PATH_TO_BUILDS.exist? puts "Path to builds doesn't exist, skipping TestClusterIntegrationTest" exit(0) end @builds = begin PATH_TO_BUILDS.entries.reject { |f| f.to_s =~ /^\./ }.sort rescue Errno::ENOENT [] end STDOUT.puts %Q|Builds: \n#{@builds.map { |b| " * #{b}"}.join("\n")}| unless ENV['QUIET'] @builds.each do |build| should "start and stop #{build.to_s}" do puts ("----- #{build.to_s} " + "-"*(80-7-build.to_s.size)).to_s.ansi(:bold) begin Elasticsearch::Extensions::Test::Cluster.start \ command: PATH_TO_BUILDS.join(build.join('bin/elasticsearch')).to_s, port: 9260, cluster_name: 'elasticsearch-ext-integration-test', path_data: '/tmp/elasticsearch-ext-integration-test' # Index some data to create the data directory client = Elasticsearch::Client.new host: "localhost:9260" client.index index: 'test1', type: 'd', id: 1, body: { title: 'TEST' } ensure Elasticsearch::Extensions::Test::Cluster.stop \ command: PATH_TO_BUILDS.join(build.join('bin/elasticsearch')).to_s, port: 9260, cluster_name: 'elasticsearch-ext-integration-test' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/test/test/cluster/unit/000077500000000000000000000000001462737751600310455ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/test/test/cluster/unit/cluster_test.rb000066400000000000000000000301321462737751600341110ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' require 'elasticsearch/extensions/test/cluster' class Elasticsearch::Extensions::TestClusterTest < Elasticsearch::Test::UnitTestCase include Elasticsearch::Extensions::Test context "The Test::Cluster" do context "module" do should "delegate the methods to the class" do Cluster::Cluster .expects(:new) .with({foo: 'bar'}) .returns(mock start: true, stop: true, running?: true, wait_for_green: true) .times(4) Elasticsearch::Extensions::Test::Cluster.start foo: 'bar' Elasticsearch::Extensions::Test::Cluster.stop foo: 'bar' Elasticsearch::Extensions::Test::Cluster.running? foo: 'bar' Elasticsearch::Extensions::Test::Cluster.wait_for_green foo: 'bar' end end context "class" do setup do Elasticsearch::Extensions::Test::Cluster::Cluster.any_instance.stubs(:__default_network_host).returns('_local_') @subject = Elasticsearch::Extensions::Test::Cluster::Cluster.new(number_of_nodes: 1) @subject.stubs(:__remove_cluster_data).returns(true) end teardown do ENV.delete('TEST_CLUSTER_PORT') end should "be initialized with parameters" do c = Cluster::Cluster.new port: 9400 assert_equal 9400, c.arguments[:port] end should "not modify the arguments" do args = { port: 9400 }.freeze assert_nothing_raised { Cluster::Cluster.new args } assert_nil args[:command] end should "take parameters from environment variables" do ENV['TEST_CLUSTER_PORT'] = '9400' c = Cluster::Cluster.new assert_equal 9400, c.arguments[:port] end should "raise exception for dangerous cluster name" do assert_raise(ArgumentError) { Cluster::Cluster.new cluster_name: '' } assert_raise(ArgumentError) { Cluster::Cluster.new cluster_name: '/' } end should "have a version" do @subject.unstub(:version) @subject.expects(:__determine_version).returns('2.0') assert_equal '2.0', @subject.version end should "have a default network host" do Cluster::Cluster.any_instance.unstub(:__default_network_host) Cluster::Cluster.any_instance.stubs(:version).returns('5.0') assert_equal '_local_', Cluster::Cluster.new.__default_network_host end should "have a default cluster name" do Socket.stubs(:gethostname).returns('FOOBAR') assert_equal 'elasticsearch-test-foobar', Cluster::Cluster.new.__default_cluster_name end should "have a cluster URL for new versions" do assert_equal 'http://localhost:9250', Cluster::Cluster.new(network_host: '_local_').__cluster_url end should "have a cluster URL for old versions" do assert_equal 'http://192.168.1.1:9250', Cluster::Cluster.new(network_host: '192.168.1.1').__cluster_url end should "return corresponding command to a version" do assert_match /\-D es\.foreground=yes/, @subject.__command('2.0', @subject.arguments, 1) end should "raise an error when a corresponding command cannot be found" do assert_raise ArgumentError do @subject.__command('FOOBAR', @subject.arguments, 1) end end should "remove cluster data" do @subject.unstub(:__remove_cluster_data) FileUtils.expects(:rm_rf).with("/tmp/elasticsearch_test") @subject.__remove_cluster_data end should "not log when :quiet" do c = Cluster::Cluster.new quiet: true STDERR.expects(:puts).never c.__log 'QUIET' end context "when starting a cluster, " do should "return false when it's already running" do Process.expects(:spawn).never c = Cluster::Cluster.new c.expects(:running?).returns(true) assert_equal false, c.start end should "start the specified number of nodes" do Process.expects(:spawn).times(3) Process.expects(:detach).times(3) c = Cluster::Cluster.new number_of_nodes: 3 c.expects(:running?).returns(false) c.unstub(:__remove_cluster_data) c.expects(:__remove_cluster_data).returns(true) c.expects(:wait_for_green).returns(true) c.expects(:__check_for_running_processes).returns(true) c.expects(:__determine_version).returns('5.0') c.expects(:__cluster_info).returns('CLUSTER INFO') assert_equal true, c.start end end context "when stopping a cluster" do setup do @subject = Elasticsearch::Extensions::Test::Cluster::Cluster.new end should "print information about an exception" do @subject.expects(:__get_nodes).raises(Errno::ECONNREFUSED) assert_nothing_raised do assert_equal false, @subject.stop end end should "return false when the nodes are empty" do @subject.expects(:__get_nodes).returns({}) assert_equal false, @subject.stop end should "kill each node" do @subject.expects(:__get_nodes).returns({'nodes' => { 'n1' => { 'process' => { 'id' => 1 }}, 'n2' => { 'process' => { 'id' => 2 }} }}) Kernel.stubs(:sleep) Process.expects(:kill).with('INT', 1) Process.expects(:kill).with('INT', 2) Process.expects(:getpgid).with(1).raises(Errno::ESRCH) Process.expects(:getpgid).with(2).raises(Errno::ESRCH) assert_equal [1, 2], @subject.stop end end context "when checking if the cluster is running" do setup do @subject = Elasticsearch::Extensions::Test::Cluster::Cluster.new \ cluster_name: 'test', number_of_nodes: 2 end should "return true" do @subject.expects(:__get_cluster_health).returns({'cluster_name' => 'test', 'number_of_nodes' => 2}) assert_equal true, @subject.running? end should "return false" do @subject.expects(:__get_cluster_health).returns({'cluster_name' => 'test', 'number_of_nodes' => 1}) assert_equal false, @subject.running? end end context "when waiting for the green state" do should "return true" do @subject.expects(:__wait_for_status).returns(true) assert_equal true, @subject.wait_for_green end end context "when waiting for cluster state" do setup do @subject = Elasticsearch::Extensions::Test::Cluster::Cluster.new \ cluster_name: 'test', number_of_nodes: 1 end should "return true" do @subject .expects(:__get_cluster_health) .with('yellow') .returns({'status' => 'yellow', 'cluster_name' => 'test', 'number_of_nodes' => 1}) @subject.__wait_for_status('yellow') end end context "when getting the cluster health" do should "return the response" do Net::HTTP .expects(:get) .with(URI('http://localhost:9250/_cluster/health')) .returns(JSON.dump({'status' => 'yellow', 'cluster_name' => 'test', 'number_of_nodes' => 1})) @subject.__get_cluster_health end should "wait for status" do Net::HTTP .expects(:get) .with(URI('http://localhost:9250/_cluster/health?wait_for_status=green')) .returns(JSON.dump({'status' => 'yellow', 'cluster_name' => 'test', 'number_of_nodes' => 1})) @subject.__get_cluster_health('green') end end context "when getting the list of nodes" do should "return the response" do Net::HTTP .expects(:get) .with(URI('http://localhost:9250/_nodes/process')) .returns(JSON.dump({'nodes' => { 'n1' => {}, 'n2' => {} } })) assert_equal 'n1', @subject.__get_nodes['nodes'].keys.first end end context "when determining a version" do setup do @subject = Elasticsearch::Extensions::Test::Cluster::Cluster.new command: '/foo/bar/bin/elasticsearch' end should "return version from lib/elasticsearch.X.Y.Z.jar" do File.expects(:exist?).with('/foo/bar/bin/../lib/').returns(true) Dir.expects(:entries).with('/foo/bar/bin/../lib/').returns(['foo.jar', 'elasticsearch-foo-1.0.0.jar', 'elasticsearch-2.3.0.jar', 'elasticsearch-bar-9.9.9.jar']) assert_equal '2.0', @subject.__determine_version end should "return version from `elasticsearch --version`" do File.expects(:exist?).with('/foo/bar/bin/../lib/').returns(false) File.expects(:exist?).with('/foo/bar/bin/elasticsearch').returns(true) io = mock('IO') io.expects(:pid).returns(123) io.expects(:read).returns('Version: 2.3.0-SNAPSHOT, Build: d1c86b0/2016-03-30T10:43:20Z, JVM: 1.8.0_60') io.expects(:closed?).returns(false) io.expects(:close) IO.expects(:popen).returns(io) Process.stubs(:wait) Process.expects(:kill).with('INT', 123) assert_equal '2.0', @subject.__determine_version end should "return version from arguments" do cluster = Elasticsearch::Extensions::Test::Cluster::Cluster.new command: '/foo/bar/bin/elasticsearch', version: '5.2' assert_equal '5.0', cluster.__determine_version end should "raise an exception when the version cannot be parsed from .jar" do # Incorrect jar version (no dots) File.expects(:exist?).with('/foo/bar/bin/../lib/').returns(true) Dir.expects(:entries).with('/foo/bar/bin/../lib/').returns(['elasticsearch-100.jar']) assert_raise(RuntimeError) { @subject.__determine_version } end should "raise an exception when the version cannot be parsed from command output" do File.expects(:exist?).with('/foo/bar/bin/../lib/').returns(false) File.expects(:exist?).with('/foo/bar/bin/elasticsearch').returns(true) io = mock('IO') io.expects(:pid).returns(123) io.expects(:read).returns('Version: FOOBAR') io.expects(:closed?).returns(false) io.expects(:close) IO.expects(:popen).returns(io) Process.stubs(:wait) Process.expects(:kill).with('INT', 123) assert_raise(RuntimeError) { @subject.__determine_version } end should "raise an exception when the version cannot be converted to short version" do # There's no Elasticsearch version 3... File.expects(:exist?).with('/foo/bar/bin/../lib/').returns(true) Dir.expects(:entries).with('/foo/bar/bin/../lib/').returns(['elasticsearch-3.2.1.jar']) assert_raise(RuntimeError) { @subject.__determine_version } end should "raise an exception when the command cannot be found" do @subject = Elasticsearch::Extensions::Test::Cluster::Cluster.new File.expects(:exist?).with('./../lib/').returns(false) File.expects(:exist?).with('elasticsearch').returns(false) @subject.expects(:`).returns('') assert_raise(Errno::ENOENT) { @subject.__determine_version } end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-extensions/test/test_helper.rb000066400000000000000000000047741462737751600303050ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. ELASTICSEARCH_HOSTS = if (hosts = ENV['TEST_ES_SERVER'] || ENV['ELASTICSEARCH_HOSTS']) hosts.split(',').map do |host| /(http\:\/\/)?(\S+)/.match(host)[2] end end.freeze TEST_HOST, TEST_PORT = ELASTICSEARCH_HOSTS.first.split(':') if ELASTICSEARCH_HOSTS JRUBY = defined?(JRUBY_VERSION) if ENV['COVERAGE'] require 'simplecov' SimpleCov.start { add_filter "/test|test_" } end require 'minitest/autorun' require 'shoulda-context' require 'mocha/setup' require 'minitest/reporters' Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new require 'ansi/code' require 'logger' require 'elasticsearch/extensions' require 'elasticsearch/extensions/test/startup_shutdown' require 'elasticsearch/extensions/test/cluster' module Elasticsearch module Test module Assertions def assert_nothing_raised(*) yield end end class UnitTestCase < ::Minitest::Test include Assertions alias_method :assert_not_nil, :refute_nil alias_method :assert_raise, :assert_raises end class IntegrationTestCase < ::Minitest::Test include Assertions alias_method :assert_not_nil, :refute_nil alias_method :assert_raise, :assert_raises include Elasticsearch::Extensions::Test extend StartupShutdown startup do Elasticsearch::Extensions::Test::Cluster.start(number_of_nodes: 2) if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?(number_of_nodes: 2) end shutdown do Elasticsearch::Extensions::Test::Cluster.stop(number_of_nodes: 2) if ENV['SERVER'] and Elasticsearch::Extensions::Test::Cluster.running?(number_of_nodes: 2) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/000077500000000000000000000000001462737751600243045ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/.gitignore000066400000000000000000000002321462737751600262710ustar00rootroot00000000000000*.gem *.rbc .bundle .config .yardoc Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/Gemfile000066400000000000000000000030021462737751600255720ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. source 'https://rubygems.org' # Specify your gem's dependencies in elasticsearch-transport.gemspec gemspec if File.exist? File.expand_path('../elasticsearch-api/elasticsearch-api.gemspec', __dir__) gem 'elasticsearch-api', path: File.expand_path('../elasticsearch-api', __dir__), require: false end if File.exist? File.expand_path('../elasticsearch/elasticsearch.gemspec', __dir__) gem 'elasticsearch', path: File.expand_path('../elasticsearch', __dir__), require: false end group :development, :test do gem 'faraday-httpclient' gem 'faraday-net_http_persistent' gem 'faraday-patron' unless defined? JRUBY_VERSION gem 'faraday-typhoeus' gem 'rspec' if defined?(JRUBY_VERSION) gem 'pry-nav' else gem 'pry-byebug', '~> 3.9' end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/Gemfile-faraday1.gemfile000066400000000000000000000031171462737751600306760ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. source 'https://rubygems.org' # Usage: # # $ BUNDLE_GEMFILE=./Gemfile-faraday1.gemfile bundle install # $ BUNDLE_GEMFILE=./Gemfile-faraday1.gemfile bundle exec rake test:faraday1:unit gem 'faraday', '~> 1' gemspec path: './' if File.exist? File.expand_path('../elasticsearch-api/elasticsearch-api.gemspec', __dir__) gem 'elasticsearch-api', path: File.expand_path('../elasticsearch-api', __dir__), require: false end if File.exist? File.expand_path('../elasticsearch/elasticsearch.gemspec', __dir__) gem 'elasticsearch', path: File.expand_path('../elasticsearch', __dir__), require: false end group :development, :test do gem 'httpclient' gem 'net-http-persistent' gem 'patron' unless defined? JRUBY_VERSION gem 'typhoeus' gem 'rspec' if defined?(JRUBY_VERSION) gem 'pry-nav' else gem 'pry-byebug' end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/LICENSE000066400000000000000000000261361462737751600253210ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/README.md000066400000000000000000000521761462737751600255760ustar00rootroot00000000000000# Elasticsearch::Transport **This library is part of the [`elasticsearch-ruby`](https://github.com/elasticsearch/elasticsearch-ruby/) package; please refer to it, unless you want to use this library standalone.** ---- The `elasticsearch-transport` library provides a low-level Ruby client for connecting to an [Elasticsearch](http://elasticsearch.com) cluster. It handles connecting to multiple nodes in the cluster, rotating across connections, logging and tracing requests and responses, maintaining failed connections, discovering nodes in the cluster, and provides an abstraction for data serialization and transport. It does not handle calling the Elasticsearch API; see the [`elasticsearch-api`](https://github.com/elasticsearch/elasticsearch-ruby/tree/master/elasticsearch-api) library. The library is compatible with Ruby 1.9 or higher and with all versions of Elasticsearch since 0.90. Features overview: * Pluggable logging and tracing * Pluggable connection selection strategies (round-robin, random, custom) * Pluggable transport implementation, customizable and extendable * Pluggable serializer implementation * Request retries and dead connections handling * Node reloading (based on cluster state) on errors or on demand For optimal performance, use a HTTP library which supports persistent ("keep-alive") connections, such as [patron](https://github.com/toland/patron) or [Typhoeus](https://github.com/typhoeus/typhoeus). Just require the library (`require 'patron'`) in your code, and it will be automatically used. Currently these libraries will be automatically detected and used: - [Patron](https://github.com/toland/patron) - [Typhoeus](https://github.com/typhoeus/typhoeus) - [HTTPClient](https://rubygems.org/gems/httpclient) - [Net::HTTP::Persistent](https://rubygems.org/gems/net-http-persistent) **Note on [Typhoeus](https://github.com/typhoeus/typhoeus)**: You need to use v1.4.0 or up since older versions are not compatible with Faraday 1.0. For detailed information, see example configurations [below](#transport-implementations). ## Installation Install the package from [Rubygems](https://rubygems.org): gem install elasticsearch-transport To use an unreleased version, either add it to your `Gemfile` for [Bundler](http://gembundler.com): gem 'elasticsearch-transport', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git' or install it from a source code checkout: git clone https://github.com/elasticsearch/elasticsearch-ruby.git cd elasticsearch-ruby/elasticsearch-transport bundle install rake install ## Example Usage In the simplest form, connect to Elasticsearch running on without any configuration: require 'elasticsearch/transport' client = Elasticsearch::Client.new response = client.perform_request 'GET', '_cluster/health' # => # Full documentation is available at . ## Configuration * [Setting Hosts](#setting-hosts) * [Default port](#default-port) * [Connect using an Elastic Cloud ID](#connect-using-an-elastic-cloud-id) * [Authentication](#authentication) * [Logging](#logging) * [Custom HTTP Headers](#custom-http-headers) * [Identifying running tasks with X-Opaque-Id](#identifying-running-tasks-with-x-opaque-id) * [Setting Timeouts](#setting-timeouts) * [Randomizing Hosts](#randomizing-hosts) * [Retrying on Failures](#retrying-on-failures) * [Reloading Hosts](#reloading-hosts) * [Connection Selector](#connection-selector) * [Transport Implementations](#transport-implementations) * [Serializer implementations](#serializer-implementations) * [Exception Handling](#exception-handling) * [Development and Community](#development-and-community) The client supports many configurations options for setting up and managing connections, configuring logging, customizing the transport library, etc. ### Setting Hosts To connect to a specific Elasticsearch host: Elasticsearch::Client.new host: 'search.myserver.com' To connect to a host with specific port: Elasticsearch::Client.new host: 'myhost:8080' To connect to multiple hosts: Elasticsearch::Client.new hosts: ['myhost1', 'myhost2'] Instead of Strings, you can pass host information as an array of Hashes: Elasticsearch::Client.new hosts: [ { host: 'myhost1', port: 8080 }, { host: 'myhost2', port: 8080 } ] **NOTE:** When specifying multiple hosts, you probably want to enable the `retry_on_failure` option to perform a failed request on another node (see the _Retrying on Failures_ chapter). Common URL parts -- scheme, HTTP authentication credentials, URL prefixes, etc -- are handled automatically: Elasticsearch::Client.new url: 'https://username:password@api.server.org:4430/search' You can pass multiple URLs separated by a comma: Elasticsearch::Client.new urls: 'http://localhost:9200,http://localhost:9201' Another way to configure the URL(s) is to export the `ELASTICSEARCH_URL` variable. The client will automatically round-robin across the hosts (unless you select or implement a different [connection selector](#connection-selector)). ### Default port The default port is `9200`. Please specify a port for your host(s) if they differ from this default. Please see below for an exception to this when connecting using an Elastic Cloud ID. ### Connect using an Elastic Cloud ID If you are using [Elastic Cloud](https://www.elastic.co/cloud), you can provide your cloud id to the client. You must supply your username and password separately, and optionally a port. If no port is supplied, port 443 will be used. Note: Do not enable sniffing when using Elastic Cloud. The nodes are behind a load balancer so Elastic Cloud will take care of everything for you. Elasticsearch::Client.new(cloud_id: 'name:bG9jYWxob3N0JGFiY2QkZWZnaA==', user: 'elastic', password: 'changeme') ### Authentication You can pass the authentication credentials, scheme and port in the host configuration hash: Elasticsearch::Client.new hosts: [ { host: 'my-protected-host', port: '443', user: 'USERNAME', password: 'PASSWORD', scheme: 'https' } ] ... or simply use the common URL format: Elasticsearch::Client.new url: 'https://username:password@example.com:9200' To pass a custom certificate for SSL peer verification to Faraday-based clients, use the `transport_options` option: Elasticsearch::Client.new url: 'https://username:password@example.com:9200', transport_options: { ssl: { ca_file: '/path/to/cacert.pem' } } You can also use [**API Key authentication**](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html): ``` ruby Elasticsearch::Client.new( host: host, transport_options: transport_options, api_key: credentials ) ``` Where credentials is either the base64 encoding of `id` and `api_key` joined by a colon or a hash with the `id` and `api_key`: ``` ruby Elasticsearch::Client.new( host: host, transport_options: transport_options, api_key: {id: 'my_id', api_key: 'my_api_key'} ) ``` ### Logging To log requests and responses to standard output with the default logger (an instance of Ruby's {::Logger} class), set the `log` argument to true: ```ruby Elasticsearch::Client.new(log: true) ``` You can also use [ecs-logging](https://github.com/elastic/ecs-logging-ruby). `ecs-logging` is a set of libraries that allows you to transform your application logs to structured logs that comply with the [Elastic Common Schema (ECS)](https://www.elastic.co/guide/en/ecs/current/ecs-reference.html): ```ruby logger = EcsLogging::Logger.new($stdout) Elasticsearch::Client.new(logger: logger) ``` To trace requests and responses in the _Curl_ format, set the `trace` argument: ```ruby Elasticsearch::Client.new(trace: true) ``` You can customize the default logger or tracer: ```ruby client.transport.logger.formatter = proc { |s, d, p, m| "#{s}: #{m}\n" } client.transport.logger.level = Logger::INFO ``` Or, you can use a custom `::Logger` instance: ```ruby Elasticsearch::Client.new(logger: Logger.new(STDERR)) ``` You can pass the client any conforming logger implementation: ```ruby require 'logging' # https://github.com/TwP/logging/ log = Logging.logger['elasticsearch'] log.add_appenders Logging.appenders.stdout log.level = :info client = Elasticsearch::Client.new(logger: log) ``` ### Custom HTTP Headers You can set a custom HTTP header on the client's initializer: ```ruby client = Elasticsearch::Client.new( transport_options: { headers: {user_agent: "My App"} } ) ``` You can also pass in `headers` as a parameter to any of the API Endpoints to set custom headers for the request: ```ruby client.search(index: 'myindex', q: 'title:test', headers: {user_agent: "My App"}) ``` ### Identifying running tasks with X-Opaque-Id The X-Opaque-Id header allows to track certain calls, or associate certain tasks with the client that started them ([more on the Elasticsearch docs](https://www.elastic.co/guide/en/elasticsearch/reference/master/tasks.html#_identifying_running_tasks)). To use this feature, you need to set an id for `opaque_id` on the client on each request. Example: ```ruby client = Elasticsearch::Client.new client.search(index: 'myindex', q: 'title:test', opaque_id: '123456') ``` The search request will include the following HTTP Header: ``` X-Opaque-Id: 123456 ``` You can also set a prefix for X-Opaque-Id when initializing the client. This will be prepended to the id you set before each request if you're using X-Opaque-Id. Example: ```ruby client = Elasticsearch::Client.new(opaque_id_prefix: 'eu-west1') client.search(index: 'myindex', q: 'title:test', opaque_id: '123456') ``` The request will include the following HTTP Header: ``` X-Opaque-Id: eu-west1_123456 ``` ### Setting Timeouts For many operations in Elasticsearch, the default timeouts of HTTP libraries are too low. To increase the timeout, you can use the `request_timeout` parameter: Elasticsearch::Client.new request_timeout: 5*60 You can also use the `transport_options` argument documented below. ### Randomizing Hosts If you pass multiple hosts to the client, it rotates across them in a round-robin fashion, by default. When the same client would be running in multiple processes (eg. in a Ruby web server such as Thin), it might keep connecting to the same nodes "at once". To prevent this, you can randomize the hosts collection on initialization and reloading: Elasticsearch::Client.new hosts: ['localhost:9200', 'localhost:9201'], randomize_hosts: true ### Retrying on Failures When the client is initialized with multiple hosts, it makes sense to retry a failed request on a different host: Elasticsearch::Client.new hosts: ['localhost:9200', 'localhost:9201'], retry_on_failure: true By default, the client will retry the request 3 times. You can specify how many times to retry before it raises an exception by passing a number to `retry_on_failure`: Elasticsearch::Client.new hosts: ['localhost:9200', 'localhost:9201'], retry_on_failure: 5 These two parameters can also be used together: ```ruby Elasticsearch::Client.new hosts: ['localhost:9200', 'localhost:9201'], retry_on_status: [502, 503], retry_on_failure: 10 ``` ### Reloading Hosts Elasticsearch by default dynamically discovers new nodes in the cluster. You can leverage this in the client, and periodically check for new nodes to spread the load. To retrieve and use the information from the [_Nodes Info API_](http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-nodes-info.html) on every 10,000th request: Elasticsearch::Client.new hosts: ['localhost:9200', 'localhost:9201'], reload_connections: true You can pass a specific number of requests after which the reloading should be performed: Elasticsearch::Client.new hosts: ['localhost:9200', 'localhost:9201'], reload_connections: 1_000 To reload connections on failures, use: Elasticsearch::Client.new hosts: ['localhost:9200', 'localhost:9201'], reload_on_failure: true The reloading will timeout if not finished under 1 second by default. To change the setting: Elasticsearch::Client.new hosts: ['localhost:9200', 'localhost:9201'], sniffer_timeout: 3 **NOTE:** When using reloading hosts ("sniffing") together with authentication, just pass the scheme, user and password with the host info -- or, for more clarity, in the `http` options: Elasticsearch::Client.new host: 'localhost:9200', http: { scheme: 'https', user: 'U', password: 'P' }, reload_connections: true, reload_on_failure: true ### Connection Selector By default, the client will rotate the connections in a round-robin fashion, using the {Elasticsearch::Transport::Transport::Connections::Selector::RoundRobin} strategy. You can implement your own strategy to customize the behaviour. For example, let's have a "rack aware" strategy, which will prefer the nodes with a specific [attribute](https://github.com/elasticsearch/elasticsearch/blob/1.0/config/elasticsearch.yml#L81-L85). Only when these would be unavailable, the strategy will use the other nodes: class RackIdSelector include Elasticsearch::Transport::Transport::Connections::Selector::Base def select(options={}) connections.select do |c| # Try selecting the nodes with a `rack_id:x1` attribute first c.host[:attributes] && c.host[:attributes][:rack_id] == 'x1' end.sample || connections.to_a.sample end end Elasticsearch::Client.new hosts: ['x1.search.org', 'x2.search.org'], selector_class: RackIdSelector ### Transport Implementations By default, the client will use the [_Faraday_](https://rubygems.org/gems/faraday) HTTP library as a transport implementation. It will auto-detect and use an _adapter_ for _Faraday_ based on gems loaded in your code, preferring HTTP clients with support for persistent connections. To use the [_Patron_](https://github.com/toland/patron) HTTP, for example, just require it: ```ruby require 'patron' ``` Then, create a new client, and the _Patron_ gem will be used as the "driver": ```ruby client = Elasticsearch::Client.new client.transport.connections.first.connection.builder.adapter # => Faraday::Adapter::Patron 10.times do client.nodes.stats(metric: 'http')['nodes'].values.each do |n| puts "#{n['name']} : #{n['http']['total_opened']}" end end # => Stiletoo : 24 # => Stiletoo : 24 # => Stiletoo : 24 # => ... ``` To use a specific adapter for _Faraday_, pass it as the `adapter` argument: client = Elasticsearch::Client.new adapter: :net_http_persistent client.transport.connections.first.connection.builder.handlers # => [Faraday::Adapter::NetHttpPersistent] To pass options to the [`Faraday::Connection`](https://github.com/lostisland/faraday/blob/master/lib/faraday/connection.rb) constructor, use the `transport_options` key: client = Elasticsearch::Client.new transport_options: { request: { open_timeout: 1 }, headers: { user_agent: 'MyApp' }, params: { :format => 'yaml' }, ssl: { verify: false } } To configure the _Faraday_ instance directly, use a block: require 'patron' client = Elasticsearch::Client.new(host: 'localhost', port: '9200') do |f| f.response :logger f.adapter :patron end You can use any standard Faraday middleware and plugins in the configuration block. You can also initialize the transport class yourself, and pass it to the client constructor as the `transport` argument: ```ruby require 'patron' transport_configuration = lambda do |f| f.response :logger f.adapter :patron end transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new \ hosts: [ { host: 'localhost', port: '9200' } ], &transport_configuration # Pass the transport to the client # client = Elasticsearch::Client.new transport: transport ``` Instead of passing the transport to the constructor, you can inject it at run time: # Set up the transport # faraday_configuration = lambda do |f| f.instance_variable_set :@ssl, { verify: false } f.adapter :excon end faraday_client = Elasticsearch::Transport::Transport::HTTP::Faraday.new \ hosts: [ { host: 'my-protected-host', port: '443', user: 'USERNAME', password: 'PASSWORD', scheme: 'https' }], &faraday_configuration # Create a default client # client = Elasticsearch::Client.new # Inject the transport to the client # client.transport = faraday_client You can also use a bundled [_Curb_](https://rubygems.org/gems/curb) based transport implementation: require 'curb' require 'elasticsearch/transport/transport/http/curb' client = Elasticsearch::Client.new transport_class: Elasticsearch::Transport::Transport::HTTP::Curb client.transport.connections.first.connection # => # It's possible to customize the _Curb_ instance by passing a block to the constructor as well (in this case, as an inline block): transport = Elasticsearch::Transport::Transport::HTTP::Curb.new \ hosts: [ { host: 'localhost', port: '9200' } ], & lambda { |c| c.verbose = true } client = Elasticsearch::Client.new transport: transport You can write your own transport implementation easily, by including the {Elasticsearch::Transport::Transport::Base} module, implementing the required contract, and passing it to the client as the `transport_class` parameter -- or injecting it directly. ### Serializer Implementations By default, the [MultiJSON](http://rubygems.org/gems/multi_json) library is used as the serializer implementation, and it will pick up the "right" adapter based on gems available. The serialization component is pluggable, though, so you can write your own by including the {Elasticsearch::Transport::Transport::Serializer::Base} module, implementing the required contract, and passing it to the client as the `serializer_class` or `serializer` parameter. ### Exception Handling The library defines a [number of exception classes](https://github.com/elasticsearch/elasticsearch-ruby/blob/master/elasticsearch-transport/lib/elasticsearch/transport/transport/errors.rb) for various client and server errors, as well as unsuccessful HTTP responses, making it possible to `rescue` specific exceptions with desired granularity. The highest-level exception is {Elasticsearch::Transport::Transport::Error} and will be raised for any generic client *or* server errors. {Elasticsearch::Transport::Transport::ServerError} will be raised for server errors only. As an example for response-specific errors, a `404` response status will raise an {Elasticsearch::Transport::Transport::Errors::NotFound} exception. Finally, {Elasticsearch::Transport::Transport::SnifferTimeoutError} will be raised when connection reloading ("sniffing") times out. ## Development and Community For local development, clone the repository and run `bundle install`. See `rake -T` for a list of available Rake tasks for running tests, generating documentation, starting a testing cluster, etc. Bug fixes and features must be covered by unit tests. Integration tests are written in Ruby 1.9 syntax. Github's pull requests and issues are used to communicate, send bug reports and code contributions. ## The Architecture * {Elasticsearch::Transport::Client} is composed of {Elasticsearch::Transport::Transport} * {Elasticsearch::Transport::Transport} is composed of {Elasticsearch::Transport::Transport::Connections}, and an instance of logger, tracer, serializer and sniffer. * Logger and tracer can be any object conforming to Ruby logging interface, ie. an instance of [`Logger`](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html), [_log4r_](https://rubygems.org/gems/log4r), [_logging_](https://github.com/TwP/logging/), etc. * The {Elasticsearch::Transport::Transport::Serializer::Base} implementations handle converting data for Elasticsearch (eg. to JSON). You can implement your own serializer. * {Elasticsearch::Transport::Transport::Sniffer} allows to discover nodes in the cluster and use them as connections. * {Elasticsearch::Transport::Transport::Connections::Collection} is composed of {Elasticsearch::Transport::Transport::Connections::Connection} instances and a selector instance. * {Elasticsearch::Transport::Transport::Connections::Connection} contains the connection attributes such as hostname and port, as well as the concrete persistent "session" connected to a specific node. * The {Elasticsearch::Transport::Transport::Connections::Selector::Base} implementations allow to choose connections from the pool, eg. in a round-robin or random fashion. You can implement your own selector strategy. ## Development To work on the code, clone and bootstrap the main repository first -- please see instructions in the main [README](../README.md#development). To run tests, launch a testing cluster and use the Rake tasks: ``` time rake test:unit time rake test:integration ``` Use `COVERAGE=true` before running a test task to check coverage with Simplecov. ## License This software is licensed under the [Apache 2 license](./LICENSE). elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/Rakefile000066400000000000000000000100141462737751600257450ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require "bundler/gem_tasks" desc "Run unit tests" task :default => 'test:unit' task :test => 'test:unit' # ----- Test tasks ------------------------------------------------------------ require 'rake/testtask' require 'rspec/core/rake_task' FARADAY1_GEMFILE = 'Gemfile-faraday1.gemfile'.freeze GEMFILES = ['Gemfile', FARADAY1_GEMFILE].freeze task :install do GEMFILES.each do |gemfile| gemfile = File.expand_path("../#{gemfile}", __FILE__) sh "bundle install --gemfile #{gemfile}" end end namespace :test do desc 'Wait for Elasticsearch to be in a green state' task :wait_for_green do sh '../scripts/wait-cluster.sh' end RSpec::Core::RakeTask.new(:spec) Rake::TestTask.new(:unit) do |test| test.libs << 'lib' << 'test' test.test_files = FileList['test/unit/**/*_test.rb'] test.verbose = false test.warning = false end Rake::TestTask.new(:integration) do |test| test.libs << 'lib' << 'test' test.test_files = FileList['test/integration/**/*_test.rb'] test.deps = ['test:wait_for_green', 'test:spec'] test.verbose = false test.warning = false end desc 'Run all tests' task :all do Rake::Task['test:unit'].invoke Rake::Task['test:spec'].invoke Rake::Task['test:integration'].invoke end Rake::TestTask.new(:profile) do |test| test.libs << 'lib' << 'test' test.test_files = FileList['test/profile/**/*_test.rb'] end namespace :faraday1 do desc 'Faraday 1: Run RSpec with dependency on Faraday 1' task :spec do sh "BUNDLE_GEMFILE=#{FARADAY1_GEMFILE} bundle exec rspec" end desc 'Faraday 1: Run unit tests with dependency on Faraday 1' task :unit do Dir.glob('./test/unit/**/**.rb').each do |test| sh "BUNDLE_GEMFILE=#{FARADAY1_GEMFILE} ruby -Ilib:test #{test}" end end desc 'Faraday 1: Run integration tests with dependency on Faraday 1' task :integration do Dir.glob('./test/integration/**/**.rb').each do |test| sh "BUNDLE_GEMFILE=#{FARADAY1_GEMFILE} ruby -Ilib:test #{test}" end end desc 'Faraday 1: Run all tests' task :all do Rake::Task['test:faraday1:unit'].invoke Rake::Task['test:faraday1:spec'].invoke Rake::Task['test:faraday1:integration'].invoke end end namespace :cluster do desc "Start Elasticsearch nodes for tests" task :start do $LOAD_PATH << File.expand_path('../lib', __FILE__) << File.expand_path('../test', __FILE__) require 'elasticsearch/extensions/test/cluster' Elasticsearch::Extensions::Test::Cluster.start end desc "Stop Elasticsearch nodes for tests" task :stop do $LOAD_PATH << File.expand_path('../lib', __FILE__) << File.expand_path('../test', __FILE__) require 'elasticsearch/extensions/test/cluster' Elasticsearch::Extensions::Test::Cluster.stop end end end # ----- Documentation tasks --------------------------------------------------- require 'yard' YARD::Rake::YardocTask.new(:doc) do |t| t.options = %w| --embed-mixins --markup=markdown | end # ----- Code analysis tasks --------------------------------------------------- if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9' require 'cane/rake_task' Cane::RakeTask.new(:quality) do |cane| cane.abc_max = 15 cane.no_style = true end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/elasticsearch-transport.gemspec000066400000000000000000000065641462737751600325300ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'elasticsearch/transport/version' Gem::Specification.new do |s| s.name = 'elasticsearch-transport' s.version = Elasticsearch::Transport::VERSION s.authors = ['Karel Minarik'] s.email = ['karel.minarik@elasticsearch.org'] s.summary = 'Ruby client for Elasticsearch.' s.homepage = 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.16/index.html' s.license = 'Apache-2.0' s.metadata = { 'homepage_uri' => 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.16/index.html', 'changelog_uri' => 'https://github.com/elastic/elasticsearch-ruby/blob/7.16/CHANGELOG.md', 'source_code_uri' => 'https://github.com/elastic/elasticsearch-ruby/tree/7.16/elasticsearch-transport', 'bug_tracker_uri' => 'https://github.com/elastic/elasticsearch-ruby/issues' } s.files = `git ls-files`.split($/) s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } s.test_files = s.files.grep(%r{^(test|spec|features)/}) s.require_paths = ['lib'] s.extra_rdoc_files = [ 'README.md', 'LICENSE' ] s.rdoc_options = [ '--charset=UTF-8' ] s.required_ruby_version = '>= 2.4' s.add_dependency 'base64' s.add_dependency 'multi_json' s.add_dependency 'faraday', '>= 1', '< 3' # Faraday Adapters s.add_development_dependency 'manticore' if defined? JRUBY_VERSION s.add_development_dependency 'curb' unless defined? JRUBY_VERSION s.add_development_dependency 'ansi' s.add_development_dependency 'bundler' s.add_development_dependency 'cane' s.add_development_dependency 'elasticsearch', ['>= 7', '< 8.0.0'] s.add_development_dependency 'elasticsearch-extensions' s.add_development_dependency 'hashie' s.add_development_dependency 'minitest' s.add_development_dependency 'minitest-reporters' s.add_development_dependency 'mocha' s.add_development_dependency 'patron' unless defined? JRUBY_VERSION s.add_development_dependency 'pry' s.add_development_dependency 'rake', '~> 13' s.add_development_dependency 'require-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius) s.add_development_dependency 'ruby-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius) s.add_development_dependency 'shoulda-context' s.add_development_dependency 'simplecov' s.add_development_dependency 'test-unit', '~> 2' s.add_development_dependency 'yard' s.description = <<-DESC.gsub(/^ /, '') Ruby client for Elasticsearch. See the `elasticsearch` gem for full integration. DESC end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/000077500000000000000000000000001462737751600250525ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch-transport.rb000066400000000000000000000014521462737751600322450ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'elasticsearch/transport' elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/000077500000000000000000000000001462737751600276645ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport.rb000066400000000000000000000030611462737751600322450ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'uri' require 'time' require 'timeout' require 'zlib' require 'multi_json' require 'faraday' require 'elasticsearch/transport/transport/loggable' require 'elasticsearch/transport/transport/serializer/multi_json' require 'elasticsearch/transport/transport/sniffer' require 'elasticsearch/transport/transport/response' require 'elasticsearch/transport/transport/errors' require 'elasticsearch/transport/transport/base' require 'elasticsearch/transport/transport/connections/selector' require 'elasticsearch/transport/transport/connections/connection' require 'elasticsearch/transport/transport/connections/collection' require 'elasticsearch/transport/transport/http/faraday' require 'elasticsearch/transport/client' require 'elasticsearch/transport/redacted' require 'elasticsearch/transport/version' elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/000077500000000000000000000000001462737751600317205ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/client.rb000066400000000000000000000400041462737751600335210ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'base64' require 'elasticsearch/transport/meta_header' module Elasticsearch module Transport # Handles communication with an Elasticsearch cluster. # # See {file:README.md README} for usage and code examples. # class Client include MetaHeader DEFAULT_TRANSPORT_CLASS = Transport::HTTP::Faraday DEFAULT_LOGGER = lambda do require 'logger' logger = Logger.new(STDERR) logger.progname = 'elasticsearch' logger.formatter = proc { |severity, datetime, progname, msg| "#{datetime}: #{msg}\n" } logger end DEFAULT_TRACER = lambda do require 'logger' logger = Logger.new(STDERR) logger.progname = 'elasticsearch.tracer' logger.formatter = proc { |severity, datetime, progname, msg| "#{msg}\n" } logger end # The default host and port to use if not otherwise specified. # # @since 7.0.0 DEFAULT_HOST = 'localhost:9200'.freeze # The default port to use if connecting using a Cloud ID. # Updated from 9243 to 443 in client version 7.10.1 # # @since 7.2.0 DEFAULT_CLOUD_PORT = 443 # The default port to use if not otherwise specified. # # @since 7.2.0 DEFAULT_PORT = 9200 # Returns the transport object. # # @see Elasticsearch::Transport::Transport::Base # @see Elasticsearch::Transport::Transport::HTTP::Faraday # attr_accessor :transport # Create a client connected to an Elasticsearch cluster. # # Specify the URL via arguments or set the `ELASTICSEARCH_URL` environment variable. # # @option arguments [String,Array] :hosts Single host passed as a String or Hash, or multiple hosts # passed as an Array; `host` or `url` keys are also valid # # @option arguments [Boolean] :log Use the default logger (disabled by default) # # @option arguments [Boolean] :trace Use the default tracer (disabled by default) # # @option arguments [Object] :logger An instance of a Logger-compatible object # # @option arguments [Object] :tracer An instance of a Logger-compatible object # # @option arguments [Number] :resurrect_after After how many seconds a dead connection should be tried again # # @option arguments [Boolean,Number] :reload_connections Reload connections after X requests (false by default) # # @option arguments [Boolean] :randomize_hosts Shuffle connections on initialization and reload (false by default) # # @option arguments [Integer] :sniffer_timeout Timeout for reloading connections in seconds (1 by default) # # @option arguments [Boolean,Number] :retry_on_failure Retry X times when request fails before raising and # exception (false by default) # @option arguments [Number] :delay_on_retry Delay in milliseconds between each retry (0 by default) # # @option arguments Array :retry_on_status Retry when specific status codes are returned # # @option arguments [Boolean] :reload_on_failure Reload connections after failure (false by default) # # @option arguments [Integer] :request_timeout The request timeout to be passed to transport in options # # @option arguments [Symbol] :adapter A specific adapter for Faraday (e.g. `:patron`) # # @option arguments [Hash] :transport_options Options to be passed to the `Faraday::Connection` constructor # # @option arguments [Constant] :transport_class A specific transport class to use, will be initialized by # the client and passed hosts and all arguments # # @option arguments [Object] :transport A specific transport instance # # @option arguments [Constant] :serializer_class A specific serializer class to use, will be initialized by # the transport and passed the transport instance # # @option arguments [Constant] :selector An instance of selector strategy implemented with # {Elasticsearch::Transport::Transport::Connections::Selector::Base}. # # @option arguments [String] :send_get_body_as Specify the HTTP method to use for GET requests with a body. # (Default: GET) # @option arguments [true, false] :compression Whether to compress requests. Gzip compression will be used. # The default is false. Responses will automatically be inflated if they are compressed. # If a custom transport object is used, it must handle the request compression and response inflation. # # @option api_key [String, Hash] :api_key Use API Key Authentication, either the base64 encoding of `id` and `api_key` # joined by a colon as a String, or a hash with the `id` and `api_key` values. # @option opaque_id_prefix [String] :opaque_id_prefix set a prefix for X-Opaque-Id when initializing the client. # This will be prepended to the id you set before each request # if you're using X-Opaque-Id # @option enable_meta_header [Boolean] :enable_meta_header Enable sending the meta data header to Cloud. # (Default: true) # @option ca_fingerprint [String] :ca_fingerprint provide this value to only trust certificates that are signed by a specific CA certificate # # @yield [faraday] Access and configure the `Faraday::Connection` instance directly with a block # def initialize(arguments={}, &block) @options = arguments.each_with_object({}){ |(k,v), args| args[k.to_sym] = v } @arguments = @options @arguments[:logger] ||= @arguments[:log] ? DEFAULT_LOGGER.call() : nil @arguments[:tracer] ||= @arguments[:trace] ? DEFAULT_TRACER.call() : nil @arguments[:reload_connections] ||= false @arguments[:retry_on_failure] ||= false @arguments[:delay_on_retry] ||= 0 @arguments[:reload_on_failure] ||= false @arguments[:randomize_hosts] ||= false @arguments[:transport_options] ||= {} @arguments[:http] ||= {} @arguments[:enable_meta_header] = arguments.fetch(:enable_meta_header) { true } @options[:http] ||= {} set_api_key if (@api_key = @arguments[:api_key]) set_compatibility_header if ENV['ELASTIC_CLIENT_APIVERSIONING'] @seeds = extract_cloud_creds(@arguments) @seeds ||= __extract_hosts(@arguments[:hosts] || @arguments[:host] || @arguments[:url] || @arguments[:urls] || ENV['ELASTICSEARCH_URL'] || DEFAULT_HOST) @send_get_body_as = @arguments[:send_get_body_as] || 'GET' @opaque_id_prefix = @arguments[:opaque_id_prefix] || nil @ca_fingerprint = @arguments.delete(:ca_fingerprint) if @arguments[:request_timeout] @arguments[:transport_options][:request] = { timeout: @arguments[:request_timeout] } end if @arguments[:transport] @transport = @arguments[:transport] else @transport_class = @arguments[:transport_class] || DEFAULT_TRANSPORT_CLASS @transport = if @transport_class == Transport::HTTP::Faraday @arguments[:adapter] ||= __auto_detect_adapter set_meta_header # from include MetaHeader @transport_class.new(hosts: @seeds, options: @arguments) do |faraday| faraday.adapter(@arguments[:adapter]) block&.call faraday end else set_meta_header # from include MetaHeader @transport_class.new(hosts: @seeds, options: @arguments) end end end # Performs a request through delegation to {#transport}. # def perform_request(method, path, params = {}, body = nil, headers = nil) method = @send_get_body_as if 'GET' == method && body if (opaque_id = params.delete(:opaque_id)) headers = {} if headers.nil? opaque_id = @opaque_id_prefix ? "#{@opaque_id_prefix}#{opaque_id}" : opaque_id headers.merge!('X-Opaque-Id' => opaque_id) end validate_ca_fingerprints if @ca_fingerprint transport.perform_request(method, path, params, body, headers) end private def set_api_key @api_key = __encode(@api_key) if @api_key.is_a? Hash add_header('Authorization' => "ApiKey #{@api_key}") @arguments.delete(:user) @arguments.delete(:password) end def set_compatibility_header return unless ['1', 'true'].include?(ENV['ELASTIC_CLIENT_APIVERSIONING']) return if instance_variable_get('@options').dig(:transport_options, :headers, 'Accept') add_header( { 'Accept' => 'application/vnd.elasticsearch+json; compatible-with=7', 'Content-Type' => 'application/vnd.elasticsearch+json; compatible-with=7' } ) end def validate_ca_fingerprints transport.connections.connections.each do |connection| unless connection.host[:scheme] == 'https' raise Elasticsearch::Transport::Transport::Error, 'CA fingerprinting can\'t be configured over http' end next if connection.verified ctx = OpenSSL::SSL::SSLContext.new socket = TCPSocket.new(connection.host[:host], connection.host[:port]) ssl = OpenSSL::SSL::SSLSocket.new(socket, ctx) ssl.connect cert_store = ssl.peer_cert_chain matching_certs = cert_store.select do |cert| OpenSSL::Digest::SHA256.hexdigest(cert.to_der).upcase == @ca_fingerprint.upcase.gsub(':', '') end if matching_certs.empty? raise Elasticsearch::Transport::Transport::Error, 'Server certificate CA fingerprint does not match the value configured in ca_fingerprint' end connection.verified = true end end def add_header(header) headers = @arguments[:transport_options]&.[](:headers) || {} headers.merge!(header) @arguments[:transport_options].merge!( headers: headers ) end def extract_cloud_creds(arguments) return unless arguments[:cloud_id] && !arguments[:cloud_id].empty? name = arguments[:cloud_id].split(':')[0] cloud_url, elasticsearch_instance = Base64.decode64(arguments[:cloud_id].gsub("#{name}:", '')).split('$') if cloud_url.include?(':') url, port = cloud_url.split(':') host = "#{elasticsearch_instance}.#{url}" else host = "#{elasticsearch_instance}.#{cloud_url}" port = arguments[:port] || DEFAULT_CLOUD_PORT end [ { scheme: 'https', user: arguments[:user], password: arguments[:password], host: host, port: port.to_i } ] end # Normalizes and returns hosts configuration. # # Arrayifies the `hosts_config` argument and extracts `host` and `port` info from strings. # Performs shuffling when the `randomize_hosts` option is set. # # TODO: Refactor, so it's available in Elasticsearch::Transport::Base as well # # @return [Array] # @raise [ArgumentError] # # @api private # def __extract_hosts(hosts_config) hosts = case hosts_config when String hosts_config.split(',').map { |h| h.strip! || h } when Array hosts_config when Hash, URI [ hosts_config ] else Array(hosts_config) end host_list = hosts.map { |host| __parse_host(host) } @options[:randomize_hosts] ? host_list.shuffle! : host_list end def __parse_host(host) host_parts = case host when String if host =~ /^[a-z]+\:\/\// # Construct a new `URI::Generic` directly from the array returned by URI::split. # This avoids `URI::HTTP` and `URI::HTTPS`, which supply default ports. uri = URI::Generic.new(*URI.split(host)) default_port = uri.scheme == 'https' ? 443 : DEFAULT_PORT { scheme: uri.scheme, user: uri.user, password: uri.password, host: uri.host, path: uri.path, port: uri.port || default_port } else host, port = host.split(':') { host: host, port: port } end when URI { scheme: host.scheme, user: host.user, password: host.password, host: host.host, path: host.path, port: host.port } when Hash host else raise ArgumentError, "Please pass host as a String, URI or Hash -- #{host.class} given." end if @api_key # Remove Basic Auth if using API KEY host_parts.delete(:user) host_parts.delete(:password) else @options[:http][:user] ||= host_parts[:user] @options[:http][:password] ||= host_parts[:password] end host_parts[:port] = host_parts[:port].to_i if host_parts[:port] host_parts[:path].chomp!('/') if host_parts[:path] host_parts end # Auto-detect the best adapter (HTTP "driver") available, based on libraries # loaded by the user, preferring those with persistent connections # ("keep-alive") by default # # @return [Symbol] # # @api private # def __auto_detect_adapter case when defined?(::Patron) :patron when defined?(::Typhoeus) :typhoeus when defined?(::HTTPClient) :httpclient when defined?(::Net::HTTP::Persistent) :net_http_persistent else ::Faraday.default_adapter end end # Encode credentials for the Authorization Header # Credentials is the base64 encoding of id and api_key joined by a colon # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html def __encode(api_key) Base64.strict_encode64([api_key[:id], api_key[:api_key]].join(':')) end end end end meta_header.rb000066400000000000000000000116611462737751600344310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'base64' module Elasticsearch module Transport # Methods for the Elastic meta header used by Cloud. # X-Elastic-Client-Meta HTTP header which is used by Elastic Cloud and can be disabled when # instantiating the Client with the :enable_meta_header parameter set to `false`. # module MetaHeader def set_meta_header return if @arguments[:enable_meta_header] == false service, version = meta_header_service_version meta_headers = { service.to_sym => version, rb: RUBY_VERSION, t: Elasticsearch::Transport::VERSION } meta_headers.merge!(meta_header_engine) if meta_header_engine meta_headers.merge!(meta_header_adapter) if meta_header_adapter add_header({ 'x-elastic-client-meta' => meta_headers.map { |k, v| "#{k}=#{v}" }.join(',') }) end def meta_header_service_version if enterprise_search? Elastic::ENTERPRISE_SERVICE_VERSION elsif elasticsearch? Elastic::ELASTICSEARCH_SERVICE_VERSION elsif defined?(Elasticsearch::VERSION) [:es, client_meta_version(Elasticsearch::VERSION)] else [:es, client_meta_version(Elasticsearch::Transport::VERSION)] end end def enterprise_search? defined?(Elastic::ENTERPRISE_SERVICE_VERSION) && called_from?('enterprise-search-ruby') end def elasticsearch? defined?(Elastic::ELASTICSEARCH_SERVICE_VERSION) && called_from?('elasticsearch') end def called_from?(service) !caller.select { |c| c.match?(service) }.empty? end # We return the current version if it's a release, but if it's a pre/alpha/beta release we # return p # def client_meta_version(version) regexp = /^([0-9]+\.[0-9]+\.[0-9]+)(\.?[a-z0-9.-]+)?$/ match = version.match(regexp) return "#{match[1]}p" if (match[2]) version end def meta_header_engine case RUBY_ENGINE when 'ruby' {} when 'jruby' { jv: ENV_JAVA['java.version'], jr: JRUBY_VERSION } when 'rbx' { rbx: RUBY_VERSION } else { RUBY_ENGINE.to_sym => RUBY_VERSION } end end # This function tries to define the version for the Faraday adapter. If it hasn't been loaded # by the time we're calling this method, it's going to report the adapter (if we know it) but # return 0 as the version. It won't report anything when using a custom adapter we don't # identify. # # Returns a Hash # def meta_header_adapter if @transport_class == Transport::HTTP::Faraday version = '0' adapter_version = case @arguments[:adapter] when :patron version = Patron::VERSION if defined?(::Patron::VERSION) {pt: version} when :net_http version = if defined?(Net::HTTP::VERSION) Net::HTTP::VERSION elsif defined?(Net::HTTP::HTTPVersion) Net::HTTP::HTTPVersion end {nh: version} when :typhoeus version = Typhoeus::VERSION if defined?(::Typhoeus::VERSION) {ty: version} when :httpclient version = HTTPClient::VERSION if defined?(HTTPClient::VERSION) {hc: version} when :net_http_persistent version = Net::HTTP::Persistent::VERSION if defined?(Net::HTTP::Persistent::VERSION) {np: version} else {} end {fd: Faraday::VERSION}.merge(adapter_version) elsif defined?(Transport::HTTP::Curb) && @transport_class == Transport::HTTP::Curb {cl: Curl::CURB_VERSION} elsif defined?(Transport::HTTP::Manticore) && @transport_class == Transport::HTTP::Manticore {mc: Manticore::VERSION} end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/redacted.rb000066400000000000000000000042371462737751600340260ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Transport # Class for wrapping a hash that could have sensitive data. # When printed, the sensitive values will be redacted. # # @since 6.1.1 class Redacted < ::Hash def initialize(elements = nil) super() (elements || {}).each_pair{ |key, value| self[key] = value } end # The keys whose values will be redacted. # # @since 6.1.1 SENSITIVE_KEYS = [ :password, :pwd ].freeze # The replacement string used in place of the value for sensitive keys. # # @since 6.1.1 STRING_REPLACEMENT = ''.freeze # Get a string representation of the hash. # # @return [ String ] The string representation of the hash. # # @since 6.1.1 def inspect redacted_string(:inspect) end # Get a string representation of the hash. # # @return [ String ] The string representation of the hash. # # @since 6.1.1 def to_s redacted_string(:to_s) end private def redacted_string(method) '{' + reduce([]) do |list, (k, v)| list << "#{k.send(method)}=>#{redact(k, v, method)}" end.join(', ') + '}' end def redact(k, v, method) return STRING_REPLACEMENT if SENSITIVE_KEYS.include?(k.to_sym) v.send(method) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transport/000077500000000000000000000000001462737751600337545ustar00rootroot00000000000000base.rb000066400000000000000000000450201462737751600351350ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transport# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Transport module Transport # @abstract Module with common functionality for transport implementations. # module Base include Loggable DEFAULT_PORT = 9200 DEFAULT_PROTOCOL = 'http' DEFAULT_RELOAD_AFTER = 10_000 # Requests DEFAULT_RESURRECT_AFTER = 60 # Seconds DEFAULT_MAX_RETRIES = 3 # Requests DEFAULT_SERIALIZER_CLASS = Serializer::MultiJson SANITIZED_PASSWORD = '*' * (rand(14)+1) attr_reader :hosts, :options, :connections, :counter, :last_request_at, :protocol attr_accessor :serializer, :sniffer, :logger, :tracer, :reload_connections, :reload_after, :resurrect_after # Creates a new transport object # # @param arguments [Hash] Settings and options for the transport # @param block [Proc] Lambda or Proc which can be evaluated in the context of the "session" object # # @option arguments [Array] :hosts An Array of normalized hosts information # @option arguments [Array] :options A Hash with options (usually passed by {Client}) # # @see Client#initialize # def initialize(arguments = {}, &block) @state_mutex = Mutex.new @hosts = arguments[:hosts] || [] @options = arguments[:options] || {} @options[:http] ||= {} @options[:retry_on_status] ||= [] @options[:delay_on_retry] ||= 0 @block = block @compression = !!@options[:compression] @connections = __build_connections @serializer = options[:serializer] || ( options[:serializer_class] ? options[:serializer_class].new(self) : DEFAULT_SERIALIZER_CLASS.new(self) ) @protocol = options[:protocol] || DEFAULT_PROTOCOL @logger = options[:logger] @tracer = options[:tracer] @sniffer = options[:sniffer_class] ? options[:sniffer_class].new(self) : Sniffer.new(self) @counter = 0 @counter_mtx = Mutex.new @last_request_at = Time.now @reload_connections = options[:reload_connections] @reload_after = options[:reload_connections].is_a?(Integer) ? options[:reload_connections] : DEFAULT_RELOAD_AFTER @resurrect_after = options[:resurrect_after] || DEFAULT_RESURRECT_AFTER @retry_on_status = Array(options[:retry_on_status]).map { |d| d.to_i } end # Returns a connection from the connection pool by delegating to {Connections::Collection#get_connection}. # # Resurrects dead connection if the `resurrect_after` timeout has passed. # Increments the counter and performs connection reloading if the `reload_connections` option is set. # # @return [Connections::Connection] # @see Connections::Collection#get_connection # def get_connection(options={}) resurrect_dead_connections! if Time.now > @last_request_at + @resurrect_after @counter_mtx.synchronize { @counter += 1 } reload_connections! if reload_connections && counter % reload_after == 0 connections.get_connection(options) end # Reloads and replaces the connection collection based on cluster information # # @see Sniffer#hosts # def reload_connections! hosts = sniffer.hosts __rebuild_connections :hosts => hosts, :options => options self rescue SnifferTimeoutError log_error "[SnifferTimeoutError] Timeout when reloading connections." self end # Tries to "resurrect" all eligible dead connections # # @see Connections::Connection#resurrect! # def resurrect_dead_connections! connections.dead.each { |c| c.resurrect! } end # Rebuilds the connections collection in the transport. # # The methods *adds* new connections from the passed hosts to the collection, # and *removes* all connections not contained in the passed hosts. # # @return [Connections::Collection] # @api private # def __rebuild_connections(arguments={}) @state_mutex.synchronize do @hosts = arguments[:hosts] || [] @options = arguments[:options] || {} __close_connections new_connections = __build_connections stale_connections = @connections.all.select { |c| ! new_connections.include?(c) } new_connections = new_connections.reject { |c| @connections.all.include?(c) } @connections.remove(stale_connections) @connections.add(new_connections) @connections end end # Builds and returns a collection of connections # # The adapters have to implement the {Base#__build_connection} method. # # @return [Connections::Collection] # @api private # def __build_connections Connections::Collection.new \ :connections => hosts.map { |host| host[:protocol] = host[:scheme] || options[:scheme] || options[:http][:scheme] || DEFAULT_PROTOCOL host[:port] ||= options[:port] || options[:http][:port] || DEFAULT_PORT if (options[:user] || options[:http][:user]) && !host[:user] host[:user] ||= options[:user] || options[:http][:user] host[:password] ||= options[:password] || options[:http][:password] end __build_connection(host, (options[:transport_options] || {}), @block) }, :selector_class => options[:selector_class], :selector => options[:selector] end # @abstract Build and return a connection. # A transport implementation *must* implement this method. # See {HTTP::Faraday#__build_connection} for an example. # # @return [Connections::Connection] # @api private # def __build_connection(host, options={}, block=nil) raise NoMethodError, "Implement this method in your class" end # Closes the connections collection # # @api private # def __close_connections # A hook point for specific adapters when they need to close connections end # Log request and response information # # @api private # def __log_response(method, path, params, body, url, response, json, took, duration) if logger sanitized_url = url.to_s.gsub(/\/\/(.+):(.+)@/, '//' + '\1:' + SANITIZED_PASSWORD + '@') log_info "#{method.to_s.upcase} #{sanitized_url} " + "[status:#{response.status}, request:#{sprintf('%.3fs', duration)}, query:#{took}]" log_debug "> #{__convert_to_json(body)}" if body log_debug "< #{response.body}" end end # Trace the request in the `curl` format # # @api private # def __trace(method, path, params, headers, body, url, response, json, took, duration) trace_url = "http://localhost:9200/#{path}?pretty" + ( params.empty? ? '' : "&#{::Faraday::Utils::ParamsHash[params].to_query}" ) trace_body = body ? " -d '#{__convert_to_json(body, :pretty => true)}'" : '' trace_command = "curl -X #{method.to_s.upcase}" trace_command += " -H '#{headers.collect { |k,v| "#{k}: #{v}" }.join(", ")}'" if headers && !headers.empty? trace_command += " '#{trace_url}'#{trace_body}\n" tracer.info trace_command tracer.debug "# #{Time.now.iso8601} [#{response.status}] (#{format('%.3f', duration)}s)\n#" tracer.debug json ? serializer.dump(json, :pretty => true).gsub(/^/, '# ').sub(/\}$/, "\n# }")+"\n" : "# #{response.body}\n" end # Raise error specific for the HTTP response status or a generic server error # # @api private # def __raise_transport_error(response) error = ERRORS[response.status] || ServerError raise error.new "[#{response.status}] #{response.body}" end # Converts any non-String object to JSON # # @api private # def __convert_to_json(o=nil, options={}) o.is_a?(String) ? o : serializer.dump(o, options) end # Returns a full URL based on information from host # # @param host [Hash] Host configuration passed in from {Client} # # @api private def __full_url(host) url = "#{host[:protocol]}://" url += "#{CGI.escape(host[:user])}:#{CGI.escape(host[:password])}@" if host[:user] url += host[:host] url += ":#{host[:port]}" if host[:port] url += host[:path] if host[:path] url end # Performs a request to Elasticsearch, while handling logging, tracing, marking dead connections, # retrying the request and reloading the connections. # # @abstract The transport implementation has to implement this method either in full, # or by invoking this method with a block. See {HTTP::Faraday#perform_request} for an example. # # @param method [String] Request method # @param path [String] The API endpoint # @param params [Hash] Request parameters (will be serialized by {Connections::Connection#full_url}) # @param body [Hash] Request body (will be serialized by the {#serializer}) # @param headers [Hash] Request headers (will be serialized by the {#serializer}) # @param block [Proc] Code block to evaluate, passed from the implementation # # @return [Response] # @raise [NoMethodError] If no block is passed # @raise [ServerError] If request failed on server # @raise [Error] If no connection is available # def perform_request(method, path, params = {}, body = nil, headers = nil, opts = {}, &block) raise NoMethodError, 'Implement this method in your transport class' unless block_given? start = Time.now tries = 0 reload_on_failure = opts.fetch(:reload_on_failure, @options[:reload_on_failure]) delay_on_retry = opts.fetch(:delay_on_retry, @options[:delay_on_retry]) max_retries = if opts.key?(:retry_on_failure) opts[:retry_on_failure] === true ? DEFAULT_MAX_RETRIES : opts[:retry_on_failure] elsif options.key?(:retry_on_failure) options[:retry_on_failure] === true ? DEFAULT_MAX_RETRIES : options[:retry_on_failure] end params = params.clone ignore = Array(params.delete(:ignore)).compact.map { |s| s.to_i } begin sleep(delay_on_retry / 1000.0) if tries > 0 tries += 1 connection = get_connection or raise Error.new('Cannot get new connection from pool.') if connection.connection.respond_to?(:params) && connection.connection.params.respond_to?(:to_hash) params = connection.connection.params.merge(params.to_hash) end url = connection.full_url(path, params) response = block.call(connection, url) connection.healthy! if connection.failures > 0 # Raise an exception so we can catch it for `retry_on_status` __raise_transport_error(response) if response.status.to_i >= 300 && @retry_on_status.include?(response.status.to_i) rescue Elasticsearch::Transport::Transport::ServerError => e if response && @retry_on_status.include?(response.status) log_warn "[#{e.class}] Attempt #{tries} to get response from #{url}" if tries <= (max_retries || DEFAULT_MAX_RETRIES) retry else log_fatal "[#{e.class}] Cannot get response from #{url} after #{tries} tries" raise e end else raise e end rescue *host_unreachable_exceptions => e log_error "[#{e.class}] #{e.message} #{connection.host.inspect}" connection.dead! if reload_on_failure and tries < connections.all.size log_warn "[#{e.class}] Reloading connections (attempt #{tries} of #{connections.all.size})" reload_connections! and retry end if max_retries log_warn "[#{e.class}] Attempt #{tries} connecting to #{connection.host.inspect}" if tries <= max_retries retry else log_fatal "[#{e.class}] Cannot connect to #{connection.host.inspect} after #{tries} tries" raise e end else raise e end rescue Exception => e log_fatal "[#{e.class}] #{e.message} (#{connection.host.inspect if connection})" raise e end #/begin duration = Time.now - start if response.status.to_i >= 300 __log_response(method, path, params, body, url, response, nil, 'N/A', duration) __trace(method, path, params, connection_headers(connection), body, url, response, nil, 'N/A', duration) if tracer # Log the failure only when `ignore` doesn't match the response status log_fatal "[#{response.status}] #{response.body}" unless ignore.include?(response.status.to_i) __raise_transport_error response unless ignore.include?(response.status.to_i) end json = serializer.load(response.body) if response.body && !response.body.empty? && response.headers && response.headers["content-type"] =~ /json/ took = (json['took'] ? sprintf('%.3fs', json['took']/1000.0) : 'n/a') rescue 'n/a' unless ignore.include?(response.status.to_i) __log_response method, path, params, body, url, response, json, took, duration end __trace(method, path, params, connection_headers(connection), body, url, response, nil, 'N/A', duration) if tracer log_warn(response.headers['warning']) if response.headers&.[]('warning') Response.new response.status, json || response.body, response.headers ensure @last_request_at = Time.now end # @abstract Returns an Array of connection errors specific to the transport implementation. # See {HTTP::Faraday#host_unreachable_exceptions} for an example. # # @return [Array] # def host_unreachable_exceptions [Errno::ECONNREFUSED] end private USER_AGENT_STR = 'User-Agent'.freeze USER_AGENT_REGEX = /user\-?\_?agent/ ACCEPT_ENCODING = 'Accept-Encoding'.freeze CONTENT_ENCODING = 'Content-Encoding'.freeze CONTENT_TYPE_STR = 'Content-Type'.freeze CONTENT_TYPE_REGEX = /content\-?\_?type/ DEFAULT_CONTENT_TYPE = 'application/json'.freeze GZIP = 'gzip'.freeze GZIP_FIRST_TWO_BYTES = '1f8b'.freeze HEX_STRING_DIRECTIVE = 'H*'.freeze RUBY_ENCODING = '1.9'.respond_to?(:force_encoding) def compress_request(body, headers) if body headers ||= {} if gzipped?(body) headers[CONTENT_ENCODING] = GZIP elsif use_compression? headers[CONTENT_ENCODING] = GZIP gzip = Zlib::GzipWriter.new(StringIO.new) gzip << body body = gzip.close.string else headers.delete(CONTENT_ENCODING) end elsif headers headers.delete(CONTENT_ENCODING) end [body, headers] end def decompress_response(body) return body unless gzipped?(body) io = StringIO.new(body) gzip_reader = if RUBY_ENCODING Zlib::GzipReader.new(io, :encoding => 'ASCII-8BIT') else Zlib::GzipReader.new(io) end gzip_reader.read end def gzipped?(body) return unless body && !body.empty? body[0..1].unpack(HEX_STRING_DIRECTIVE)[0] == GZIP_FIRST_TWO_BYTES end def use_compression? @compression end def apply_headers(client, options) headers = options[:headers] || {} headers[CONTENT_TYPE_STR] = find_value(headers, CONTENT_TYPE_REGEX) || DEFAULT_CONTENT_TYPE headers[USER_AGENT_STR] = find_value(headers, USER_AGENT_REGEX) || user_agent_header(client) client.headers[ACCEPT_ENCODING] = GZIP if use_compression? client.headers.merge!(headers) end def find_value(hash, regex) key_value = hash.find { |k, _| k.to_s.downcase =~ regex } if key_value hash.delete(key_value[0]) key_value[1] end end def user_agent_header(client) @user_agent ||= begin meta = ["RUBY_VERSION: #{RUBY_VERSION}"] if RbConfig::CONFIG && RbConfig::CONFIG['host_os'] meta << "#{RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase} #{RbConfig::CONFIG['target_cpu']}" end "elasticsearch-ruby/#{VERSION} (#{meta.join('; ')})" end end def connection_headers(connection) if defined?(Elasticsearch::Transport::Transport::HTTP::Manticore) && self.class == Elasticsearch::Transport::Transport::HTTP::Manticore @request_options[:headers] else connection.connection.headers end end end end end end connections/000077500000000000000000000000001462737751600362175ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transportcollection.rb000066400000000000000000000075551462737751600407130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transport/connections# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Transport module Transport module Connections # Wraps the collection of connections for the transport object as an Enumerable object. # # @see Base#connections # @see Selector::Base#select # @see Connection # class Collection include Enumerable DEFAULT_SELECTOR = Selector::RoundRobin attr_reader :selector # @option arguments [Array] :connections An array of {Connection} objects. # @option arguments [Constant] :selector_class The class to be used as a connection selector strategy. # @option arguments [Object] :selector The selector strategy object. # def initialize(arguments={}) selector_class = arguments[:selector_class] || DEFAULT_SELECTOR @connections = arguments[:connections] || [] @selector = arguments[:selector] || selector_class.new(arguments.merge(:connections => self)) end # Returns an Array of hosts information in this collection as Hashes. # # @return [Array] # def hosts @connections.to_a.map { |c| c.host } end # Returns an Array of alive connections. # # @return [Array] # def connections @connections.reject { |c| c.dead? } end alias :alive :connections # Returns an Array of dead connections. # # @return [Array] # def dead @connections.select { |c| c.dead? } end # Returns an Array of all connections, both dead and alive # # @return [Array] # def all @connections end # Returns a connection. # # If there are no alive connections, returns a connection with least failures. # Delegates to selector's `#select` method to get the connection. # # @return [Connection] # def get_connection(options={}) selector.select(options) || @connections.min_by(&:failures) end def each(&block) connections.each(&block) end def slice(*args) connections.slice(*args) end alias :[] :slice def size connections.size end # Add connection(s) to the collection # # @param connections [Connection,Array] A connection or an array of connections to add # @return [self] # def add(connections) @connections += Array(connections).to_a self end # Remove connection(s) from the collection # # @param connections [Connection,Array] A connection or an array of connections to remove # @return [self] # def remove(connections) @connections -= Array(connections).to_a self end end end end end end connection.rb000066400000000000000000000130731462737751600407070ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transport/connections# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Transport module Transport module Connections # Wraps the connection information and logic. # # The Connection instance wraps the host information (hostname, port, attributes, etc), # as well as the "session" (a transport client object, such as a {HTTP::Faraday} instance). # # It provides methods to construct and properly encode the URLs and paths for passing them # to the transport client object. # # It provides methods to handle connection livecycle (dead, alive, healthy). # class Connection DEFAULT_RESURRECT_TIMEOUT = 60 attr_reader :host, :connection, :options, :failures, :dead_since attr_accessor :verified # @option arguments [Hash] :host Host information (example: `{host: 'localhost', port: 9200}`) # @option arguments [Object] :connection The transport-specific physical connection or "session" # @option arguments [Hash] :options Options (usually passed in from transport) # def initialize(arguments={}) @host = arguments[:host].is_a?(Hash) ? Redacted.new(arguments[:host]) : arguments[:host] @connection = arguments[:connection] @options = arguments[:options] || {} @verified = false @state_mutex = Mutex.new @options[:resurrect_timeout] ||= DEFAULT_RESURRECT_TIMEOUT @dead = false @failures = 0 end # Returns the complete endpoint URL with host, port, path and serialized parameters. # # @return [String] # def full_url(path, params = {}) url = "#{host[:protocol]}://" url += "#{CGI.escape(host[:user])}:#{CGI.escape(host[:password])}@" if host[:user] url += "#{host[:host]}:#{host[:port]}" url += "#{host[:path]}" if host[:path] full_path = full_path(path, params) url += '/' unless full_path.match?(/^\//) url += full_path end # Returns the complete endpoint path with serialized parameters. # # @return [String] # def full_path(path, params={}) path + (params.empty? ? '' : "?#{::Faraday::Utils::ParamsHash[params].to_query}") end # Returns true when this connection has been marked dead, false otherwise. # # @return [Boolean] # def dead? @dead || false end # Marks this connection as dead, incrementing the `failures` counter and # storing the current time as `dead_since`. # # @return [self] # def dead! @state_mutex.synchronize do @dead = true @failures += 1 @dead_since = Time.now end self end # Marks this connection as alive, ie. it is eligible to be returned from the pool by the selector. # # @return [self] # def alive! @state_mutex.synchronize do @dead = false end self end # Marks this connection as healthy, ie. a request has been successfully performed with it. # # @return [self] # def healthy! @state_mutex.synchronize do @dead = false @failures = 0 end self end # Marks this connection as alive, if the required timeout has passed. # # @return [self,nil] # @see DEFAULT_RESURRECT_TIMEOUT # @see #resurrectable? # def resurrect! alive! if resurrectable? end # Returns true if the connection is eligible to be resurrected as alive, false otherwise. # # @return [Boolean] # def resurrectable? @state_mutex.synchronize { Time.now > @dead_since + ( @options[:resurrect_timeout] * 2 ** (@failures-1) ) } end # Equality operator based on connection protocol, host, port and attributes # # @return [Boolean] # def ==(other) self.host[:protocol] == other.host[:protocol] && \ self.host[:host] == other.host[:host] && \ self.host[:port].to_i == other.host[:port].to_i && \ self.host[:attributes] == other.host[:attributes] end # @return [String] # def to_s "<#{self.class.name} host: #{host} (#{dead? ? 'dead since ' + dead_since.to_s : 'alive'})>" end end end end end end selector.rb000066400000000000000000000056561462737751600404000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transport/connections# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Transport module Transport module Connections module Selector # @abstract Common functionality for connection selector implementations. # module Base attr_reader :connections # @option arguments [Connections::Collection] :connections Collection with connections. # def initialize(arguments={}) @connections = arguments[:connections] end # @abstract Selector strategies implement this method to # select and return a connection from the pool. # # @return [Connection] # def select(options={}) raise NoMethodError, "Implement this method in the selector implementation." end end # "Random connection" selector strategy. # class Random include Base # Returns a random connection from the collection. # # @return [Connections::Connection] # def select(options={}) connections.to_a.send( defined?(RUBY_VERSION) && RUBY_VERSION > '1.9' ? :sample : :choice) end end # "Round-robin" selector strategy (default). # class RoundRobin include Base # @option arguments [Connections::Collection] :connections Collection with connections. # def initialize(arguments = {}) super @mutex = Mutex.new @current = nil end # Returns the next connection from the collection, rotating them in round-robin fashion. # # @return [Connections::Connection] # def select(options={}) @mutex.synchronize do conns = connections if @current && (@current < conns.size-1) @current += 1 else @current = 0 end conns[@current] end end end end end end end end errors.rb000066400000000000000000000054221462737751600355410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transport# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Transport module Transport # Generic client error # class Error < StandardError; end # Reloading connections timeout (1 sec by default) # class SnifferTimeoutError < Timeout::Error; end # Elasticsearch server error (HTTP status 5xx) # class ServerError < Error; end module Errors; end HTTP_STATUSES = { 300 => 'MultipleChoices', 301 => 'MovedPermanently', 302 => 'Found', 303 => 'SeeOther', 304 => 'NotModified', 305 => 'UseProxy', 307 => 'TemporaryRedirect', 308 => 'PermanentRedirect', 400 => 'BadRequest', 401 => 'Unauthorized', 402 => 'PaymentRequired', 403 => 'Forbidden', 404 => 'NotFound', 405 => 'MethodNotAllowed', 406 => 'NotAcceptable', 407 => 'ProxyAuthenticationRequired', 408 => 'RequestTimeout', 409 => 'Conflict', 410 => 'Gone', 411 => 'LengthRequired', 412 => 'PreconditionFailed', 413 => 'RequestEntityTooLarge', 414 => 'RequestURITooLong', 415 => 'UnsupportedMediaType', 416 => 'RequestedRangeNotSatisfiable', 417 => 'ExpectationFailed', 418 => 'ImATeapot', 421 => 'TooManyConnectionsFromThisIP', 426 => 'UpgradeRequired', 429 => 'TooManyRequests', 450 => 'BlockedByWindowsParentalControls', 494 => 'RequestHeaderTooLarge', 497 => 'HTTPToHTTPS', 499 => 'ClientClosedRequest', 500 => 'InternalServerError', 501 => 'NotImplemented', 502 => 'BadGateway', 503 => 'ServiceUnavailable', 504 => 'GatewayTimeout', 505 => 'HTTPVersionNotSupported', 506 => 'VariantAlsoNegotiates', 510 => 'NotExtended' } ERRORS = HTTP_STATUSES.inject({}) do |sum, error| status, name = error sum[status] = Errors.const_set name, Class.new(ServerError) sum end end end end http/000077500000000000000000000000001462737751600346545ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transportcurb.rb000066400000000000000000000115361462737751600361420ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transport/http# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Transport module Transport module HTTP # Alternative HTTP transport implementation, using the [_Curb_](https://rubygems.org/gems/curb) client. # # @see Transport::Base # class Curb include Base # Performs the request by invoking {Transport::Base#perform_request} with a block. # # @return [Response] # @see Transport::Base#perform_request # def perform_request(method, path, params={}, body=nil, headers=nil, opts={}) super do |connection, _url| connection.connection.url = connection.full_url(path, params) body = body ? __convert_to_json(body) : nil body, headers = compress_request(body, headers) case method when 'HEAD' connection.connection.set :nobody, true when 'GET', 'POST', 'PUT', 'DELETE' connection.connection.set :nobody, false connection.connection.put_data = body if body if headers if connection.connection.headers connection.connection.headers.merge!(headers) else connection.connection.headers = headers end end else raise ArgumentError, "Unsupported HTTP method: #{method}" end connection.connection.http(method.to_sym) Response.new( connection.connection.response_code, decompress_response(connection.connection.body_str), headers(connection) ) end end def headers(connection) headers_string = connection.connection.header_str return nil if headers_string.nil? response_headers = headers_string&.split(/\\r\\n|\r\n/).reject(&:empty?) response_headers.shift # Removes HTTP status string processed_header = response_headers.flat_map { |s| s.scan(/^(\S+): (.+)/) } headers_hash = Hash[processed_header].transform_keys(&:downcase) if headers_hash['content-type']&.match?(/application\/json/) headers_hash['content-type'] = 'application/json' end headers_hash end # Builds and returns a connection # # @return [Connections::Connection] # def __build_connection(host, options={}, block=nil) client = ::Curl::Easy.new apply_headers(client, options) client.url = __full_url(host) if host[:user] client.http_auth_types = host[:auth_type] || :basic client.username = host[:user] client.password = host[:password] end client.instance_eval(&block) if block Connections::Connection.new :host => host, :connection => client end # Returns an array of implementation specific connection errors. # # @return [Array] # def host_unreachable_exceptions [ ::Curl::Err::HostResolutionError, ::Curl::Err::ConnectionFailedError, ::Curl::Err::GotNothingError, ::Curl::Err::RecvError, ::Curl::Err::SendError, ::Curl::Err::TimeoutError ] end private def user_agent_header(client) @user_agent ||= begin meta = ["RUBY_VERSION: #{RUBY_VERSION}"] if RbConfig::CONFIG && RbConfig::CONFIG['host_os'] meta << "#{RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase} #{RbConfig::CONFIG['target_cpu']}" end meta << "Curb #{Curl::CURB_VERSION}" "elasticsearch-ruby/#{VERSION} (#{meta.join('; ')})" end end end end end end end faraday.rb000066400000000000000000000067211462737751600366160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transport/http# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Transport module Transport module HTTP # The default transport implementation, using the [_Faraday_](https://rubygems.org/gems/faraday) # library for abstracting the HTTP client. # # @see Transport::Base # class Faraday include Base # Performs the request by invoking {Transport::Base#perform_request} with a block. # # @return [Response] # @see Transport::Base#perform_request # def perform_request(method, path, params = {}, body = nil, headers = nil, opts = {}) super do |connection, url| headers = if connection.connection.headers if !headers.nil? connection.connection.headers.merge(headers) else connection.connection.headers end else headers end body = body ? __convert_to_json(body) : nil body, headers = compress_request(body, headers) response = connection.connection.run_request(method.downcase.to_sym, url, body, headers) Response.new response.status, decompress_response(response.body), response.headers end end # Builds and returns a connection # # @return [Connections::Connection] # def __build_connection(host, options={}, block=nil) client = ::Faraday.new(__full_url(host), options, &block) apply_headers(client, options) Connections::Connection.new(host: host, connection: client) end # Returns an array of implementation specific connection errors. # # @return [Array] # def host_unreachable_exceptions [::Faraday::ConnectionFailed, ::Faraday::TimeoutError] end private def user_agent_header(client) @user_agent ||= begin meta = ["RUBY_VERSION: #{RUBY_VERSION}"] if RbConfig::CONFIG && RbConfig::CONFIG['host_os'] meta << "#{RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase} #{RbConfig::CONFIG['target_cpu']}" end meta << "#{client.headers[USER_AGENT_STR]}" "elasticsearch-ruby/#{VERSION} (#{meta.join('; ')})" end end end end end end end manticore.rb000066400000000000000000000161421462737751600371660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transport/http# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'manticore' module Elasticsearch module Transport module Transport module HTTP # Alternative HTTP transport implementation for JRuby, # using the [_Manticore_](https://github.com/cheald/manticore) client, # # @example HTTP # # require 'elasticsearch/transport/transport/http/manticore' # # client = Elasticsearch::Client.new transport_class: Elasticsearch::Transport::Transport::HTTP::Manticore # # client.transport.connections.first.connection # => # # # client.info['status'] # => 200 # # @example HTTPS (All SSL settings are optional, # see http://www.rubydoc.info/gems/manticore/Manticore/Client:initialize) # # require 'elasticsearch/transport/transport/http/manticore' # # client = Elasticsearch::Client.new \ # url: 'https://elasticsearch.example.com', # transport_class: Elasticsearch::Transport::Transport::HTTP::Manticore, # ssl: { # truststore: '/tmp/truststore.jks', # truststore_password: 'password', # keystore: '/tmp/keystore.jks', # keystore_password: 'secret', # } # # client.transport.connections.first.connection # => # # # client.info['status'] # => 200 # # @see Transport::Base # class Manticore include Base def initialize(arguments = {}, &block) @request_options = { headers: ( arguments.dig(:transport_options, :headers) || arguments.dig(:options, :transport_options, :headers) || {} ) } @manticore = build_client(arguments[:options] || {}) super(arguments, &block) end # Should just be run once at startup def build_client(options = {}) client_options = options[:transport_options] || {} client_options[:ssl] = options[:ssl] || {} @manticore = ::Manticore::Client.new(client_options) end # Performs the request by invoking {Transport::Base#perform_request} with a block. # # @return [Response] # @see Transport::Base#perform_request # def perform_request(method, path, params = {}, body = nil, headers = nil, opts = {}) super do |connection, url| body = body ? __convert_to_json(body) : nil body, headers = compress_request(body, parse_headers(headers)) params[:body] = body if body params[:headers] = headers if headers case method when 'GET' resp = connection.connection.get(url, params) when 'HEAD' resp = connection.connection.head(url, params) when 'PUT' resp = connection.connection.put(url, params) when 'POST' resp = connection.connection.post(url, params) when 'DELETE' resp = connection.connection.delete(url, params) else raise ArgumentError.new "Method #{method} not supported" end Response.new(resp.code, resp.read_body, resp.headers) end end # Builds and returns a collection of connections. # Each connection is a Manticore::Client # # @return [Connections::Collection] # def __build_connections apply_headers(options) Connections::Collection.new( connections: hosts.map do |host| host[:protocol] = host[:scheme] || DEFAULT_PROTOCOL host[:port] ||= DEFAULT_PORT host.delete(:user) # auth is not supported here. host.delete(:password) # use the headers Connections::Connection.new(host: host, connection: @manticore) end, selector_class: options[:selector_class], selector: options[:selector] ) end # Closes all connections by marking them as dead # and closing the underlying HttpClient instances # # @return [Connections::Collection] # def __close_connections # The Manticore adapter uses a single long-lived instance # of Manticore::Client, so we don't close the connections. end # Returns an array of implementation specific connection errors. # # @return [Array] # def host_unreachable_exceptions [ ::Manticore::Timeout, ::Manticore::SocketException, ::Manticore::ClientProtocolException, ::Manticore::ResolutionFailure ] end private def parse_headers(headers) request_headers = @request_options.fetch(:headers, {}) headers = request_headers.merge(headers || {}) headers.empty? ? nil : headers end def apply_headers(options) headers = options[:headers].clone || options.dig(:transport_options, :headers).clone || {} headers[CONTENT_TYPE_STR] = find_value(headers, CONTENT_TYPE_REGEX) || DEFAULT_CONTENT_TYPE headers[USER_AGENT_STR] = find_value(headers, USER_AGENT_REGEX) || find_value(@request_options[:headers], USER_AGENT_REGEX) || user_agent_header headers[ACCEPT_ENCODING] = GZIP if use_compression? @request_options[:headers].merge!(headers) end def user_agent_header @user_agent_header ||= begin meta = ["RUBY_VERSION: #{JRUBY_VERSION}"] if RbConfig::CONFIG && RbConfig::CONFIG['host_os'] meta << "#{RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase} #{RbConfig::CONFIG['target_cpu']}" end meta << "Manticore #{::Manticore::VERSION}" "elasticsearch-ruby/#{VERSION} (#{meta.join('; ')})" end end end end end end end loggable.rb000066400000000000000000000043141462737751600360000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transport# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch # Module to encapsulate all logging functionality. # # @since 7.0.0 module Loggable # Log a debug message. # # @example Log a debug message. # log_debug('Message') # # @param [ String ] message The message to log. # # @since 7.0.0 def log_debug(message) logger.debug(message) if logger && logger.debug? end # Log an error message. # # @example Log an error message. # log_error('Message') # # @param [ String ] message The message to log. # # @since 7.0.0 def log_error(message) logger.error(message) if logger && logger.error? end # Log a fatal message. # # @example Log a fatal message. # log_fatal('Message') # # @param [ String ] message The message to log. # # @since 7.0.0 def log_fatal(message) logger.fatal(message) if logger && logger.fatal? end # Log an info message. # # @example Log an info message. # log_info('Message') # # @param [ String ] message The message to log. # # @since 7.0.0 def log_info(message) logger.info(message) if logger && logger.info? end # Log a warn message. # # @example Log a warn message. # log_warn('Message') # # @param [ String ] message The message to log. # # @since 7.0.0 def log_warn(message) logger.warn(message) if logger && logger.warn? end end end response.rb000066400000000000000000000025261462737751600360650ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transport# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Transport module Transport # Wraps the response from Elasticsearch. # class Response attr_reader :status, :body, :headers # @param status [Integer] Response status code # @param body [String] Response body # @param headers [Hash] Response headers def initialize(status, body, headers={}) @status, @body, @headers = status, body, headers @body = body.force_encoding('UTF-8') if body.respond_to?(:force_encoding) && !body.frozen? end end end end end serializer/000077500000000000000000000000001462737751600360465ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transportmulti_json.rb000066400000000000000000000032141462737751600405560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transport/serializer# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Transport module Transport module Serializer # An abstract class for implementing serializer implementations # module Base # @param transport [Object] The instance of transport which uses this serializer # def initialize(transport=nil) @transport = transport end end # A default JSON serializer (using [MultiJSON](http://rubygems.org/gems/multi_json)) # class MultiJson include Base # De-serialize a Hash from JSON string # def load(string, options={}) ::MultiJson.load(string, options) end # Serialize a Hash to JSON string # def dump(object, options={}) ::MultiJson.dump(object, options) end end end end end end sniffer.rb000066400000000000000000000063271462737751600356660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/transport# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Transport module Transport # Handles node discovery ("sniffing") # class Sniffer PROTOCOL = 'http' attr_reader :transport attr_accessor :timeout # @param transport [Object] A transport instance # def initialize(transport) @transport = transport @timeout = transport.options[:sniffer_timeout] || 1 end # Retrieves the node list from the Elasticsearch's # [_Nodes Info API_](https://www.elastic.co/guide/reference/api/admin-cluster-nodes-info/) # and returns a normalized Array of information suitable for passing to transport. # # Shuffles the collection before returning it when the `randomize_hosts` option is set for transport. # # @return [Array] # @raise [SnifferTimeoutError] # def hosts Timeout::timeout(timeout, SnifferTimeoutError) do nodes = perform_sniff_request.body hosts = nodes['nodes'].map do |id, info| next unless info[PROTOCOL] host, port = parse_publish_address(info[PROTOCOL]['publish_address']) { id: id, name: info['name'], version: info['version'], host: host, port: port, roles: info['roles'], attributes: info['attributes'] } end.compact hosts.shuffle! if transport.options[:randomize_hosts] hosts end end private def perform_sniff_request transport.perform_request( 'GET', '_nodes/http', {}, nil, nil, reload_on_failure: false ) end def parse_publish_address(publish_address) # publish_address is in the format hostname/ip:port if publish_address =~ /\// parts = publish_address.partition('/') [ parts[0], parse_address_port(parts[2])[1] ] else parse_address_port(publish_address) end end def parse_address_port(publish_address) # address is ipv6 if publish_address =~ /[\[\]]/ if parts = publish_address.match(/\A\[(.+)\](?::(\d+))?\z/) [ parts[1], parts[2] ] end else publish_address.split(':') end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/lib/elasticsearch/transport/version.rb000066400000000000000000000015311462737751600337320ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Transport VERSION = '7.17.11'.freeze end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/000077500000000000000000000000001462737751600252365ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/elasticsearch/000077500000000000000000000000001462737751600300505ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/elasticsearch/connections/000077500000000000000000000000001462737751600323725ustar00rootroot00000000000000collection_spec.rb000066400000000000000000000155631462737751600360170ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/elasticsearch/connections# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::Transport::Transport::Connections::Collection do describe '#initialize' do let(:collection) do described_class.new end it 'has an empty list of connections as a default' do expect(collection.connections).to be_empty end it 'has a default selector class' do expect(collection.selector).not_to be_nil end context 'when a selector class is specified' do let(:collection) do described_class.new(selector_class: Elasticsearch::Transport::Transport::Connections::Selector::Random) end it 'sets the selector' do expect(collection.selector).to be_a(Elasticsearch::Transport::Transport::Connections::Selector::Random) end end end describe '#get_connection' do let(:collection) do described_class.new(selector_class: Elasticsearch::Transport::Transport::Connections::Selector::Random) end before do expect(collection.selector).to receive(:select).and_return('OK') end it 'uses the selector to select a connection' do expect(collection.get_connection).to eq('OK') end end describe '#hosts' do let(:collection) do described_class.new(connections: [ double('connection', host: 'A'), double('connection', host: 'B') ]) end it 'returns a list of hosts' do expect(collection.hosts).to eq([ 'A', 'B']) end end describe 'enumerable' do let(:collection) do described_class.new(connections: [ double('connection', host: 'A', dead?: false), double('connection', host: 'B', dead?: false) ]) end describe '#map' do it 'responds to the method' do expect(collection.map { |c| c.host.downcase }).to eq(['a', 'b']) end end describe '#[]' do it 'responds to the method' do expect(collection[0].host).to eq('A') expect(collection[1].host).to eq('B') end end describe '#size' do it 'responds to the method' do expect(collection.size).to eq(2) end end context 'when a connection is marked as dead' do let(:collection) do described_class.new(connections: [ double('connection', host: 'A', dead?: true), double('connection', host: 'B', dead?: false) ]) end it 'does not enumerate the dead connections' do expect(collection.size).to eq(1) expect(collection.collect { |c| c.host }).to eq(['B']) end context '#alive' do it 'enumerates the alive connections' do expect(collection.alive.collect { |c| c.host }).to eq(['B']) end end context '#dead' do it 'enumerates the alive connections' do expect(collection.dead.collect { |c| c.host }).to eq(['A']) end end end end describe '#add' do let(:collection) do described_class.new(connections: [ double('connection', host: 'A', dead?: false), double('connection', host: 'B', dead?: false) ]) end context 'when an array is provided' do before do collection.add([double('connection', host: 'C', dead?: false), double('connection', host: 'D', dead?: false)]) end it 'adds the connections' do expect(collection.size).to eq(4) end end context 'when an element is provided' do before do collection.add(double('connection', host: 'C', dead?: false)) end it 'adds the connection' do expect(collection.size).to eq(3) end end end describe '#remove' do let(:connections) do [ double('connection', host: 'A', dead?: false), double('connection', host: 'B', dead?: false) ] end let(:collection) do described_class.new(connections: connections) end context 'when an array is provided' do before do collection.remove(connections) end it 'removes the connections' do expect(collection.size).to eq(0) end end context 'when an element is provided' do let(:connections) do [ double('connection', host: 'A', dead?: false), double('connection', host: 'B', dead?: false) ] end before do collection.remove(connections.first) end it 'removes the connection' do expect(collection.size).to eq(1) end end end describe '#get_connection' do context 'when all connections are dead' do let(:connection_a) do Elasticsearch::Transport::Transport::Connections::Connection.new(host: { host: 'A' }) end let(:connection_b) do Elasticsearch::Transport::Transport::Connections::Connection.new(host: { host: 'B' }) end let(:collection) do described_class.new(connections: [connection_a, connection_b]) end before do connection_a.dead!.dead! connection_b.dead! end it 'returns the connection with the least failures' do expect(collection.get_connection.host[:host]).to eq('B') end end context 'when multiple threads are used' do let(:connections) do 20.times.collect do |i| Elasticsearch::Transport::Transport::Connections::Connection.new(host: { host: i }) end end let(:collection) do described_class.new(connections: connections) end it 'allows threads to select connections in parallel' do expect(10.times.collect do threads = [] 20.times do threads << Thread.new do collection.get_connection end end threads.map { |t| t.join } collection.get_connection.host[:host] end).to eq((0..9).to_a) end it 'always returns a connection' do threads = 20.times.map do Thread.new do 20.times.map do collection.get_connection.dead! end end end expect(threads.flat_map(&:value).size).to eq(400) end end end end selector_spec.rb000066400000000000000000000104411462737751600354720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/elasticsearch/connections# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::Transport::Transport::Connections::Selector do before do class BackupStrategySelector include Elasticsearch::Transport::Transport::Connections::Selector::Base def select(options={}) connections.reject do |c| c.host[:attributes] && c.host[:attributes][:backup] end.sample end end end after do Object.send(:remove_const, :BackupStrategySelector) end let(:backup_strategy_selector) do BackupStrategySelector.new end describe 'the Random selector' do let(:connections) do [1, 2] end let(:selector) do described_class::Random.new(connections: connections) end it 'is initialized with connections' do expect(selector.connections).to eq(connections) end describe '#select' do let(:connections) do (0..19).to_a end it 'returns a connection' do expect(selector.select).to be_a(Integer) end context 'when multiple threads are used' do it 'allows threads to select connections in parallel' do expect(10.times.collect do threads = [] 20.times do threads << Thread.new do selector.select end end threads.map { |t| t.join } selector.select end).to all(be_a(Integer)) end end end end describe 'the RoundRobin selector' do let(:connections) do ['A', 'B', 'C'] end let(:selector) do described_class::RoundRobin.new(connections: connections) end it 'is initialized with connections' do expect(selector.connections).to eq(connections) end describe '#select' do it 'rotates over the connections' do expect(selector.select).to eq('A') expect(selector.select).to eq('B') expect(selector.select).to eq('C') expect(selector.select).to eq('A') end context 'when multiple threads are used' do let(:connections) do (0..19).to_a end it 'returns a connection' do expect(selector.select).to be_a(Integer) end it 'allows threads to select connections in parallel' do expect(10.times.collect do threads = [] 20.times do threads << Thread.new do selector.select end end threads.map { |t| t.join } selector.select end).to eq((0..9).to_a) end end end end describe 'a custom selector' do let(:connections) do [ double(host: { hostname: 'host1' }), double(host: { hostname: 'host2', attributes: { backup: true } }) ] end let(:selector) do BackupStrategySelector.new(connections: connections) end it 'is initialized with connections' do expect(selector.connections).to eq(connections) end describe '#select' do it 'applies the custom strategy' do 10.times { expect(selector.select.host[:hostname]).to eq('host1') } end end end context 'when the Base module is included in a class' do before do class ExampleSelector include Elasticsearch::Transport::Transport::Connections::Selector::Base end end after do Object.send(:remove_const, :ExampleSelector) end it 'requires the #select method to be redefined' do expect { ExampleSelector.new.select }.to raise_exception(NoMethodError) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/elasticsearch/transport/000077500000000000000000000000001462737751600321045ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/elasticsearch/transport/base_spec.rb000066400000000000000000000231731462737751600343630ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::Transport::Transport::Base do context 'when a host is printed in a logged message' do shared_examples_for 'a redacted string' do let(:client) do Elasticsearch::Transport::Client.new(arguments) end let(:logger) do double('logger', error?: true, error: '') end it 'does not include the password in the logged string' do expect(logger).not_to receive(:error).with(/secret_password/) expect { client.perform_request('GET', '_cluster/stats') }.to raise_exception(Faraday::ConnectionFailed) end it 'replaces the password with the string \'REDACTED\'' do expect(logger).to receive(:error).with(/REDACTED/) expect { client.perform_request('GET', '_cluster/stats') }.to raise_exception(Faraday::ConnectionFailed) end end context 'when the user and password are provided as separate arguments' do let(:arguments) do { hosts: 'fake', logger: logger, password: 'secret_password', user: 'test' } end it_behaves_like 'a redacted string' end context 'when the user and password are provided in the string URI' do let(:arguments) do { hosts: 'https://test:secret_password@fake_local_elasticsearch', logger: logger } end if jruby? let(:client) { Elasticsearch::Transport::Client.new(arguments) } let(:logger) { double('logger', fatal?: true, fatal: '') } it 'does not include the password in the logged string' do expect(logger).not_to receive(:fatal).with(/secret_password/) expect { client.perform_request('GET', '_cluster/stats') }.to raise_exception(Faraday::SSLError) end it 'replaces the password with the string \'REDACTED\'' do expect(logger).to receive(:fatal).with(/REDACTED/) expect { client.perform_request('GET', '_cluster/stats') }.to raise_exception(Faraday::SSLError) end else it_behaves_like 'a redacted string' end end context 'when the user and password are provided in the URI object' do let(:arguments) do { hosts: URI.parse('https://test:secret_password@fake_local_elasticsearch'), logger: logger } end if jruby? let(:client) { Elasticsearch::Transport::Client.new(arguments) } let(:logger) { double('logger', fatal?: true, fatal: '') } it 'does not include the password in the logged string' do expect(logger).not_to receive(:fatal).with(/secret_password/) expect { client.perform_request('GET', '_cluster/stats') }.to raise_exception(Faraday::SSLError) end it 'replaces the password with the string \'REDACTED\'' do expect(logger).to receive(:fatal).with(/REDACTED/) expect { client.perform_request('GET', '_cluster/stats') }.to raise_exception(Faraday::SSLError) end else it_behaves_like 'a redacted string' end end end context 'when reload_on_failure is true and and hosts are unreachable' do let(:client) do Elasticsearch::Transport::Client.new(arguments) end let(:arguments) do { hosts: ['http://unavailable:9200', 'http://unavailable:9201'], reload_on_failure: true, sniffer_timeout: 5 } end it 'raises an exception' do expect { client.perform_request('GET', '/') }.to raise_exception(Faraday::ConnectionFailed) end end context 'when the client has `retry_on_failure` set to an integer' do let(:client) do Elasticsearch::Transport::Client.new(arguments) end let(:arguments) do { hosts: ['http://unavailable:9200', 'http://unavailable:9201'], retry_on_failure: 2, adapter: :net_http } end context 'when `perform_request` is called without a `retry_on_failure` option value' do before do expect(client.transport).to receive(:get_connection).exactly(3).times.and_call_original end it 'uses the client `retry_on_failure` value' do expect { client.transport.perform_request('GET', '/info') }.to raise_exception(Faraday::ConnectionFailed) end end context 'when `perform_request` is called with a `retry_on_status` option value' do before do expect(client.transport).to receive(:__raise_transport_error).exactly(6).times.and_call_original end let(:arguments) do { hosts: ELASTICSEARCH_HOSTS, retry_on_status: ['404'], adapter: :net_http } end it 'retries on 404 status the specified number of max_retries' do expect do client.transport.perform_request('GET', 'myindex/mydoc/1?routing=FOOBARBAZ', {}, nil, nil, retry_on_failure: 5) end.to raise_exception(Elasticsearch::Transport::Transport::Errors::NotFound) end end context 'when `perform_request` is called with a `retry_on_failure` option value' do before do expect(client.transport).to receive(:get_connection).exactly(6).times.and_call_original end it 'uses the option `retry_on_failure` value' do expect do client.transport.perform_request('GET', '/info', {}, nil, nil, retry_on_failure: 5) end.to raise_exception(Faraday::ConnectionFailed) end end end context 'when the client has `retry_on_failure` set to true' do let(:client) do Elasticsearch::Transport::Client.new(arguments) end let(:arguments) do { hosts: ['http://unavailable:9200', 'http://unavailable:9201'], retry_on_failure: true } end context 'when `perform_request` is called without a `retry_on_failure` option value' do before do expect(client.transport).to receive(:get_connection).exactly(4).times.and_call_original end it 'uses the default `MAX_RETRIES` value' do expect { client.transport.perform_request('GET', '/info') }.to raise_exception(Faraday::ConnectionFailed) end end context 'when `perform_request` is called with a `retry_on_failure` option value' do before do expect(client.transport).to receive(:get_connection).exactly(6).times.and_call_original end it 'uses the option `retry_on_failure` value' do expect { client.transport.perform_request('GET', '/info', {}, nil, nil, retry_on_failure: 5) }.to raise_exception(Faraday::ConnectionFailed) end end end context 'when the client has `retry_on_failure` set to false' do let(:client) do Elasticsearch::Transport::Client.new(arguments) end let(:arguments) do { hosts: ['http://unavailable:9200', 'http://unavailable:9201'], retry_on_failure: false } end context 'when `perform_request` is called without a `retry_on_failure` option value' do before do expect(client.transport).to receive(:get_connection).once.and_call_original end it 'does not retry' do expect { client.transport.perform_request('GET', '/info') }.to raise_exception(Faraday::ConnectionFailed) end end context 'when `perform_request` is called with a `retry_on_failure` option value' do before do expect(client.transport).to receive(:get_connection).exactly(6).times.and_call_original end it 'uses the option `retry_on_failure` value' do expect { client.transport.perform_request('GET', '/info', {}, nil, nil, retry_on_failure: 5) }.to raise_exception(Faraday::ConnectionFailed) end end end context 'when the client has no `retry_on_failure` set' do let(:client) do Elasticsearch::Transport::Client.new(arguments) end let(:arguments) do { hosts: ['http://unavailable:9200', 'http://unavailable:9201'] } end context 'when `perform_request` is called without a `retry_on_failure` option value' do before do expect(client.transport).to receive(:get_connection).exactly(1).times.and_call_original end it 'does not retry' do expect do client.transport.perform_request('GET', '/info') end.to raise_exception(Faraday::ConnectionFailed) end end context 'when `perform_request` is called with a `retry_on_failure` option value' do before do expect(client.transport).to receive(:get_connection).exactly(6).times.and_call_original end it 'uses the option `retry_on_failure` value' do expect do client.transport.perform_request('GET', '/info', {}, nil, nil, retry_on_failure: 5) end.to raise_exception(Faraday::ConnectionFailed) end end end end client_spec.rb000066400000000000000000001742411462737751600346530ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/elasticsearch/transport# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::Transport::Client do let(:client) do described_class.new.tap do |_client| allow(_client).to receive(:__build_connections) end end it 'has a default transport' do expect(client.transport).to be_a(Elasticsearch::Transport::Client::DEFAULT_TRANSPORT_CLASS) end it 'preserves the Faraday default user agent header' do expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/Faraday/) end it 'identifies the Ruby client in the User-Agent header' do expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/elasticsearch-ruby\/#{Elasticsearch::Transport::VERSION}/) end it 'identifies the Ruby version in the User-Agent header' do expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/#{RUBY_VERSION}/) end it 'identifies the host_os in the User-Agent header' do expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/#{RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase}/) end it 'identifies the target_cpu in the User-Agent header' do expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/#{RbConfig::CONFIG['target_cpu']}/) end it 'sets the \'Content-Type\' header to \'application/json\' by default' do expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('application/json') end it 'uses localhost by default' do expect(client.transport.hosts[0][:host]).to eq('localhost') end context 'when a User-Agent header is specified as client option' do let(:client) do described_class.new(transport_options: { headers: { 'User-Agent' => 'testing' } }) end it 'sets the specified User-Agent header' do expect(client.transport.connections.first.connection.headers['User-Agent']).to eq('testing') end end context 'when an encoded api_key is provided' do let(:client) do described_class.new(api_key: 'an_api_key') end let(:authorization_header) do client.transport.connections.first.connection.headers['Authorization'] end it 'Adds the ApiKey header to the connection' do expect(authorization_header).to eq('ApiKey an_api_key') end end context 'when an un-encoded api_key is provided' do let(:client) do described_class.new(api_key: { id: 'my_id', api_key: 'my_api_key' }) end let(:authorization_header) do client.transport.connections.first.connection.headers['Authorization'] end it 'Adds the ApiKey header to the connection' do expect(authorization_header).to eq("ApiKey #{Base64.strict_encode64('my_id:my_api_key')}") end end context 'when basic auth and api_key are provided' do let(:client) do described_class.new( api_key: { id: 'my_id', api_key: 'my_api_key' }, host: 'http://elastic:password@localhost:9200' ) end let(:authorization_header) do client.transport.connections.first.connection.headers['Authorization'] end it 'removes basic auth credentials' do expect(authorization_header).not_to match(/^Basic/) expect(authorization_header).to match(/^ApiKey/) end end context 'when a user-agent header is specified as client option in lower-case' do let(:client) do described_class.new(transport_options: { headers: { 'user-agent' => 'testing' } }) end it 'sets the specified User-Agent header' do expect(client.transport.connections.first.connection.headers['User-Agent']).to eq('testing') end end context 'when a Content-Type header is specified as client option' do let(:client) do described_class.new(transport_options: { headers: { 'Content-Type' => 'testing' } }) end it 'sets the specified Content-Type header' do expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('testing') end end context 'when a content-type header is specified as client option in lower-case' do let(:client) do described_class.new(transport_options: { headers: { 'content-type' => 'testing' } }) end it 'sets the specified Content-Type header' do expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('testing') end end context 'when the Curb transport class is used', unless: jruby? do let(:client) do described_class.new(transport_class: Elasticsearch::Transport::Transport::HTTP::Curb) end it 'preserves the Curb default user agent header' do expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/Curb/) end it 'identifies the Ruby client in the User-Agent header' do expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/elasticsearch-ruby\/#{Elasticsearch::Transport::VERSION}/) end it 'identifies the Ruby version in the User-Agent header' do expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/#{RUBY_VERSION}/) end it 'identifies the host_os in the User-Agent header' do expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/#{RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase}/) end it 'identifies the target_cpu in the User-Agent header' do expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/#{RbConfig::CONFIG['target_cpu']}/) end it 'sets the \'Content-Type\' header to \'application/json\' by default' do expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('application/json') end it 'uses localhost by default' do expect(client.transport.hosts[0][:host]).to eq('localhost') end context 'when a User-Agent header is specified as a client option' do let(:client) do described_class.new(transport_class: Elasticsearch::Transport::Transport::HTTP::Curb, transport_options: { headers: { 'User-Agent' => 'testing' } }) end it 'sets the specified User-Agent header' do expect(client.transport.connections.first.connection.headers['User-Agent']).to eq('testing') end end context 'when a user-agent header is specified as a client option as lower-case' do let(:client) do described_class.new(transport_class: Elasticsearch::Transport::Transport::HTTP::Curb, transport_options: { headers: { 'user-agent' => 'testing' } }) end it 'sets the specified User-Agent header' do expect(client.transport.connections.first.connection.headers['User-Agent']).to eq('testing') end end context 'when a Content-Type header is specified as client option' do let(:client) do described_class.new(transport_class: Elasticsearch::Transport::Transport::HTTP::Curb, transport_options: { headers: { 'Content-Type' => 'testing' } }) end it 'sets the specified Content-Type header' do expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('testing') end end context 'when a content-type header is specified as client option in lower-case' do let(:client) do described_class.new(transport_class: Elasticsearch::Transport::Transport::HTTP::Curb, transport_options: { headers: { 'content-type' => 'testing' } }) end it 'sets the specified Content-Type header' do expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('testing') end end end describe 'adapter' do context 'when no adapter is specified' do fork do let(:client) { described_class.new } let(:adapter) { client.transport.connections.all.first.connection.builder.adapter } it 'uses Faraday NetHttp' do expect(adapter).to eq Faraday::Adapter::NetHttp end end end unless jruby? context 'when the adapter is patron' do let(:adapter) do client.transport.connections.all.first.connection.builder.adapter end let(:client) do described_class.new(adapter: :patron, enable_meta_header: false) end it 'uses Faraday with the adapter' do require 'faraday/patron' expect(adapter).to eq Faraday::Adapter::Patron end end unless jruby? context 'when the adapter is typhoeus' do let(:adapter) do client.transport.connections.all.first.connection.builder.adapter end let(:client) do require 'faraday/typhoeus' if is_faraday_v2? described_class.new(adapter: :typhoeus, enable_meta_header: false) end it 'uses Faraday with the adapter' do expect(adapter).to eq Faraday::Adapter::Typhoeus end end unless jruby? context 'when the adapter is specified as a string key' do let(:adapter) do client.transport.connections.all.first.connection.builder.adapter end let(:client) do described_class.new(adapter: :patron, enable_meta_header: false) end it 'uses Faraday with the adapter' do expect(adapter).to eq Faraday::Adapter::Patron end end unless jruby? context 'when the adapter can be detected', unless: jruby? do around do |example| require 'patron'; load 'patron.rb' example.run end let(:adapter) do client.transport.connections.all.first.connection.builder.adapter end it 'uses the detected adapter' do expect(adapter).to eq Faraday::Adapter::Patron end end context 'when the Faraday adapter is configured' do let(:client) do described_class.new do |faraday| faraday.adapter :patron faraday.response :logger end end let(:adapter) do client.transport.connections.all.first.connection.builder.adapter end let(:handlers) do client.transport.connections.all.first.connection.builder.handlers end it 'sets the adapter' do expect(adapter).to eq Faraday::Adapter::Patron end it 'sets the logger' do expect(handlers).to include(Faraday::Response::Logger) end end unless jruby? end context 'when cloud credentials are provided' do let(:client) do described_class.new( cloud_id: 'name:bG9jYWxob3N0JGFiY2QkZWZnaA==', user: 'elastic', password: 'changeme' ) end let(:hosts) do client.transport.hosts end it 'extracts the cloud credentials' do expect(hosts[0][:host]).to eq('abcd.localhost') expect(hosts[0][:protocol]).to eq('https') expect(hosts[0][:user]).to eq('elastic') expect(hosts[0][:password]).to eq('changeme') expect(hosts[0][:port]).to eq(443) end it 'creates the correct full url' do expect( client.transport.__full_url(client.transport.hosts[0]) ).to eq('https://elastic:changeme@abcd.localhost:443') end context 'when a port is specified' do let(:client) do described_class.new(cloud_id: 'name:bG9jYWxob3N0JGFiY2QkZWZnaA==', user: 'elastic', password: 'changeme', port: 9250) end it 'sets the specified port along with the cloud credentials' do expect(hosts[0][:host]).to eq('abcd.localhost') expect(hosts[0][:protocol]).to eq('https') expect(hosts[0][:user]).to eq('elastic') expect(hosts[0][:password]).to eq('changeme') expect(hosts[0][:port]).to eq(9250) end it 'creates the correct full url' do expect(client.transport.__full_url(client.transport.hosts[0])).to eq('https://elastic:changeme@abcd.localhost:9250') end end context 'when the cluster has alternate names' do let(:client) do described_class.new( cloud_id: 'myCluster:bG9jYWxob3N0JGFiY2QkZWZnaA==', user: 'elasticfantastic', password: 'tobechanged' ) end let(:hosts) do client.transport.hosts end it 'extracts the cloud credentials' do expect(hosts[0][:host]).to eq('abcd.localhost') expect(hosts[0][:protocol]).to eq('https') expect(hosts[0][:user]).to eq('elasticfantastic') expect(hosts[0][:password]).to eq('tobechanged') expect(hosts[0][:port]).to eq(443) end it 'creates the correct full url' do expect( client.transport.__full_url(client.transport.hosts[0]) ).to eq('https://elasticfantastic:tobechanged@abcd.localhost:443') end end context 'when decoded cloud id has a trailing dollar sign' do let(:client) do described_class.new( cloud_id: 'a_cluster:bG9jYWxob3N0JGFiY2Qk', user: 'elasticfantastic', password: 'changeme' ) end let(:hosts) do client.transport.hosts end it 'extracts the cloud credentials' do expect(hosts[0][:host]).to eq('abcd.localhost') expect(hosts[0][:protocol]).to eq('https') expect(hosts[0][:user]).to eq('elasticfantastic') expect(hosts[0][:password]).to eq('changeme') expect(hosts[0][:port]).to eq(443) end it 'creates the correct full url' do expect( client.transport.__full_url(client.transport.hosts[0]) ).to eq('https://elasticfantastic:changeme@abcd.localhost:443') end end context 'when the cloud host provides a port' do let(:client) do described_class.new( cloud_id: 'name:ZWxhc3RpY19zZXJ2ZXI6OTI0MyRlbGFzdGljX2lk', user: 'elastic', password: 'changeme' ) end let(:hosts) do client.transport.hosts end it 'creates the correct full url' do expect(hosts[0][:host]).to eq('elastic_id.elastic_server') expect(hosts[0][:protocol]).to eq('https') expect(hosts[0][:user]).to eq('elastic') expect(hosts[0][:password]).to eq('changeme') expect(hosts[0][:port]).to eq(9243) end end context 'when the cloud host provides a port and the port is also specified' do let(:client) do described_class.new( cloud_id: 'name:ZWxhc3RpY19zZXJ2ZXI6OTI0MyRlbGFzdGljX2lk', user: 'elastic', password: 'changeme', port: 9200 ) end let(:hosts) do client.transport.hosts end it 'creates the correct full url' do expect(hosts[0][:host]).to eq('elastic_id.elastic_server') expect(hosts[0][:protocol]).to eq('https') expect(hosts[0][:user]).to eq('elastic') expect(hosts[0][:password]).to eq('changeme') expect(hosts[0][:port]).to eq(9243) end end end shared_examples_for 'a client that extracts hosts' do context 'when the host is a String' do context 'when there is a protocol specified' do context 'when credentials are specified \'http://USERNAME:PASSWORD@myhost:8080\'' do let(:host) do 'http://USERNAME:PASSWORD@myhost:8080' end it 'extracts the credentials' do expect(hosts[0][:user]).to eq('USERNAME') expect(hosts[0][:password]).to eq('PASSWORD') end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the port' do expect(hosts[0][:port]).to be(8080) end end context 'when there is a trailing slash \'http://myhost/\'' do let(:host) do 'http://myhost/' end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') expect(hosts[0][:scheme]).to eq('http') expect(hosts[0][:path]).to eq('') end it 'extracts the scheme' do expect(hosts[0][:scheme]).to eq('http') end it 'extracts the path' do expect(hosts[0][:path]).to eq('') end end context 'when there is a trailing slash with a path \'http://myhost/foo/bar/\'' do let(:host) do 'http://myhost/foo/bar/' end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') expect(hosts[0][:scheme]).to eq('http') expect(hosts[0][:path]).to eq('/foo/bar') end end context 'when the protocol is http' do context 'when there is no port specified \'http://myhost\'' do let(:host) do 'http://myhost' end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:protocol]).to eq('http') end it 'defaults to port 9200' do expect(hosts[0][:port]).to be(9200) end end context 'when there is a port specified \'http://myhost:7101\'' do let(:host) do 'http://myhost:7101' end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:protocol]).to eq('http') end it 'extracts the port' do expect(hosts[0][:port]).to be(7101) end context 'when there is a path specified \'http://myhost:7101/api\'' do let(:host) do 'http://myhost:7101/api' end it 'sets the path' do expect(hosts[0][:host]).to eq('myhost') expect(hosts[0][:protocol]).to eq('http') expect(hosts[0][:path]).to eq('/api') expect(hosts[0][:port]).to be(7101) end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:protocol]).to eq('http') end it 'extracts the port' do expect(hosts[0][:port]).to be(7101) end it 'extracts the path' do expect(hosts[0][:path]).to eq('/api') end end end end context 'when the protocol is https' do context 'when there is no port specified \'https://myhost\'' do let(:host) do 'https://myhost' end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:protocol]).to eq('https') end it 'defaults to port 443' do expect(hosts[0][:port]).to be(443) end end context 'when there is a port specified \'https://myhost:7101\'' do let(:host) do 'https://myhost:7101' end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:protocol]).to eq('https') end it 'extracts the port' do expect(hosts[0][:port]).to be(7101) end context 'when there is a path specified \'https://myhost:7101/api\'' do let(:host) do 'https://myhost:7101/api' end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:protocol]).to eq('https') end it 'extracts the port' do expect(hosts[0][:port]).to be(7101) end it 'extracts the path' do expect(hosts[0][:path]).to eq('/api') end end end context 'when IPv6 format is used' do around do |example| original_setting = Faraday.ignore_env_proxy Faraday.ignore_env_proxy = true example.run Faraday.ignore_env_proxy = original_setting end let(:host) do 'https://[2090:db8:85a3:9811::1f]:8080' end it 'extracts the host' do expect(hosts[0][:host]).to eq('[2090:db8:85a3:9811::1f]') end it 'extracts the protocol' do expect(hosts[0][:protocol]).to eq('https') end it 'extracts the port' do expect(hosts[0][:port]).to be(8080) end it 'creates the correct full url' do expect(client.transport.__full_url(client.transport.hosts[0])).to eq('https://[2090:db8:85a3:9811::1f]:8080') end end end end context 'when no protocol is specified \'myhost\'' do let(:host) do 'myhost' end it 'defaults to http' do expect(hosts[0][:host]).to eq('myhost') expect(hosts[0][:protocol]).to eq('http') end it 'uses port 9200' do expect(hosts[0][:port]).to be(9200) end end end context 'when the host is a Hash' do let(:host) do { :host => 'myhost', :scheme => 'https' } end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:protocol]).to eq('https') end it 'extracts the port' do expect(hosts[0][:port]).to be(9200) end context 'when IPv6 format is used' do around do |example| original_setting = Faraday.ignore_env_proxy Faraday.ignore_env_proxy = true example.run Faraday.ignore_env_proxy = original_setting end let(:host) do { host: '[2090:db8:85a3:9811::1f]', scheme: 'https', port: '443' } end it 'extracts the host' do expect(hosts[0][:host]).to eq('[2090:db8:85a3:9811::1f]') expect(hosts[0][:scheme]).to eq('https') expect(hosts[0][:port]).to be(443) end it 'creates the correct full url' do expect(client.transport.__full_url(client.transport.hosts[0])).to eq('https://[2090:db8:85a3:9811::1f]:443') end end context 'when the host is localhost as a IPv6 address' do around do |example| original_setting = Faraday.ignore_env_proxy Faraday.ignore_env_proxy = true example.run Faraday.ignore_env_proxy = original_setting end let(:host) do { host: '[::1]' } end it 'extracts the host' do expect(hosts[0][:host]).to eq('[::1]') expect(hosts[0][:port]).to be(9200) end it 'creates the correct full url' do expect(client.transport.__full_url(client.transport.hosts[0])).to eq('http://[::1]:9200') end end context 'when the port is specified as a String' do let(:host) do { host: 'myhost', scheme: 'https', port: '443' } end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:scheme]).to eq('https') end it 'converts the port to an integer' do expect(hosts[0][:port]).to be(443) end end context 'when the port is specified as an Integer' do let(:host) do { host: 'myhost', scheme: 'https', port: 443 } end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:scheme]).to eq('https') end it 'extracts port as an integer' do expect(hosts[0][:port]).to be(443) end end end context 'when the hosts are a Hashie:Mash' do let(:host) do Hashie::Mash.new(host: 'myhost', scheme: 'https') end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:scheme]).to eq('https') end it 'converts the port to an integer' do expect(hosts[0][:port]).to be(9200) end context 'when the port is specified as a String' do let(:host) do Hashie::Mash.new(host: 'myhost', scheme: 'https', port: '443') end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:scheme]).to eq('https') end it 'converts the port to an integer' do expect(hosts[0][:port]).to be(443) end end context 'when the port is specified as an Integer' do let(:host) do Hashie::Mash.new(host: 'myhost', scheme: 'https', port: 443) end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:scheme]).to eq('https') end it 'extracts port as an integer' do expect(hosts[0][:port]).to be(443) end end end context 'when the hosts are an array' do context 'when there is one host' do let(:host) do ['myhost'] end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:protocol]).to eq('http') end it 'defaults to port 9200' do expect(hosts[0][:port]).to be(9200) end end context 'when there is one host with a protocol and no port' do let(:host) do ['http://myhost'] end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:scheme]).to eq('http') end it 'defaults to port 9200' do expect(hosts[0][:port]).to be(9200) end end context 'when there is one host with a protocol and the default http port explicitly provided' do let(:host) do ['http://myhost:80'] end it 'respects the explicit port' do expect(hosts[0][:port]).to be(80) end end context 'when there is one host with a protocol and the default https port explicitly provided' do let(:host) do ['https://myhost:443'] end it 'respects the explicit port' do expect(hosts[0][:port]).to be(443) end end context 'when there is one host with a protocol and no port' do let(:host) do ['https://myhost'] end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:scheme]).to eq('https') end it 'defaults to port 443' do expect(hosts[0][:port]).to be(443) end end context 'when there is one host with a protocol, path, and no port' do let(:host) do ['http://myhost/foo/bar'] end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') end it 'extracts the protocol' do expect(hosts[0][:scheme]).to eq('http') end it 'defaults to port 9200' do expect(hosts[0][:port]).to be(9200) end it 'extracts the path' do expect(hosts[0][:path]).to eq('/foo/bar') end end context 'when there is more than one host' do let(:host) do ['host1', 'host2'] end it 'extracts the hosts' do expect(hosts[0][:host]).to eq('host1') expect(hosts[0][:protocol]).to eq('http') expect(hosts[0][:port]).to be(9200) expect(hosts[1][:host]).to eq('host2') expect(hosts[1][:protocol]).to eq('http') expect(hosts[1][:port]).to be(9200) end end context 'when ports are also specified' do let(:host) do ['host1:1000', 'host2:2000'] end it 'extracts the hosts' do expect(hosts[0][:host]).to eq('host1') expect(hosts[0][:protocol]).to eq('http') expect(hosts[0][:port]).to be(1000) expect(hosts[1][:host]).to eq('host2') expect(hosts[1][:protocol]).to eq('http') expect(hosts[1][:port]).to be(2000) end end end context 'when the hosts is an instance of URI' do let(:host) do URI.parse('https://USERNAME:PASSWORD@myhost:4430') end it 'extracts the host' do expect(hosts[0][:host]).to eq('myhost') expect(hosts[0][:scheme]).to eq('https') expect(hosts[0][:port]).to be(4430) expect(hosts[0][:user]).to eq('USERNAME') expect(hosts[0][:password]).to eq('PASSWORD') end end context 'when the hosts is invalid' do let(:host) do 123 end it 'extracts the host' do expect { hosts }.to raise_exception(ArgumentError) end end end context 'when hosts are specified with the \'host\' key' do let(:client) do described_class.new(host: ['host1', 'host2', 'host3', 'host4'], randomize_hosts: true) end let(:hosts) do client.transport.hosts end it 'sets the hosts in random order' do expect(hosts.all? { |host| client.transport.hosts.include?(host) }).to be(true) end end context 'when hosts are specified with the \'host\' key as a String' do let(:client) do described_class.new('host' => ['host1', 'host2', 'host3', 'host4'], 'randomize_hosts' => true) end let(:hosts) do client.transport.hosts end it 'sets the hosts in random order' do expect(hosts.all? { |host| client.transport.hosts.include?(host) }).to be(true) end end context 'when hosts are specified with the \'hosts\' key' do let(:client) do described_class.new(hosts: host) end let(:hosts) do client.transport.hosts end it_behaves_like 'a client that extracts hosts' end context 'when hosts are specified with the \'hosts\' key as a String' do let(:client) do described_class.new('hosts' => host) end let(:hosts) do client.transport.hosts end it_behaves_like 'a client that extracts hosts' end context 'when hosts are specified with the \'url\' key' do let(:client) do described_class.new(url: host) end let(:hosts) do client.transport.hosts end it_behaves_like 'a client that extracts hosts' end context 'when hosts are specified with the \'url\' key as a String' do let(:client) do described_class.new('url' => host) end let(:hosts) do client.transport.hosts end it_behaves_like 'a client that extracts hosts' end context 'when hosts are specified with the \'urls\' key' do let(:client) do described_class.new(urls: host) end let(:hosts) do client.transport.hosts end it_behaves_like 'a client that extracts hosts' end context 'when hosts are specified with the \'urls\' key as a String' do let(:client) do described_class.new('urls' => host) end let(:hosts) do client.transport.hosts end it_behaves_like 'a client that extracts hosts' end context 'when the URL is set in the ELASTICSEARCH_URL environment variable' do context 'when there is only one host specified' do around do |example| before_url = ENV['ELASTICSEARCH_URL'] ENV['ELASTICSEARCH_URL'] = 'example.com' example.run ENV['ELASTICSEARCH_URL'] = before_url end it 'sets the host' do expect(client.transport.hosts[0][:host]).to eq('example.com') expect(client.transport.hosts.size).to eq(1) end end context 'when mutliple hosts are specified as a comma-separated String list' do around do |example| before_url = ENV['ELASTICSEARCH_URL'] ENV['ELASTICSEARCH_URL'] = 'example.com, other.com' example.run ENV['ELASTICSEARCH_URL'] = before_url end it 'sets the hosts' do expect(client.transport.hosts[0][:host]).to eq('example.com') expect(client.transport.hosts[1][:host]).to eq('other.com') expect(client.transport.hosts.size).to eq(2) end end end context 'when options are defined' do context 'when scheme is specified' do let(:client) do described_class.new(scheme: 'https') end it 'sets the scheme' do expect(client.transport.connections[0].full_url('')).to match(/https/) end end context 'when scheme is specified as a String key' do let(:client) do described_class.new('scheme' => 'https') end it 'sets the scheme' do expect(client.transport.connections[0].full_url('')).to match(/https/) end end context 'when user and password are specified' do let(:client) do described_class.new(user: 'USERNAME', password: 'PASSWORD') end it 'sets the user and password' do expect(client.transport.connections[0].full_url('')).to match(/USERNAME/) expect(client.transport.connections[0].full_url('')).to match(/PASSWORD/) end context 'when the connections are reloaded' do before do allow(client.transport.sniffer).to receive(:hosts).and_return([{ host: 'foobar', port: 4567, id: 'foobar4567' }]) client.transport.reload_connections! end it 'sets keeps user and password' do expect(client.transport.connections[0].full_url('')).to match(/USERNAME/) expect(client.transport.connections[0].full_url('')).to match(/PASSWORD/) expect(client.transport.connections[0].full_url('')).to match(/foobar/) end end end context 'when user and password are specified as String keys' do let(:client) do described_class.new('user' => 'USERNAME', 'password' => 'PASSWORD') end it 'sets the user and password' do expect(client.transport.connections[0].full_url('')).to match(/USERNAME/) expect(client.transport.connections[0].full_url('')).to match(/PASSWORD/) end context 'when the connections are reloaded' do before do allow(client.transport.sniffer).to receive(:hosts).and_return([{ host: 'foobar', port: 4567, id: 'foobar4567' }]) client.transport.reload_connections! end it 'sets keeps user and password' do expect(client.transport.connections[0].full_url('')).to match(/USERNAME/) expect(client.transport.connections[0].full_url('')).to match(/PASSWORD/) expect(client.transport.connections[0].full_url('')).to match(/foobar/) end end end context 'when port is specified' do let(:client) do described_class.new(host: 'node1', port: 1234) end it 'sets the port' do expect(client.transport.connections[0].full_url('')).to match(/1234/) end end context 'when the log option is true' do let(:client) do described_class.new(log: true) end it 'has a default logger for transport' do expect(client.transport.logger.info).to eq(described_class::DEFAULT_LOGGER.call.info) end end context 'when the trace option is true' do let(:client) do described_class.new(trace: true) end it 'has a default logger for transport' do expect(client.transport.tracer.info).to eq(described_class::DEFAULT_TRACER.call.info) end end context 'when a custom transport class is specified' do let(:transport_class) do Class.new { def initialize(*); end } end let(:client) do described_class.new(transport_class: transport_class) end it 'allows the custom transport class to be defined' do expect(client.transport).to be_a(transport_class) end end context 'when a custom transport instance is specified' do let(:transport_instance) do Class.new { def initialize(*); end }.new end let(:client) do described_class.new(transport: transport_instance) end it 'allows the custom transport class to be defined' do expect(client.transport).to be(transport_instance) end end context 'when \'transport_options\' are defined' do let(:client) do described_class.new(transport_options: { request: { timeout: 1 } }) end it 'sets the options on the transport' do expect(client.transport.options[:transport_options][:request]).to eq(timeout: 1) end end context 'when \'request_timeout\' is defined' do let(:client) do described_class.new(request_timeout: 120) end it 'sets the options on the transport' do expect(client.transport.options[:transport_options][:request]).to eq(timeout: 120) end end context 'when \'request_timeout\' is defined as a String key' do let(:client) do described_class.new('request_timeout' => 120) end it 'sets the options on the transport' do expect(client.transport.options[:transport_options][:request]).to eq(timeout: 120) end end end describe '#perform_request' do let(:transport_instance) do Class.new { def initialize(*); end }.new end let(:client) do described_class.new(transport: transport_instance) end it 'delegates performing requests to the transport' do expect(transport_instance).to receive(:perform_request).and_return(true) expect(client.perform_request('GET', '/')).to be(true) end context 'when the \'send_get_body_as\' option is specified' do let(:client) do described_class.new(transport: transport_instance, :send_get_body_as => 'POST') end before do expect(transport_instance).to receive(:perform_request).with('POST', '/', {}, '{"foo":"bar"}', '{"Content-Type":"application/x-ndjson"}').and_return(true) end let(:request) do client.perform_request('POST', '/', {}, '{"foo":"bar"}', '{"Content-Type":"application/x-ndjson"}') end it 'sets the option' do expect(request).to be(true) end end context 'when x-opaque-id is set' do let(:client) { described_class.new(host: hosts) } it 'uses x-opaque-id on a request' do expect(client.perform_request('GET', '/', { opaque_id: '12345' }).headers['x-opaque-id']).to eq('12345') end end context 'when an x-opaque-id prefix is set on initialization' do let(:prefix) { 'elastic_cloud' } let(:client) do described_class.new(host: hosts, opaque_id_prefix: prefix) end it 'uses x-opaque-id on a request' do expect(client.perform_request('GET', '/', { opaque_id: '12345' }).headers['x-opaque-id']).to eq("#{prefix}12345") end context 'when using an API call' do let(:client) { described_class.new(host: hosts) } it 'doesnae raise an ArgumentError' do expect { client.perform_request('GET', '_search', opaque_id: 'no_error') }.not_to raise_error end it 'uses X-Opaque-Id in the header' do allow(client).to receive(:perform_request) { OpenStruct.new(body: '') } expect { client.perform_request('GET', '_search', {}, nil, opaque_id: 'opaque_id') }.not_to raise_error expect(client).to have_received(:perform_request) .with('GET', '_search', {}, nil, { opaque_id: 'opaque_id' }) end end end context 'when using the API Compatibility Header' do it 'sets the API compatibility headers' do ENV['ELASTIC_CLIENT_APIVERSIONING'] = 'true' client = described_class.new(host: hosts) headers = client.transport.connections.first.connection.headers expect(headers['Content-Type']).to eq('application/vnd.elasticsearch+json; compatible-with=7') expect(headers['Accept']).to eq('application/vnd.elasticsearch+json; compatible-with=7') ENV.delete('ELASTIC_CLIENT_APIVERSIONING') end it 'does not use API compatibility headers' do val = ENV.delete('ELASTIC_CLIENT_APIVERSIONING') client = described_class.new(host: hosts) expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('application/json') ENV['ELASTIC_CLIENT_APIVERSIONING'] = val end it 'does not use API compatibility headers when it is set to unsupported values' do val = ENV.delete('ELASTIC_CLIENT_APIVERSIONING') ENV['ELASTIC_CLIENT_APIVERSIONING'] = 'test' client = described_class.new(host: hosts) expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('application/json') ENV['ELASTIC_CLIENT_APIVERSIONING'] = 'false' client = described_class.new(host: hosts) expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('application/json') ENV['ELASTIC_CLIENT_APIVERSIONING'] = '3' client = described_class.new(host: hosts) expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('application/json') ENV['ELASTIC_CLIENT_APIVERSIONING'] = val end end context 'when Elasticsearch response includes a warning header' do let(:logger) { double('logger', warn: '', warn?: '', info?: '', info: '', debug?: '', debug: '') } let(:client) do Elasticsearch::Transport::Client.new(hosts: hosts, logger: logger) end let(:warning) { 'Elasticsearch warning: "deprecation warning"' } it 'prints a warning' do expect_any_instance_of(Faraday::Connection).to receive(:run_request) do Elasticsearch::Transport::Transport::Response.new(200, {}, { 'warning' => warning }) end client.perform_request('GET', '/') expect(logger).to have_received(:warn).with(warning) end end context 'when a header is set on an endpoint request' do let(:client) { described_class.new(host: hosts) } let(:headers) { { 'user-agent' => 'my ruby app' } } it 'performs the request with the header' do allow(client).to receive(:perform_request) { OpenStruct.new(body: '') } expect { client.perform_request('GET', '_search', {}, nil, headers) }.not_to raise_error expect(client).to have_received(:perform_request) .with('GET', '_search', {}, nil, headers) end end context 'when a header is set on an endpoint request and on initialization' do let!(:client) do described_class.new( host: hosts, transport_options: { headers: instance_headers } ) end let(:instance_headers) { { set_in_instantiation: 'header value' } } let(:param_headers) { {'user-agent' => 'My Ruby Tests', 'set-on-method-call' => 'header value'} } it 'performs the request with the header' do expected_headers = client.transport.connections.connections.first.connection.headers.merge(param_headers) expect_any_instance_of(Faraday::Connection) .to receive(:run_request) .with(:get, "http://#{hosts[0]}/_search", nil, expected_headers) { OpenStruct.new(body: '')} client.perform_request('GET', '_search', {}, nil, param_headers) end end end context 'when the client connects to Elasticsearch' do let(:logger) do Logger.new(STDERR).tap do |logger| logger.formatter = proc do |severity, datetime, progname, msg| color = case severity when /INFO/ then :green when /ERROR|WARN|FATAL/ then :red when /DEBUG/ then :cyan else :white end ANSI.ansi(severity[0] + ' ', color, :faint) + ANSI.ansi(msg, :white, :faint) + "\n" end end unless ENV['QUIET'] end let(:port) do TEST_PORT end let(:transport_options) do {} end let(:options) do {} end let(:client) do described_class.new({ host: hosts, logger: logger }.merge!(transport_options: transport_options).merge!(options)) end context 'when a request is made' do let!(:response) do client.perform_request('GET', '_cluster/health') end it 'connects to the cluster' do expect(response.body['number_of_nodes']).to be >= (1) end end describe '#initialize' do context 'when options are specified' do let(:transport_options) do { headers: { accept: 'application/yaml', content_type: 'application/yaml' } } end let(:response) do client.perform_request('GET', '_cluster/health') end it 'applies the options to the client' do expect(response.body).to match(/---\n/) expect(response.headers['content-type']).to eq('application/yaml') end end context 'when a block is provided' do let(:client) do described_class.new(host: ELASTICSEARCH_HOSTS.first, logger: logger) do |client| client.headers['Accept'] = 'application/yaml' end end let(:response) do client.perform_request('GET', '_cluster/health') end it 'executes the block' do expect(response.body).to match(/---\n/) expect(response.headers['content-type']).to eq('application/yaml') end context 'when the Faraday adapter is set in the block' do require 'faraday/net_http_persistent' if is_faraday_v2? let(:client) do described_class.new(host: ELASTICSEARCH_HOSTS.first, logger: logger) do |client| client.adapter(:net_http_persistent) end end let(:handler_name) do client.transport.connections.first.connection.builder.adapter.name end let(:response) do client.perform_request('GET', '_cluster/health') end it 'sets the adapter' do expect(handler_name).to eq('Faraday::Adapter::NetHttpPersistent') end it 'uses the adapter to connect' do expect(response.status).to eq(200) end end end end describe '#options' do context 'when retry_on_failure is true' do context 'when a node is unreachable' do let(:hosts) do [ELASTICSEARCH_HOSTS.first, "foobar1", "foobar2"] end let(:options) do { retry_on_failure: true } end let(:responses) do 5.times.collect do client.perform_request('GET', '_nodes/_local') end end it 'retries on failure' do expect(responses.all? { true }).to be(true) end end end context 'when retry_on_failure is an integer' do let(:hosts) do [ELASTICSEARCH_HOSTS.first, 'foobar1', 'foobar2', 'foobar3'] end let(:options) do { retry_on_failure: 1 } end it 'retries only the specified number of times' do expect(client.perform_request('GET', '_nodes/_local')) expect { client.perform_request('GET', '_nodes/_local') }.to raise_exception(Faraday::ConnectionFailed) end end context 'when retry_on_failure is true and delay_on_retry is specified' do context 'when a node is unreachable' do let(:hosts) do [ELASTICSEARCH_HOSTS.first, "foobar1", "foobar2"] end let(:options) do { retry_on_failure: true, delay_on_retry: 3000 } end let(:responses) do 5.times.collect do client.perform_request('GET', '_nodes/_local') end end it 'retries on failure' do allow_any_instance_of(Object).to receive(:sleep).with(3000 / 1000) expect(responses.all? { true }).to be(true) end end end context 'when reload_on_failure is true' do let(:hosts) do [ELASTICSEARCH_HOSTS.first, 'foobar1', 'foobar2'] end let(:options) do { reload_on_failure: true } end let(:responses) do 5.times.collect do client.perform_request('GET', '_nodes/_local') end end it 'reloads the connections' do expect(client.transport.connections.size).to eq(3) expect(responses.all? { true }).to be(true) expect(client.transport.connections.size).to be >= (1) end end context 'when retry_on_status is specified' do let(:options) do { retry_on_status: 400 } end let(:logger) do double('logger', :debug? => false, :warn? => true, :fatal? => false, :error? => false) end before do expect(logger).to receive(:warn).exactly(4).times end it 'retries when the status matches' do expect { client.perform_request('PUT', '_foobar') }.to raise_exception(Elasticsearch::Transport::Transport::Errors::BadRequest) end end context 'when the \'compression\' option is set to true' do context 'when using Faraday as the transport' do context 'when using the Net::HTTP adapter' do let(:client) do described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :net_http) end it 'compresses the request and decompresses the response' do expect(client.perform_request('GET', '/').body).to be_a(Hash) end it 'sets the Accept-Encoding header' do expect(client.transport.connections[0].connection.headers['Accept-Encoding']).to eq 'gzip' end it 'preserves the other headers' do expect(client.transport.connections[0].connection.headers['User-Agent']) end end context 'when using the HTTPClient adapter' do require 'faraday/httpclient' let(:client) do described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :httpclient, enable_meta_header: false) end it 'compresses the request and decompresses the response' do expect(client.perform_request('GET', '/').body).to be_a(Hash) end it 'sets the Accept-Encoding header' do expect(client.transport.connections[0].connection.headers['Accept-Encoding']).to eq 'gzip' end it 'preserves the other headers' do expect(client.transport.connections[0].connection.headers['User-Agent']) end end context 'when using the Patron adapter', unless: jruby? do let(:client) do described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :patron) end it 'compresses the request and decompresses the response' do expect(client.perform_request('GET', '/').body).to be_a(Hash) end it 'sets the Accept-Encoding header' do expect(client.transport.connections[0].connection.headers['Accept-Encoding']).to eq 'gzip' end it 'preserves the other headers' do expect(client.transport.connections[0].connection.headers['User-Agent']) end end context 'when using the Net::HTTP::Persistent adapter' do let(:client) do described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :net_http_persistent) end it 'compresses the request and decompresses the response' do expect(client.perform_request('GET', '/').body).to be_a(Hash) end it 'sets the Accept-Encoding header' do expect(client.transport.connections[0].connection.headers['Accept-Encoding']).to eq 'gzip' end it 'preserves the other headers' do expect(client.transport.connections[0].connection.headers['User-Agent']) end end context 'when using the Typhoeus adapter' do let(:client) do described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :typhoeus) end it 'compresses the request and decompresses the response' do expect(client.perform_request('GET', '/').body).to be_a(Hash) end it 'sets the Accept-Encoding header' do expect(client.transport.connections[0].connection.headers['Accept-Encoding']).to eq 'gzip' end it 'preserves the other headers' do expect(client.transport.connections[0].connection.headers['User-Agent']) end end unless jruby? end end context 'when using Curb as the transport', unless: jruby? do let(:client) do described_class.new( hosts: ELASTICSEARCH_HOSTS, compression: true, transport_class: Elasticsearch::Transport::Transport::HTTP::Curb ) end it 'compresses the request and decompresses the response' do expect(client.perform_request('GET', '/').body).to be_a(Hash) end it 'sets the Accept-Encoding header' do expect(client.transport.connections[0].connection.headers['Accept-Encoding']).to eq 'gzip' end it 'preserves the other headers' do expect(client.transport.connections[0].connection.headers['User-Agent']) end end context 'when using Manticore as the transport', if: jruby? do let(:client) do described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, transport_class: Elasticsearch::Transport::Transport::HTTP::Manticore) end it 'compresses the request and decompresses the response' do expect(client.perform_request('GET', '/').body).to be_a(Hash) end end end describe '#perform_request' do context 'when a request is made' do before do client.perform_request('DELETE', '_all') client.perform_request('DELETE', 'myindex') rescue client.perform_request('PUT', 'myindex', {}, { settings: { number_of_shards: 2, number_of_replicas: 0 } }) client.perform_request('PUT', 'myindex/mydoc/1', { routing: 'XYZ', timeout: '1s' }, { foo: 'bar' }) client.perform_request('GET', '_cluster/health?wait_for_status=green&timeout=2s', {}) end let(:response) do client.perform_request('GET', 'myindex/mydoc/1?routing=XYZ') end it 'handles paths and URL paramters' do expect(response.status).to eq(200) end it 'returns response body' do expect(response.body['_source']).to eq('foo' => 'bar') end end context 'when an invalid url is specified' do it 'raises an exception' do expect { client.perform_request('GET', 'myindex/mydoc/1?routing=FOOBARBAZ') }.to raise_exception(Elasticsearch::Transport::Transport::Errors::NotFound) end end context 'when the \'ignore\' parameter is specified' do let(:response) do client.perform_request('PUT', '_foobar', ignore: 400) end it 'exposes the status in the response' do expect(response.status).to eq(400) end it 'exposes the body of the response' do expect(response.body).to be_a(Hash) expect(response.body.inspect).to match(/invalid_index_name_exception/) end end context 'when request headers are specified' do let(:response) do client.perform_request('GET', '/', {}, nil, { 'Content-Type' => 'application/yaml' }) end it 'passes them to the transport' do expect(response.body).to match(/---/) end end describe 'selector' do context 'when the round-robin selector is used' do let(:nodes) do 3.times.collect do client.perform_request('GET', '_nodes/_local').body['nodes'].to_a[0][1]['name'] end end let(:node_names) do client.perform_request('GET', '_nodes/stats').body('nodes').collect do |name, stats| stats['name'] end end let(:expected_names) do 3.times.collect do |i| node_names[i % node_names.size] end end # it 'rotates nodes' do # pending 'Better way to detect rotating nodes' # expect(nodes).to eq(expected_names) # end end end context 'when patron is used as an adapter', unless: jruby? do before do require 'patron' end let(:options) do { adapter: :patron } end let(:adapter) do client.transport.connections.first.connection.builder.adapter end it 'uses the patron connection handler' do expect(adapter).to eq('Faraday::Adapter::Patron') end it 'keeps connections open' do response = client.perform_request('GET', '_nodes/stats/http') connections_before = response.body['nodes'].values.find { |n| n['name'] == node_names.first }['http']['total_opened'] client.transport.reload_connections! response = client.perform_request('GET', '_nodes/stats/http') connections_after = response.body['nodes'].values.find { |n| n['name'] == node_names.first }['http']['total_opened'] expect(connections_after).to be >= (connections_before) end end context 'when typhoeus is used as an adapter', unless: jruby? do before do require 'typhoeus' end let(:options) do { adapter: :typhoeus } end let(:adapter) do client.transport.connections.first.connection.builder.adapter end it 'uses the patron connection handler' do expect(adapter).to eq('Faraday::Adapter::Typhoeus') end it 'keeps connections open' do response = client.perform_request('GET', '_nodes/stats/http') connections_before = response.body['nodes'].values.find { |n| n['name'] == node_names.first }['http']['total_opened'] client.transport.reload_connections! response = client.perform_request('GET', '_nodes/stats/http') connections_after = response.body['nodes'].values.find { |n| n['name'] == node_names.first }['http']['total_opened'] expect(connections_after).to be >= (connections_before) end end end end context 'CA Fingerprinting' do context 'when setting a ca_fingerprint' do after do File.delete('./certificate.crt') File.delete('./certificate.key') end let(:certificate) do system( 'openssl req -new -newkey rsa:4096 -days 3650 -nodes -x509 -subj "/C=BE/O=Test/CN=Test"' \ ' -keyout certificate.key -out certificate.crt', err: File::NULL ) OpenSSL::X509::Certificate.new File.read('./certificate.crt') end let(:client) do Elasticsearch::Transport::Client.new( host: 'https://elastic:changeme@localhost:9200', ca_fingerprint: OpenSSL::Digest::SHA256.hexdigest(certificate.to_der) ) end it 'validates CA fingerprints on perform request' do expect(client.transport.connections.connections.map(&:verified).uniq).to eq [false] allow(client.transport).to receive(:perform_request) { 'Hello' } server = double('server').as_null_object allow(TCPSocket).to receive(:new) { server } socket = double('socket') allow(OpenSSL::SSL::SSLSocket).to receive(:new) { socket } allow(socket).to receive(:connect) { nil } allow(socket).to receive(:peer_cert_chain) { [certificate] } response = client.perform_request('GET', '/') expect(client.transport.connections.connections.map(&:verified).uniq).to eq [true] expect(response).to eq 'Hello' end end context 'when using an http host' do let(:client) do Elasticsearch::Transport::Client.new( host: 'http://elastic:changeme@localhost:9200', ca_fingerprint: 'test' ) end it 'raises an error' do expect do client.perform_request('GET', '/') end.to raise_exception(Elasticsearch::Transport::Transport::Error) end end context 'when not setting a ca_fingerprint' do let(:client) do Elasticsearch::Transport::Client.new( host: 'http://elastic:changeme@localhost:9200' ) end it 'has unvalidated connections' do allow(client).to receive(:validate_ca_fingerprints) { nil } allow(client.transport).to receive(:perform_request) { nil } client.perform_request('GET', '/') expect(client).to_not have_received(:validate_ca_fingerprints) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/elasticsearch/transport/http/000077500000000000000000000000001462737751600330635ustar00rootroot00000000000000curb_spec.rb000066400000000000000000000101631462737751600352770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/elasticsearch/transport/http# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. unless defined?(JRUBY_VERSION) require_relative '../../../spec_helper' describe Elasticsearch::Transport::Transport::HTTP::Curb do let(:client) do Elasticsearch::Transport::Client.new(transport_class: described_class) end describe '#perform_request' do subject(:perform_request) { client.perform_request(*args) } let(:args) do ['POST', '/', {}, body, headers] end let(:body) { '{"foo":"bar"}' } let(:headers) { { 'Content-Type' => 'application/x-ndjson' } } before do allow_any_instance_of(Curl::Easy).to receive(:http).and_return(true) end it 'convert body to json' do expect(client.transport).to receive(:__convert_to_json).with(body) perform_request end it 'call compress_request' do expect(client.transport).to receive(:compress_request).with(body, headers) perform_request end it 'return response' do expect(perform_request).to be_kind_of(Elasticsearch::Transport::Transport::Response) end it 'put body' do expect(client.transport.connections.first.connection).to receive('put_data=').with(body) perform_request end context 'when body nil' do let(:body) { nil } it 'convert body to json' do expect(client.transport).not_to receive(:__convert_to_json) perform_request end it 'call compress_request' do expect(client.transport).to receive(:compress_request).with(body, headers) perform_request end it 'put body' do expect(client.transport.connections.first.connection).not_to receive('put_data=') perform_request end end context 'when body is hash' do let(:body) { { foo: 'bar' } } let(:body_string) { '{"foo":"bar"}' } it 'convert body to json' do expect(client.transport).to receive(:__convert_to_json).with(body) perform_request end it 'call compress_request' do expect(client.transport).to receive(:compress_request).with(body_string, headers) perform_request end it 'put body' do expect(client.transport.connections.first.connection).to receive('put_data=').with(body_string) perform_request end end context 'when compression enabled' do let(:client) do Elasticsearch::Transport::Client.new(transport_class: described_class, compression: true) end let(:body_string) { '{"foo":"bar"}' } let(:compressed_body) do gzip = Zlib::GzipWriter.new(StringIO.new) gzip << body_string gzip.close.string end before { allow(client.transport).to receive(:decompress_response).and_return('') } it 'put compressed body' do expect(client.transport.connections.first.connection).to receive('put_data=').with(compressed_body) perform_request end it 'set Content-Encoding header' do perform_request expect(client.transport.connections.first.connection.headers).to include('Content-Encoding') end it 'set Content-Encoding to gzip' do perform_request expect(client.transport.connections.first.connection.headers['Content-Encoding']).to eql('gzip') end end end end end faraday_spec.rb000066400000000000000000000116511462737751600357560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/elasticsearch/transport/http# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require_relative '../../../spec_helper' describe Elasticsearch::Transport::Transport::HTTP::Faraday do let(:client) do Elasticsearch::Transport::Client.new(transport_class: described_class) end describe '#perform_request' do subject(:perform_request) { client.perform_request(*args) } let(:args) do ['POST', '/', {}, body, headers] end let(:body) { '{"foo":"bar"}' } let(:headers) { { 'Content-Type' => 'application/x-ndjson' } } let(:response) { instance_double('Faraday::Response', status: 200, body: '', headers: headers) } let(:expected_headers) do client.transport.connections.first.connection.headers.merge(headers) end before do allow_any_instance_of(Faraday::Connection).to receive(:run_request).and_return(response) end it 'convert body to json' do expect(client.transport).to receive(:__convert_to_json).with(body) perform_request end it 'call compress_request' do expect(client.transport).to receive(:compress_request).with(body, expected_headers) perform_request end it 'return response' do expect(perform_request).to be_kind_of(Elasticsearch::Transport::Transport::Response) end it 'run body with preper params' do expect( client.transport.connections.first.connection ).to receive(:run_request).with(:post, 'http://localhost:9200/', body, expected_headers).and_return(response) perform_request end context 'when body nil' do let(:body) { nil } let(:request_params) { [:post, 'http://localhost:9200/', body, expected_headers] } it 'convert body to json' do expect(client.transport).not_to receive(:__convert_to_json) perform_request end it 'call compress_request' do expect(client.transport).to receive(:compress_request).with(body, expected_headers) perform_request end it 'run body with preper params' do expect( client.transport.connections.first.connection ).to receive(:run_request).with(*request_params).and_return(response) perform_request end end context 'when body is hash' do let(:body) { { foo: 'bar' } } let(:body_string) { '{"foo":"bar"}' } let(:request_params) { [:post, 'http://localhost:9200/', body_string, expected_headers] } it 'convert body to json' do expect(client.transport).to receive(:__convert_to_json).with(body) perform_request end it 'call compress_request' do expect(client.transport).to receive(:compress_request).with(body_string, expected_headers) perform_request end it 'run body with preper params' do expect( client.transport.connections.first.connection ).to receive(:run_request).with(*request_params).and_return(response) perform_request end end context 'when compression enabled' do let(:client) do Elasticsearch::Transport::Client.new(transport_class: described_class, compression: true) end let(:body_string) { '{"foo":"bar"}' } let(:expected_headers) { super().merge({ "Content-Encoding" => "gzip", "Accept-Encoding" => "gzip"}) } let(:request_params) { [:post, 'http://localhost:9200/', compressed_body, expected_headers] } let(:compressed_body) do gzip = Zlib::GzipWriter.new(StringIO.new) gzip << body_string gzip.close.string end it 'run body with preper params' do expect( client.transport.connections.first.connection ).to receive(:run_request).with(*request_params).and_return(response) perform_request end context 'when client makes second request with nil boby' do before { perform_request } it 'remove Content-Encoding header' do expected_headers.delete("Content-Encoding") expect( client.transport.connections.first.connection ).to receive(:run_request).with(:post, 'http://localhost:9200/', nil, expected_headers) .and_return(response) client.perform_request('POST', '/', {}, nil, headers) end end end end end manticore_spec.rb000066400000000000000000000135701462737751600363320ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/elasticsearch/transport/http# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. if defined?(JRUBY_VERSION) require_relative '../../../spec_helper' describe Elasticsearch::Transport::Transport::HTTP::Manticore do let(:client) do Elasticsearch::Transport::Client.new(transport_class: described_class) end describe '#perform_request' do subject(:perform_request) { client.perform_request(*args) } let(:args) do ['POST', '/', {}, body, headers] end let(:body) { '{"foo":"bar"}' } let(:headers) { { 'Content-Type' => 'application/json' } } let(:response) { instance_double('Manticore::Response', code: 200, read_body: '', headers: headers) } let(:expected_headers) do client.transport.instance_variable_get('@request_options')[:headers].merge(headers) end before do allow_any_instance_of(Manticore::Client).to receive(:post).and_return(response) end it 'convert body to json' do expect(client.transport).to receive(:__convert_to_json).with(body) perform_request end it 'call compress_request' do expect(client.transport).to receive(:compress_request).with(body, expected_headers) perform_request end it 'return response' do expect(perform_request).to be_kind_of(Elasticsearch::Transport::Transport::Response) end it 'run body with proper params' do expect( client.transport.connections.first.connection ).to receive(:post).with('http://localhost:9200/', { body: body, headers: expected_headers }).and_return(response) perform_request end context 'when body nil' do let(:body) { nil } let(:request_params) { ['http://localhost:9200/', { body: body, headers: expected_headers }] } it 'convert body to json' do expect(client.transport).not_to receive(:__convert_to_json) perform_request end it 'call compress_request' do expect(client.transport).to receive(:compress_request).with(body, expected_headers) perform_request end it 'run body with preper params' do expect( client.transport.connections.first.connection ).to receive(:post).with('http://localhost:9200/', { headers: expected_headers }).and_return(response) perform_request end end context 'when body is hash' do let(:body) { { foo: 'bar' } } let(:body_string) { '{"foo":"bar"}' } let(:request_params) { ['http://localhost:9200/', { body: body_string, headers: expected_headers }] } it 'convert body to json' do expect(client.transport).to receive(:__convert_to_json).with(body) perform_request end it 'call compress_request' do expect(client.transport).to receive(:compress_request).with(body_string, expected_headers) perform_request end it 'run body with preper params' do expect( client.transport.connections.first.connection ).to receive(:post).with(*request_params).and_return(response) perform_request end end context 'when compression enabled' do let(:client) do Elasticsearch::Transport::Client.new(transport_class: described_class, compression: true) end let(:body_string) { '{"foo":"bar"}' } let(:expected_headers) { super().merge({ "Content-Encoding" => "gzip", "Accept-Encoding" => "gzip"}) } let(:request_params) { ['http://localhost:9200/', { body: compressed_body, headers: expected_headers }] } let(:compressed_body) do gzip = Zlib::GzipWriter.new(StringIO.new) gzip << body_string gzip.close.string end it 'run body with preper params' do expect( client.transport.connections.first.connection ).to receive(:post).with(*request_params).and_return(response) perform_request end context 'when client makes second request with nil boby' do before { perform_request } it 'remove Content-Encoding header' do expected_headers.delete("Content-Encoding") expect( client.transport.connections.first.connection ).to receive(:post).with('http://localhost:9200/', { headers: expected_headers }) .and_return(response) client.perform_request('POST', '/', {}, nil, headers) end end end context 'headers' do it 'sends custom headers' do client = Elasticsearch::Transport::Client.new( transport_class: described_class, transport_options: { headers: { 'Elastic-Api-Version'=>'2023-10-31' } } ) expect( client.transport.connections.first.connection ).to receive(:get).with( 'http://localhost:9200/', { headers: expected_headers.merge({ 'Elastic-Api-Version'=>'2023-10-31' }) } ).and_return(response) client.perform_request('GET', '/', {}, nil, headers) end end end end end meta_header_spec.rb000066400000000000000000000264341462737751600356330ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/elasticsearch/transport# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' require 'elasticsearch' describe Elasticsearch::Transport::Client do context 'meta-header' do let(:subject) { client.transport.connections.first.connection.headers } let(:client) { described_class.new } let(:regexp) { /^[a-z]{1,}=[a-z0-9.\-]{1,}(?:,[a-z]{1,}=[a-z0-9._\-]+)*$/ } let(:adapter) { :net_http } let(:adapter_code) { "nh=#{defined?(Net::HTTP::VERSION) ? Net::HTTP::VERSION : Net::HTTP::HTTPVersion}" } let(:meta_header) do if jruby? "es=#{meta_version},rb=#{RUBY_VERSION},t=#{Elasticsearch::Transport::VERSION},jv=#{ENV_JAVA['java.version']},jr=#{JRUBY_VERSION},fd=#{Faraday::VERSION},#{adapter_code}" else "es=#{meta_version},rb=#{RUBY_VERSION},t=#{Elasticsearch::Transport::VERSION},fd=#{Faraday::VERSION},#{adapter_code}" end end context 'client_meta_version' do let(:version) { ['7.1.0-alpha', '7.11.0.pre.1', '8.0.0-beta', '8.0.0.beta.2']} it 'converts the version to X.X.Xp' do expect(client.send(:client_meta_version, '7.0.0-alpha')).to eq('7.0.0p') expect(client.send(:client_meta_version, '7.11.0.pre.1')).to eq('7.11.0p') expect(client.send(:client_meta_version, '8.1.0-beta')).to eq('8.1.0p') expect(client.send(:client_meta_version, '8.0.0.beta.2')).to eq('8.0.0p') expect(client.send(:client_meta_version, '12.16.4.pre')).to eq('12.16.4p') end end # We are testing this method in the previous block, so now using it inside the test to make the # Elasticsearch version in the meta header string dynamic def meta_version client.send(:client_meta_version, Elasticsearch::VERSION) end context 'single use of meta header' do let(:client) do described_class.new(adapter: adapter).tap do |klient| allow(klient).to receive(:__build_connections) end end it 'x-elastic-client-header value matches regexp' do expect(subject['x-elastic-client-meta']).to match(regexp) expect(subject).to include('x-elastic-client-meta' => meta_header) end end context 'when using user-agent headers' do let(:client) do transport_options = { headers: { user_agent: 'My Ruby App' } } described_class.new(transport_options: transport_options, adapter: adapter).tap do |klient| allow(klient).to receive(:__build_connections) end end it 'is friendly to previously set headers' do expect(subject).to include(user_agent: 'My Ruby App') expect(subject['x-elastic-client-meta']).to match(regexp) expect(subject).to include('x-elastic-client-meta' => meta_header) end end context 'when using API Key' do let(:client) do described_class.new(api_key: 'an_api_key', adapter: adapter) end let(:authorization_header) do client.transport.connections.first.connection.headers['Authorization'] end it 'adds the ApiKey header to the connection' do expect(authorization_header).to eq('ApiKey an_api_key') expect(subject['x-elastic-client-meta']).to match(regexp) expect(subject).to include('x-elastic-client-meta' => meta_header) end end context 'adapters' do let(:meta_header) do if jruby? "es=#{meta_version},rb=#{RUBY_VERSION},t=#{Elasticsearch::Transport::VERSION},jv=#{ENV_JAVA['java.version']},jr=#{JRUBY_VERSION},fd=#{Faraday::VERSION}" else "es=#{meta_version},rb=#{RUBY_VERSION},t=#{Elasticsearch::Transport::VERSION},fd=#{Faraday::VERSION}" end end let(:client) { described_class.new(adapter: adapter) } let(:headers) { client.transport.connections.first.connection.headers } context 'using net/http/persistent' do let(:adapter) { :net_http_persistent } it 'sets adapter in the meta header version to 0 when not loaded' do was_required = defined?(Net::HTTP::Persistent) if was_required @klass = Net::HTTP::Persistent.clone Net::HTTP.send(:remove_const, :Persistent) end expect(headers['x-elastic-client-meta']).to match(regexp) meta = "#{meta_header},np=0" expect(headers).to include('x-elastic-client-meta' => meta) Net::HTTP::Persistent = @klass if was_required end unless jruby? it 'sets adapter in the meta header' do require 'net/http/persistent' expect(headers['x-elastic-client-meta']).to match(regexp) meta = "#{meta_header},np=#{Net::HTTP::Persistent::VERSION}" expect(headers).to include('x-elastic-client-meta' => meta) end end context 'using httpclient' do let(:adapter) { :httpclient } it 'sets adapter in the meta header version to 0 when not loaded' do was_required = defined?(HTTPClient) if was_required @klass = HTTPClient.clone Object.send(:remove_const, :HTTPClient) end expect(headers['x-elastic-client-meta']).to match(regexp) meta = "#{meta_header},hc=0" expect(headers).to include('x-elastic-client-meta' => meta) HTTPClient = @klass if was_required end unless jruby? it 'sets adapter in the meta header' do require 'httpclient' expect(headers['x-elastic-client-meta']).to match(regexp) meta = "#{meta_header},hc=#{HTTPClient::VERSION}" expect(headers).to include('x-elastic-client-meta' => meta) end end context 'using typhoeus' do let(:adapter) { :typhoeus } it 'sets adapter in the meta header version to 0 when not loaded' do was_required = defined?(Typhoeus) if was_required @klass = Typhoeus.clone Object.send(:remove_const, :Typhoeus) end expect(headers['x-elastic-client-meta']).to match(regexp) meta = "#{meta_header},ty=0" expect(headers).to include('x-elastic-client-meta' => meta) Typhoeus = @klass if was_required end it 'sets adapter in the meta header' do require 'typhoeus' expect(headers['x-elastic-client-meta']).to match(regexp) meta = "#{meta_header},ty=#{Typhoeus::VERSION}" expect(headers).to include('x-elastic-client-meta' => meta) end end unless jruby? unless jruby? let(:adapter) { :patron } context 'using patron without requiring it' do it 'sets adapter in the meta header version to 0 when not loaded' do was_required = defined?(Patron) if was_required @klass = Patron.clone Object.send(:remove_const, :Patron) end expect(headers['x-elastic-client-meta']).to match(regexp) meta = "#{meta_header},pt=0" expect(headers).to include('x-elastic-client-meta' => meta) Patron = @klass if was_required end end context 'using patron' do it 'sets adapter in the meta header' do require 'patron' expect(headers['x-elastic-client-meta']).to match(regexp) meta = "#{meta_header},pt=#{Patron::VERSION}" expect(headers).to include('x-elastic-client-meta' => meta) end end end context 'using other' do let(:adapter) { :some_other_adapter } it 'sets adapter in the meta header without requiring' do Faraday::Adapter.register_middleware some_other_adapter: Faraday::Adapter::NetHttpPersistent expect(headers['x-elastic-client-meta']).to match(regexp) expect(headers).to include('x-elastic-client-meta' => meta_header) end it 'sets adapter in the meta header' do require 'net/http/persistent' Faraday::Adapter.register_middleware some_other_adapter: Faraday::Adapter::NetHttpPersistent expect(headers['x-elastic-client-meta']).to match(regexp) expect(headers).to include('x-elastic-client-meta' => meta_header) end end end if defined?(JRUBY_VERSION) context 'when using manticore' do let(:client) do described_class.new(transport_class: Elasticsearch::Transport::Transport::HTTP::Manticore).tap do |client| client.instance_variable_set('@verified', true) end end let(:subject) { client.transport.connections.first.connection.instance_variable_get("@options")[:headers]} it 'sets manticore in the metaheader' do expect(subject['x-elastic-client-meta']).to match(regexp) expect(subject['x-elastic-client-meta']).to match(/mc=[0-9.]+/) end end else context 'when using curb' do let(:client) do described_class.new(transport_class: Elasticsearch::Transport::Transport::HTTP::Curb).tap do |client| client.instance_variable_set('@verified', true) end end it 'sets curb in the metaheader' do expect(subject['x-elastic-client-meta']).to match(regexp) expect(subject['x-elastic-client-meta']).to match(/cl=[0-9.]+/) end end end context 'when using custom transport implementation' do let(:transport_class) do Class.new do def initialize(args) end end end let(:client) { Elasticsearch::Transport::Client.new(transport_class: transport_class) } let(:subject) { client.instance_variable_get('@arguments')[:transport_options][:headers] } let(:meta_header) do if jruby? "es=#{meta_version},rb=#{RUBY_VERSION},t=#{Elasticsearch::Transport::VERSION},jv=#{ENV_JAVA['java.version']},jr=#{JRUBY_VERSION}" else "es=#{meta_version},rb=#{RUBY_VERSION},t=#{Elasticsearch::Transport::VERSION}" end end it 'doesnae set any info about the implementation in the metaheader' do expect(subject['x-elastic-client-meta']).to match(regexp) expect(subject).to include('x-elastic-client-meta' => meta_header) end end context 'when using a different service version' do before do stub_const('Elastic::ELASTICSEARCH_SERVICE_VERSION', [:ent, '8.0.0']) end let(:client) do described_class.new.tap do |client| client.instance_variable_set('@verified', true) end end it 'sets the service version in the metaheader' do expect(subject['x-elastic-client-meta']).to match(regexp) expect(subject['x-elastic-client-meta']).to start_with('ent=8.0.0') end end end end sniffer_spec.rb000066400000000000000000000162441462737751600350270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/elasticsearch/transport# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe Elasticsearch::Transport::Transport::Sniffer do let(:transport) do double('transport').tap do |t| allow(t).to receive(:perform_request).and_return(response) allow(t).to receive(:options).and_return(sniffer_timeout: 2) end end let(:sniffer) do described_class.new(transport) end let(:response) do double('response').tap do |r| allow(r).to receive(:body).and_return(raw_response) end end let(:raw_response) do { 'nodes' => { 'n1' => { 'http' => { 'publish_address' => publish_address } } } } end let(:publish_address) do '127.0.0.1:9250' end describe '#initialize' do it 'has a transport instance' do expect(sniffer.transport).to be(transport) end it 'inherits the sniffer timeout from the transport object' do expect(sniffer.timeout).to eq(2) end end describe '#timeout' do let(:sniffer) do described_class.new(double('transport', options: {})) end before do sniffer.timeout = 3 end it 'allows the timeout to be configured' do expect(sniffer.timeout).to eq(3) end end describe '#hosts' do let(:hosts) do sniffer.hosts end context 'when the entire response is parsed' do let(:raw_response) do { "cluster_name" => "elasticsearch_test", "nodes" => { "N1" => { "name" => "Node 1", "transport_address" => "127.0.0.1:9300", "host" => "testhost1", "ip" => "127.0.0.1", "version" => "7.0.0", "roles" => [ "master", "data", "ingest" ], "attributes" => { "testattr" => "test" }, "http" => { "bound_address" => [ "[fe80::1]:9250", "[::1]:9250", "127.0.0.1:9250" ], "publish_address" => "127.0.0.1:9250", "max_content_length_in_bytes" => 104857600 } } } } end it 'parses the id' do expect(sniffer.hosts[0][:id]).to eq('N1') end it 'parses the name' do expect(sniffer.hosts[0][:name]).to eq('Node 1') end it 'parses the version' do expect(sniffer.hosts[0][:version]).to eq('7.0.0') end it 'parses the host' do expect(sniffer.hosts[0][:host]).to eq('127.0.0.1') end it 'parses the port' do expect(sniffer.hosts[0][:port]).to eq('9250') end it 'parses the roles' do expect(sniffer.hosts[0][:roles]).to eq(['master', 'data', 'ingest']) end it 'parses the attributes' do expect(sniffer.hosts[0][:attributes]).to eq('testattr' => 'test') end end context 'when the transport protocol does not match' do let(:raw_response) do { 'nodes' => { 'n1' => { 'foo' => { 'publish_address' => '127.0.0.1:9250' } } } } end it 'does not parse the addresses' do expect(hosts).to eq([]) end end context 'when a list of nodes is returned' do let(:raw_response) do { 'nodes' => { 'n1' => { 'http' => { 'publish_address' => '127.0.0.1:9250' } }, 'n2' => { 'http' => { 'publish_address' => '127.0.0.1:9251' } } } } end it 'parses the response' do expect(hosts.size).to eq(2) end it 'correctly parses the hosts' do expect(hosts[0][:host]).to eq('127.0.0.1') expect(hosts[1][:host]).to eq('127.0.0.1') end it 'correctly parses the ports' do expect(hosts[0][:port]).to eq('9250') expect(hosts[1][:port]).to eq('9251') end end context 'when the host and port are an ip address and port' do it 'parses the response' do expect(hosts.size).to eq(1) end it 'correctly parses the host' do expect(hosts[0][:host]).to eq('127.0.0.1') end it 'correctly parses the port' do expect(hosts[0][:port]).to eq('9250') end end context 'when the host and port are a hostname and port' do let(:publish_address) do 'testhost1.com:9250' end let(:hosts) do sniffer.hosts end it 'parses the response' do expect(hosts.size).to eq(1) end it 'correctly parses the host' do expect(hosts[0][:host]).to eq('testhost1.com') end it 'correctly parses the port' do expect(hosts[0][:port]).to eq('9250') end end context 'when the host and port are in the format: hostname/ip:port' do let(:publish_address) do 'example.com/127.0.0.1:9250' end it 'parses the response' do expect(hosts.size).to eq(1) end it 'uses the hostname' do expect(hosts[0][:host]).to eq('example.com') end it 'correctly parses the port' do expect(hosts[0][:port]).to eq('9250') end context 'when the address is IPv6' do let(:publish_address) do 'example.com/[::1]:9250' end it 'parses the response' do expect(hosts.size).to eq(1) end it 'uses the hostname' do expect(hosts[0][:host]).to eq('example.com') end it 'correctly parses the port' do expect(hosts[0][:port]).to eq('9250') end end end context 'when the address is IPv6' do let(:publish_address) do '[::1]:9250' end it 'parses the response' do expect(hosts.size).to eq(1) end it 'correctly parses the host' do expect(hosts[0][:host]).to eq('::1') end it 'correctly parses the port' do expect(hosts[0][:port]).to eq('9250') end end context 'when the transport has :randomize_hosts option' do let(:raw_response) do { 'nodes' => { 'n1' => { 'http' => { 'publish_address' => '127.0.0.1:9250' } }, 'n2' => { 'http' => { 'publish_address' => '127.0.0.1:9251' } } } } end before do allow(transport).to receive(:options).and_return(randomize_hosts: true) end it 'shuffles the list' do expect(hosts.size).to eq(2) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/spec/spec_helper.rb000066400000000000000000000052071462737751600300600ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. if ENV['COVERAGE'] && ENV['CI'].nil? require 'simplecov' SimpleCov.start { add_filter %r{^/test|spec/} } end require 'elasticsearch-transport' require 'logger' require 'ansi/code' require 'hashie/mash' if defined?(JRUBY_VERSION) require 'elasticsearch/transport/transport/http/manticore' require 'pry-nav' else require 'pry-byebug' require 'elasticsearch/transport/transport/http/curb' require 'curb' end # The hosts to use for creating a elasticsearch client. # # @since 7.0.0 ELASTICSEARCH_HOSTS = if (hosts = ENV['TEST_ES_SERVER'] || ENV['ELASTICSEARCH_HOSTS']) hosts.split(',').map do |host| /(http\:\/\/)?(\S+)/.match(host)[2] end else ['localhost:9200'] end.freeze TEST_HOST, TEST_PORT = ELASTICSEARCH_HOSTS.first.split(':') if ELASTICSEARCH_HOSTS # Are we testing on JRuby? # # @return [ true, false ] Whether JRuby is being used. # # @since 7.0.0 def jruby? RUBY_PLATFORM =~ /\bjava\b/ end # The names of the connected nodes. # # @return [ Array ] The node names. # # @since 7.0.0 def node_names node_stats = default_client.perform_request('GET', '_nodes/stats').body $node_names ||= node_stats['nodes'].collect do |name, stats| stats['name'] end end # The default client. # # @return [ Elasticsearch::Client ] The default client. # # @since 7.0.0 def default_client $client ||= Elasticsearch::Client.new(hosts: ELASTICSEARCH_HOSTS) end def is_faraday_v2? Gem::Version.new(Faraday::VERSION) >= Gem::Version.new(2) end module Config def self.included(context) # Get the hosts to use to connect an elasticsearch client. # # @since 7.0.0 context.let(:hosts) { ELASTICSEARCH_HOSTS } end end RSpec.configure do |config| config.include(Config) config.formatter = 'documentation' config.color = true end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/000077500000000000000000000000001462737751600252635ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/integration/000077500000000000000000000000001462737751600276065ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/integration/jruby_test.rb000066400000000000000000000031201462737751600323210ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' if JRUBY require 'elasticsearch/transport/transport/http/manticore' class Elasticsearch::Transport::ClientManticoreIntegrationTest < Elasticsearch::Test::IntegrationTestCase context "Transport" do setup do @host, @port = ELASTICSEARCH_HOSTS.first.split(':') end shutdown do begin; Object.send(:remove_const, :Manticore); rescue NameError; end end should 'allow to customize the Faraday adapter to Manticore' do client = Elasticsearch::Transport::Client.new( transport_class: Elasticsearch::Transport::Transport::HTTP::Manticore, trace: true, hosts: [ { host: @host, port: @port } ] ) response = client.perform_request 'GET', '' assert_respond_to(response.body, :to_hash) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/integration/transport_test.rb000066400000000000000000000130431462737751600332270ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' class Elasticsearch::Transport::Transport::ClientIntegrationTest < Elasticsearch::Test::IntegrationTestCase startup do Elasticsearch::Extensions::Test::Cluster.start(number_of_nodes: 2) if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?(number_of_nodes: 2) end shutdown do Elasticsearch::Extensions::Test::Cluster.stop(number_of_nodes: 2) if ENV['SERVER'] and Elasticsearch::Extensions::Test::Cluster.running?(number_of_nodes: 2) end context "Transport" do setup do @host, @port = ELASTICSEARCH_HOSTS.first.split(':') @hosts = { hosts: [ { host: @host, port: @port } ] } end should "use the default Faraday adapter" do transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new(@hosts) do |f| f.response :logger end client = Elasticsearch::Transport::Client.new transport: transport assert_equal(client.transport.connections.first.connection.adapter, Faraday::Adapter::NetHttp) client.perform_request 'GET', '' end unless jruby? should "allow to customize the Faraday adapter to Typhoeus" do if is_faraday_v2? require 'faraday/typhoeus' else require 'typhoeus' end transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new(@hosts) do |f| f.response :logger f.adapter :typhoeus end client = Elasticsearch::Transport::Client.new transport: transport assert_equal(client.transport.connections.first.connection.adapter, Faraday::Adapter::Typhoeus) client.perform_request 'GET', '' end should "use the Curb client" do require 'curb' require 'elasticsearch/transport/transport/http/curb' transport = Elasticsearch::Transport::Transport::HTTP::Curb.new(@hosts) do |curl| curl.verbose = true end client = Elasticsearch::Transport::Client.new transport: transport assert_equal(client.transport.class, Elasticsearch::Transport::Transport::HTTP::Curb) client.perform_request 'GET', '' end should "deserialize JSON responses in the Curb client" do require 'curb' require 'elasticsearch/transport/transport/http/curb' transport = Elasticsearch::Transport::Transport::HTTP::Curb.new(@hosts) do |curl| curl.verbose = true end client = Elasticsearch::Transport::Client.new transport: transport response = client.perform_request 'GET', '' assert_respond_to(response.body, :to_hash) assert_not_nil response.body['name'] assert_equal 'application/json', response.headers['content-type'] end should 'allow to customize the Faraday adapter to Patron' do if is_faraday_v2? require 'faraday/patron' else require 'patron' end transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new(@hosts) do |f| f.response :logger f.adapter :patron end client = Elasticsearch::Transport::Client.new(transport: transport) assert_equal(client.transport.connections.first.connection.adapter, Faraday::Adapter::Patron) client.perform_request 'GET', '' end should "allow to customize the Faraday adapter to NetHttpPersistent" do require 'faraday/net_http_persistent' transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new(@hosts) do |f| f.response :logger f.adapter :net_http_persistent end client = Elasticsearch::Transport::Client.new transport: transport assert_equal(client.transport.connections.first.connection.adapter, Faraday::Adapter::NetHttpPersistent) client.perform_request 'GET', '' end should 'allow to customize the Faraday adapter to HTTPClient' do require 'faraday/httpclient' transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new(@hosts) do |f| f.response :logger f.adapter :httpclient end client = Elasticsearch::Transport::Client.new(transport: transport) assert_equal(client.transport.connections.first.connection.adapter, Faraday::Adapter::HTTPClient) client.perform_request 'GET', '' end should "allow to define connection parameters and pass them" do transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new( hosts: [ { host: @host, port: @port } ], options: { transport_options: { params: { :format => 'yaml' } } } ) client = Elasticsearch::Transport::Client.new transport: transport response = client.perform_request 'GET', '' assert response.body.start_with?("---\n"), "Response body should be YAML: #{response.body.inspect}" end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/profile/000077500000000000000000000000001462737751600267235ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/profile/client_benchmark_test.rb000066400000000000000000000120371462737751600336020ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' class Elasticsearch::Transport::ClientProfilingTest < Elasticsearch::Test::ProfilingTest startup do Elasticsearch::Extensions::Test::Cluster.start if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running? end context "Elasticsearch client benchmark" do setup do @port = (ENV['TEST_CLUSTER_PORT'] || 9250).to_i client = Elasticsearch::Client.new host: "localhost:#{@port}", adapter: ::Faraday.default_adapter client.perform_request 'DELETE', 'ruby_test_benchmark' rescue nil client.perform_request 'PUT', 'ruby_test_benchmark', {}, {settings: {index: {number_of_shards: 1, number_of_replicas: 0}}} 100.times do client.perform_request 'POST', 'ruby_test_benchmark_search/test', {}, {foo: 'bar'}; end client.perform_request 'POST', 'ruby_test_benchmark_search/_refresh' end teardown do client = Elasticsearch::Client.new host: "localhost:#{@port}" client.perform_request 'DELETE', 'ruby_test_benchmark' rescue nil client.perform_request 'DELETE', 'ruby_test_benchmark_search' rescue nil end context "with a single-node cluster and the default adapter" do setup do @client = Elasticsearch::Client.new hosts: "localhost:#{@port}", adapter: ::Faraday.default_adapter end measure "get the cluster info", count: 1_000 do @client.perform_request 'GET', '' end measure "index a document" do @client.perform_request 'POST', 'ruby_test_benchmark/test', {}, {foo: 'bar'} end measure "search" do @client.perform_request 'GET', 'ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}} end end context "with a two-node cluster and the default adapter" do setup do @client = Elasticsearch::Client.new hosts: ["localhost:#{@port}", "localhost:#{@port+1}"], adapter: ::Faraday.default_adapter end measure "get the cluster info", count: 1_000 do @client.perform_request 'GET', '' end measure "index a document"do @client.perform_request 'POST', 'ruby_test_benchmark/test', {}, {foo: 'bar'} end measure "search" do @client.perform_request 'GET', 'ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}} end end context "with a single-node cluster and the Curb client" do setup do require 'curb' require 'elasticsearch/transport/transport/http/curb' @client = Elasticsearch::Client.new host: "localhost:#{@port}", transport_class: Elasticsearch::Transport::Transport::HTTP::Curb end measure "get the cluster info", count: 1_000 do @client.perform_request 'GET', '' end measure "index a document" do @client.perform_request 'POST', 'ruby_test_benchmark/test', {}, {foo: 'bar'} end measure "search" do @client.perform_request 'GET', 'ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}} end end context "with a single-node cluster and the Typhoeus client" do setup do require 'typhoeus' require 'typhoeus/adapters/faraday' @client = Elasticsearch::Client.new host: "localhost:#{@port}", adapter: :typhoeus end measure "get the cluster info", count: 1_000 do @client.perform_request 'GET', '' end measure "index a document" do @client.perform_request 'POST', 'ruby_test_benchmark/test', {}, {foo: 'bar'} end measure "search" do @client.perform_request 'GET', 'ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}} end end context "with a single-node cluster and the Patron adapter" do setup do require 'patron' @client = Elasticsearch::Client.new host: "localhost:#{@port}", adapter: :patron end measure "get the cluster info", count: 1_000 do @client.perform_request 'GET', '' end measure "index a document" do @client.perform_request 'POST', 'ruby_test_benchmark/test', {}, {foo: 'bar'} end measure "search" do @client.perform_request 'GET', 'ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}} end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/test_helper.rb000066400000000000000000000072321462737751600301320ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. ELASTICSEARCH_HOSTS = if hosts = ENV['TEST_ES_SERVER'] || ENV['ELASTICSEARCH_HOSTS'] hosts.split(',').map do |host| /(http\:\/\/)?(\S+)/.match(host)[2] end else ['localhost:9200'] end.freeze TEST_HOST, TEST_PORT = ELASTICSEARCH_HOSTS.first.split(':') if ELASTICSEARCH_HOSTS JRUBY = defined?(JRUBY_VERSION) if ENV['COVERAGE'] require 'simplecov' SimpleCov.start { add_filter %r{^/test/} } end # Register `at_exit` handler for integration tests shutdown. # MUST be called before requiring `test/unit`. if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9' at_exit { Elasticsearch::Test::IntegrationTestCase.__run_at_exit_hooks } end require 'minitest/autorun' require 'minitest/reporters' require 'shoulda/context' require 'mocha/minitest' require 'ansi/code' require 'require-prof' if ENV["REQUIRE_PROF"] require 'elasticsearch-transport' require 'logger' require 'hashie' RequireProf.print_timing_infos if ENV["REQUIRE_PROF"] if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9' require 'elasticsearch/extensions/test/cluster' require 'elasticsearch/extensions/test/startup_shutdown' require 'elasticsearch/extensions/test/profiling' unless JRUBY end class FixedMinitestSpecReporter < Minitest::Reporters::SpecReporter def before_test(test) last_test = tests.last before_suite(test.class) unless last_test if last_test && last_test.klass.to_s != test.class.to_s after_suite(last_test.class) if last_test before_suite(test.class) end end end module Minitest class Test def assert_nothing_raised(*args) begin line = __LINE__ yield rescue RuntimeError => e raise MiniTest::Assertion, "Exception raised:\n<#{e.class}>", e.backtrace end true end def assert_not_nil(object, msg=nil) msg = message(msg) { "<#{object.inspect}> expected to not be nil" } assert !object.nil?, msg end def assert_block(*msgs) assert yield, *msgs end alias :assert_raise :assert_raises end end def is_faraday_v2? Gem::Version.new(Faraday::VERSION) >= Gem::Version.new(2) end Minitest::Reporters.use! FixedMinitestSpecReporter.new module Elasticsearch module Test class IntegrationTestCase < Minitest::Test extend Elasticsearch::Extensions::Test::StartupShutdown shutdown { Elasticsearch::Extensions::Test::Cluster.stop if ENV['SERVER'] && started? && Elasticsearch::Extensions::Test::Cluster.running? } end end module Test class ProfilingTest < Minitest::Test extend Elasticsearch::Extensions::Test::StartupShutdown extend Elasticsearch::Extensions::Test::Profiling shutdown { Elasticsearch::Extensions::Test::Cluster.stop if ENV['SERVER'] && started? && Elasticsearch::Extensions::Test::Cluster.running? } end unless JRUBY end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/unit/000077500000000000000000000000001462737751600262425ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/unit/adapters_test.rb000066400000000000000000000052561462737751600314410ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' class Elasticsearch::Transport::Transport::ClientAdaptersUnitTest < Minitest::Test context 'Adapters' do setup do begin Object.send(:remove_const, :Patron) rescue NameError end end should 'use the default Faraday adapter' do fork do client = Elasticsearch::Transport::Client.new assert_equal(client.transport.connections.first.connection.adapter, Faraday::Adapter::NetHttp) end end should 'use Patron Faraday adapter' do fork do if is_faraday_v2? require 'faraday/patron' else require 'patron' end client = Elasticsearch::Transport::Client.new assert_equal(client.transport.connections.first.connection.adapter, Faraday::Adapter::Patron) end end should 'use Typhoeus Faraday adapter' do fork do if is_faraday_v2? require 'faraday/typhoeus' else require 'typhoeus' end client = Elasticsearch::Transport::Client.new assert_equal(client.transport.connections.first.connection.adapter, Faraday::Adapter::Typhoeus) end end should 'use NetHttpPersistent Faraday adapter' do fork do if is_faraday_v2? require 'faraday/net_http_persistent' else require 'net/http/persistent' end client = Elasticsearch::Transport::Client.new assert_equal(client.transport.connections.first.connection.adapter, Faraday::Adapter::NetHttpPersistent) end end should 'use HTTPClient Faraday adapter' do fork do if is_faraday_v2? require 'faraday/httpclient' else require 'httpclient' end client = Elasticsearch::Transport::Client.new assert_equal(Faraday::Adapter::HTTPClient, client.transport.connections.first.connection.adapter) end end end unless jruby? end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/unit/connection_test.rb000066400000000000000000000114551462737751600317730ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' class Elasticsearch::Transport::Transport::Connections::ConnectionTest < Minitest::Test include Elasticsearch::Transport::Transport::Connections context "Connection" do should "be initialized with :host, :connection, and :options" do c = Connection.new :host => 'x', :connection => 'y', :options => {} assert_equal 'x', c.host assert_equal 'y', c.connection assert_instance_of Hash, c.options end should "return full path" do c = Connection.new assert_equal '_search', c.full_path('_search') assert_equal '_search', c.full_path('_search', {}) assert_equal '_search?foo=bar', c.full_path('_search', {:foo => 'bar'}) assert_equal '_search?foo=bar+bam', c.full_path('_search', {:foo => 'bar bam'}) end should "return full url" do c = Connection.new :host => { :protocol => 'http', :host => 'localhost', :port => '9200' } assert_equal 'http://localhost:9200/_search?foo=bar', c.full_url('_search', {:foo => 'bar'}) end should "return full url with credentials" do c = Connection.new :host => { :protocol => 'http', :user => 'U', :password => 'P', :host => 'localhost', :port => '9200' } assert_equal 'http://U:P@localhost:9200/_search?foo=bar', c.full_url('_search', {:foo => 'bar'}) end should "return full url with escaped credentials" do c = Connection.new :host => { :protocol => 'http', :user => 'U$$$', :password => 'P^^^', :host => 'localhost', :port => '9200' } assert_equal 'http://U%24%24%24:P%5E%5E%5E@localhost:9200/_search?foo=bar', c.full_url('_search', {:foo => 'bar'}) end should "return full url with path" do c = Connection.new :host => { :protocol => 'http', :host => 'localhost', :port => '9200', :path => '/foo' } assert_equal 'http://localhost:9200/foo/_search?foo=bar', c.full_url('_search', {:foo => 'bar'}) end should "return right full url with path when path starts with /" do c = Connection.new :host => { :protocol => 'http', :host => 'localhost', :port => '9200', :path => '/foo' } assert_equal 'http://localhost:9200/foo/_search?foo=bar', c.full_url('/_search', {:foo => 'bar'}) end should "have a string representation" do c = Connection.new :host => 'x' assert_match(/host: x/, c.to_s) assert_match(/alive/, c.to_s) end should "not be dead by default" do c = Connection.new assert ! c.dead? end should "be dead when marked" do c = Connection.new.dead! assert c.dead? assert_equal 1, c.failures assert_in_delta c.dead_since, Time.now, 1 end should "be alive when marked" do c = Connection.new.dead! assert c.dead? assert_equal 1, c.failures assert_in_delta c.dead_since, Time.now, 1 c.alive! assert ! c.dead? assert_equal 1, c.failures end should "be healthy when marked" do c = Connection.new.dead! assert c.dead? assert_equal 1, c.failures assert_in_delta c.dead_since, Time.now, 1 c.healthy! assert ! c.dead? assert_equal 0, c.failures end should "be resurrected if timeout passed" do c = Connection.new.dead! now = Time.now + 60 Time.stubs(:now).returns(now) assert c.resurrect!, c.inspect assert ! c.dead?, c.inspect end should "be resurrected if timeout passed for multiple failures" do c = Connection.new.dead!.dead! now = Time.now + 60*2 Time.stubs(:now).returns(now) assert c.resurrect!, c.inspect assert ! c.dead?, c.inspect end should "implement the equality operator" do c1 = Connection.new(:host => { :protocol => 'http', :host => 'foo', :port => 123 }) c2 = Connection.new(:host => { :protocol => 'http', :host => 'foo', :port => 123 }) c3 = Connection.new(:host => { :protocol => 'http', :host => 'foo', :port => 456 }) assert c1 == c2, "Connection #{c1} should be equal to #{c2}" assert c2 != c3, "Connection #{c2} should NOT be equal to #{c3}" end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/unit/response_test.rb000066400000000000000000000022711462737751600314660ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' class Elasticsearch::Transport::Transport::ResponseTest < Minitest::Test context "Response" do should "force-encode the body into UTF" do body = "Hello Encoding!".encode(Encoding::ISO_8859_1) assert_equal 'ISO-8859-1', body.encoding.name response = Elasticsearch::Transport::Transport::Response.new 200, body assert_equal 'UTF-8', response.body.encoding.name end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/unit/serializer_test.rb000066400000000000000000000022431462737751600320000ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' class Elasticsearch::Transport::Transport::SerializerTest < Minitest::Test context "Serializer" do should "use MultiJson by default" do ::MultiJson.expects(:load) ::MultiJson.expects(:dump) Elasticsearch::Transport::Transport::Serializer::MultiJson.new.load('{}') Elasticsearch::Transport::Transport::Serializer::MultiJson.new.dump({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/unit/transport_base_test.rb000066400000000000000000000577411462737751600326720ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' class Elasticsearch::Transport::Transport::BaseTest < Minitest::Test class EmptyTransport include Elasticsearch::Transport::Transport::Base end class DummyTransport include Elasticsearch::Transport::Transport::Base def __build_connection(host, options={}, block=nil) Elasticsearch::Transport::Transport::Connections::Connection.new :host => host, :connection => Object.new end end class DummyTransportPerformer < DummyTransport def perform_request(method, path, params={}, body=nil, &block); super; end end class DummySerializer def initialize(*); end end class DummySniffer def initialize(*); end end context "Transport::Base" do should "raise exception when it doesn't implement __build_connection" do assert_raise NoMethodError do EmptyTransport.new.__build_connection({ :host => 'foo'}, {}) end end should "build connections on initialization" do DummyTransport.any_instance.expects(:__build_connections) transport = DummyTransport.new end should "have default serializer" do transport = DummyTransport.new assert_instance_of Elasticsearch::Transport::Transport::Base::DEFAULT_SERIALIZER_CLASS, transport.serializer end should "have custom serializer" do transport = DummyTransport.new :options => { :serializer_class => DummySerializer } assert_instance_of DummySerializer, transport.serializer transport = DummyTransport.new :options => { :serializer => DummySerializer.new } assert_instance_of DummySerializer, transport.serializer end should "have default sniffer" do transport = DummyTransport.new assert_instance_of Elasticsearch::Transport::Transport::Sniffer, transport.sniffer end should "have custom sniffer" do transport = DummyTransport.new :options => { :sniffer_class => DummySniffer } assert_instance_of DummySniffer, transport.sniffer end context "when combining the URL" do setup do @transport = DummyTransport.new @basic_parts = { :protocol => 'http', :host => 'myhost', :port => 8080 } end should "combine basic parts" do assert_equal 'http://myhost:8080', @transport.__full_url(@basic_parts) end should "combine path" do assert_equal 'http://myhost:8080/api', @transport.__full_url(@basic_parts.merge :path => '/api') end should "combine authentication credentials" do assert_equal 'http://U:P@myhost:8080', @transport.__full_url(@basic_parts.merge :user => 'U', :password => 'P') end should "escape the username and password" do assert_equal 'http://user%40domain:foo%2Fbar@myhost:8080', @transport.__full_url(@basic_parts.merge :user => 'user@domain', :password => 'foo/bar') end end end context "getting a connection" do setup do @transport = DummyTransportPerformer.new :options => { :reload_connections => 5 } @transport.stubs(:connections).returns(stub :get_connection => Object.new) @transport.stubs(:sniffer).returns(stub :hosts => []) end should "get a connection" do assert_not_nil @transport.get_connection end should "increment the counter" do assert_equal 0, @transport.counter 3.times { @transport.get_connection } assert_equal 3, @transport.counter end should "reload connections when it hits the threshold" do @transport.expects(:reload_connections!).twice 12.times { @transport.get_connection } assert_equal 12, @transport.counter end should "not reload connections by default" do @transport = DummyTransportPerformer.new @transport.stubs(:connections).returns(stub :get_connection => Object.new) @transport.expects(:reload_connections!).never 10_010.times { @transport.get_connection } assert_equal 10_010, @transport.counter end should "not reload connections when the option is set to false" do @transport = DummyTransportPerformer.new :options => { :reload_connections => false } @transport.stubs(:connections).returns(stub :get_connection => Object.new) @transport.expects(:reload_connections!).never 10_010.times { @transport.get_connection } assert_equal 10_010, @transport.counter end end context "performing a request" do setup do @transport = DummyTransportPerformer.new end should "raise an error when no block is passed" do assert_raise NoMethodError do @transport.peform_request 'GET', '/' end end should "get the connection" do @transport.expects(:get_connection).returns(stub_everything :failures => 1) @transport.perform_request 'GET', '/' do; Elasticsearch::Transport::Transport::Response.new 200, 'OK'; end end should "raise an error when no connection is available" do @transport.expects(:get_connection).returns(nil) assert_raise Elasticsearch::Transport::Transport::Error do @transport.perform_request 'GET', '/' do; Elasticsearch::Transport::Transport::Response.new 200, 'OK'; end end end should "call the passed block" do x = 0 @transport.expects(:get_connection).returns(stub_everything :failures => 1) @transport.perform_request 'GET', '/' do |connection, url| x += 1 Elasticsearch::Transport::Transport::Response.new 200, 'OK' end assert_equal 1, x end should "deserialize a response JSON body" do @transport.expects(:get_connection).returns(stub_everything :failures => 1) @transport.serializer.expects(:load).returns({'foo' => 'bar'}) response = @transport.perform_request 'GET', '/' do Elasticsearch::Transport::Transport::Response.new 200, '{"foo":"bar"}', {"content-type" => 'application/json'} end assert_instance_of Elasticsearch::Transport::Transport::Response, response assert_equal 'bar', response.body['foo'] end should "not deserialize a response string body" do @transport.expects(:get_connection).returns(stub_everything :failures => 1) @transport.serializer.expects(:load).never response = @transport.perform_request 'GET', '/' do Elasticsearch::Transport::Transport::Response.new 200, 'FOOBAR', {"content-type" => 'text/plain'} end assert_instance_of Elasticsearch::Transport::Transport::Response, response assert_equal 'FOOBAR', response.body end should "not deserialize an empty response body" do @transport.expects(:get_connection).returns(stub_everything :failures => 1) @transport.serializer.expects(:load).never response = @transport.perform_request 'GET', '/' do Elasticsearch::Transport::Transport::Response.new 200, '', {"content-type" => 'application/json'} end assert_instance_of Elasticsearch::Transport::Transport::Response, response assert_equal '', response.body end should "serialize non-String objects" do @transport.serializer.expects(:dump).times(3) @transport.__convert_to_json({:foo => 'bar'}) @transport.__convert_to_json([1, 2, 3]) @transport.__convert_to_json(nil) end should "not serialize a String object" do @transport.serializer.expects(:dump).never @transport.__convert_to_json('{"foo":"bar"}') end should "raise an error for HTTP status 404" do @transport.expects(:get_connection).returns(stub_everything :failures => 1) assert_raise Elasticsearch::Transport::Transport::Errors::NotFound do @transport.perform_request 'GET', '/' do Elasticsearch::Transport::Transport::Response.new 404, 'NOT FOUND' end end end should "raise an error for HTTP status 404 with application/json content type" do @transport.expects(:get_connection).returns(stub_everything :failures => 1) assert_raise Elasticsearch::Transport::Transport::Errors::NotFound do @transport.perform_request 'GET', '/' do Elasticsearch::Transport::Transport::Response.new 404, 'NOT FOUND', {"content-type" => 'application/json'} end end end should "raise an error on server failure" do @transport.expects(:get_connection).returns(stub_everything :failures => 1) assert_raise Elasticsearch::Transport::Transport::Errors::InternalServerError do @transport.perform_request 'GET', '/' do Elasticsearch::Transport::Transport::Response.new 500, 'ERROR' end end end should "raise an error on connection failure" do @transport.expects(:get_connection).returns(stub_everything :failures => 1) # `block.expects(:call).raises(::Errno::ECONNREFUSED)` fails on Ruby 1.8 block = lambda { |a,b| raise ::Errno::ECONNREFUSED } assert_raise ::Errno::ECONNREFUSED do @transport.perform_request 'GET', '/', &block end end should 'raise TooManyRequestsError on 429' do @transport.expects(:get_connection).returns(stub_everything :failures => 1) assert_raise Elasticsearch::Transport::Transport::Errors::TooManyRequests do @transport.perform_request 'GET', '/' do Elasticsearch::Transport::Transport::Response.new 429, 'ERROR' end end end should "not raise an error when the :ignore argument has been passed" do @transport.stubs(:get_connection).returns(stub_everything :failures => 1) assert_raise Elasticsearch::Transport::Transport::Errors::BadRequest do @transport.perform_request 'GET', '/' do Elasticsearch::Transport::Transport::Response.new 400, 'CLIENT ERROR' end end # No `BadRequest` error @transport.perform_request 'GET', '/', :ignore => 400 do Elasticsearch::Transport::Transport::Response.new 400, 'CLIENT ERROR' end end should "mark the connection as dead on failure" do c = stub_everything :failures => 1 @transport.expects(:get_connection).returns(c) block = lambda { |a,b| raise ::Errno::ECONNREFUSED } c.expects(:dead!) assert_raise( ::Errno::ECONNREFUSED ) { @transport.perform_request 'GET', '/', &block } end end context "performing a request with reload connections on connection failures" do setup do fake_collection = stub_everything :get_connection => stub_everything(:failures => 1), :all => stub_everything(:size => 2) @transport = DummyTransportPerformer.new :options => { :reload_on_failure => 2 } @transport.stubs(:connections). returns(fake_collection) @block = lambda { |c, u| puts "UNREACHABLE" } end should "reload connections when host is unreachable" do @block.expects(:call).times(2). raises(Errno::ECONNREFUSED). then.returns(stub_everything :failures => 1) @transport.expects(:reload_connections!).returns([]) @transport.perform_request('GET', '/', &@block) assert_equal 2, @transport.counter end end context "performing a request with retry on connection failures" do setup do @transport = DummyTransportPerformer.new :options => { :retry_on_failure => true } @transport.stubs(:connections).returns(stub :get_connection => stub_everything(:failures => 1)) @block = Proc.new { |c, u| puts "UNREACHABLE" } end should "retry DEFAULT_MAX_RETRIES when host is unreachable" do @block.expects(:call).times(4). raises(Errno::ECONNREFUSED). then.raises(Errno::ECONNREFUSED). then.raises(Errno::ECONNREFUSED). then.returns(stub_everything :failures => 1) assert_nothing_raised do @transport.perform_request('GET', '/', &@block) assert_equal 4, @transport.counter end end should "raise an error after max tries" do @block.expects(:call).times(4). raises(Errno::ECONNREFUSED). then.raises(Errno::ECONNREFUSED). then.raises(Errno::ECONNREFUSED). then.raises(Errno::ECONNREFUSED). then.returns(stub_everything :failures => 1) assert_raise Errno::ECONNREFUSED do @transport.perform_request('GET', '/', &@block) end end end context "performing a request with retry on status" do setup do DummyTransportPerformer.any_instance.stubs(:connections).returns(stub :get_connection => stub_everything(:failures => 1)) logger = Logger.new(STDERR) logger.level = Logger::DEBUG DummyTransportPerformer.any_instance.stubs(:logger).returns(logger) @block = Proc.new { |c, u| puts "ERROR" } end should "not retry when the status code does not match" do @transport = DummyTransportPerformer.new :options => { :retry_on_status => 500 } assert_equal [500], @transport.instance_variable_get(:@retry_on_status) @block.expects(:call). returns(Elasticsearch::Transport::Transport::Response.new 400, 'Bad Request'). times(1) @transport.logger. expects(:warn). with( regexp_matches(/Attempt \d to get response/) ). never assert_raise Elasticsearch::Transport::Transport::Errors::BadRequest do @transport.perform_request('GET', '/', {}, nil, &@block) end end should "retry when the status code does match" do @transport = DummyTransportPerformer.new :options => { :retry_on_status => 500 } assert_equal [500], @transport.instance_variable_get(:@retry_on_status) @block.expects(:call). returns(Elasticsearch::Transport::Transport::Response.new 500, 'Internal Error'). times(4) @transport.logger. expects(:warn). with( regexp_matches(/Attempt \d to get response/) ). times(4) assert_raise Elasticsearch::Transport::Transport::Errors::InternalServerError do @transport.perform_request('GET', '/', &@block) end end end context "logging" do setup do @transport = DummyTransportPerformer.new :options => { :logger => Logger.new('/dev/null') } fake_connection = stub :full_url => 'localhost:9200/_search?size=1', :host => 'localhost', :connection => stub_everything, :failures => 0, :healthy! => true @transport.stubs(:get_connection).returns(fake_connection) @transport.serializer.stubs(:load).returns 'foo' => 'bar' @transport.serializer.stubs(:dump).returns '{"foo":"bar"}' end should "log the request and response" do @transport.logger.expects(:info). with do |line| line =~ %r|POST localhost\:9200/_search\?size=1 \[status\:200, request:.*s, query:n/a\]| end @transport.logger.expects(:debug). with '> {"foo":"bar"}' @transport.logger.expects(:debug). with '< {"foo":"bar"}' @transport.perform_request 'POST', '_search', {:size => 1}, {:foo => 'bar'} do Elasticsearch::Transport::Transport::Response.new 200, '{"foo":"bar"}' end end should "sanitize password in the URL" do fake_connection = stub :full_url => 'http://user:password@localhost:9200/_search?size=1', :host => 'localhost', :connection => stub_everything, :failures => 0, :healthy! => true @transport.stubs(:get_connection).returns(fake_connection) @transport.logger.expects(:info).with do |message| assert_match(/http:\/\/user:\*{1,15}@localhost\:9200/, message) true end @transport.perform_request('GET', '/') {Elasticsearch::Transport::Transport::Response.new 200, '{"foo":"bar"}' } end should "log a failed Elasticsearch request as fatal" do @block = Proc.new { |c, u| puts "ERROR" } @block.expects(:call).returns(Elasticsearch::Transport::Transport::Response.new 500, 'ERROR') @transport.expects(:__log_response) @transport.logger.expects(:fatal) assert_raise Elasticsearch::Transport::Transport::Errors::InternalServerError do @transport.perform_request('POST', '_search', &@block) end end should "not log a failed Elasticsearch request as fatal" do @block = Proc.new { |c, u| puts "ERROR" } @block.expects(:call).returns(Elasticsearch::Transport::Transport::Response.new 500, 'ERROR') @transport.expects(:__log_response).once @transport.logger.expects(:fatal).never # No `BadRequest` error @transport.perform_request('POST', '_search', :ignore => 500, &@block) end should "log and re-raise a Ruby exception" do @block = Proc.new { |c, u| puts "ERROR" } @block.expects(:call).raises(Exception) @transport.expects(:__log_response).never @transport.logger.expects(:fatal) assert_raise(Exception) { @transport.perform_request('POST', '_search', &@block) } end end context "tracing" do setup do @transport = DummyTransportPerformer.new :options => { :tracer => Logger.new('/dev/null') } fake_connection = stub :full_url => 'localhost:9200/_search?size=1', :host => 'localhost', :connection => stub_everything, :failures => 0, :healthy! => true @transport.stubs(:get_connection).returns(fake_connection) @transport.serializer.stubs(:load).returns 'foo' => 'bar' @transport.serializer.stubs(:dump).returns <<-JSON.gsub(/^ /, '') { "foo" : { "bar" : { "bam" : true } } } JSON end should "trace the request" do @transport.tracer.expects(:info). with do |message| message == <<-CURL.gsub(/^ /, '') curl -X POST 'http://localhost:9200/_search?pretty&size=1' -d '{ "foo" : { "bar" : { "bam" : true } } } ' CURL end.once @transport.perform_request 'POST', '_search', {:size => 1}, {:q => 'foo'} do Elasticsearch::Transport::Transport::Response.new 200, '{"foo":"bar"}' end end should "trace a failed Elasticsearch request" do @block = Proc.new { |c, u| puts "ERROR" } @block.expects(:call).returns(Elasticsearch::Transport::Transport::Response.new 500, 'ERROR') @transport.expects(:__trace) assert_raise Elasticsearch::Transport::Transport::Errors::InternalServerError do @transport.perform_request('POST', '_search', &@block) end end end context "reloading connections" do setup do @transport = DummyTransport.new :options => { :logger => Logger.new('/dev/null') } end should "rebuild connections" do @transport.sniffer.expects(:hosts).returns([]) @transport.expects(:__rebuild_connections) @transport.reload_connections! end should "log error and continue when timing out while sniffing hosts" do @transport.sniffer.expects(:hosts).raises(Elasticsearch::Transport::Transport::SnifferTimeoutError) @transport.logger.expects(:error) assert_nothing_raised do @transport.reload_connections! end end should "keep existing connections" do @transport.__rebuild_connections :hosts => [ { :host => 'node1', :port => 1 } ], :options => { :http => {} } assert_equal 1, @transport.connections.size old_connection_id = @transport.connections.first.object_id @transport.__rebuild_connections :hosts => [ { :host => 'node1', :port => 1 }, { :host => 'node2', :port => 2 } ], :options => { :http => {} } assert_equal 2, @transport.connections.size assert_equal old_connection_id, @transport.connections.first.object_id end should "remove dead connections" do @transport.__rebuild_connections :hosts => [ { :host => 'node1', :port => 1 }, { :host => 'node2', :port => 2 } ], :options => { :http => {} } assert_equal 2, @transport.connections.size @transport.connections[1].dead! @transport.__rebuild_connections :hosts => [ { :host => 'node1', :port => 1 } ], :options => { :http => {} } assert_equal 1, @transport.connections.size assert_equal 1, @transport.connections.all.size end should "not duplicate connections" do @transport.__rebuild_connections :hosts => [ { :host => 'node1', :port => 1 }, { :host => 'node2', :port => 2 } ], :options => { :http => {} } assert_equal 2, @transport.connections.size @transport.connections[0].dead! @transport.__rebuild_connections :hosts => [ { :host => 'node1', :port => 1 }, { :host => 'node2', :port => 2 } ], :options => { :http => {} } assert_equal 2, @transport.connections.all.size assert_equal 1, @transport.connections.size end end context "rebuilding connections" do setup do @transport = DummyTransport.new end should "close connections" do @transport.expects(:__close_connections) @transport.__rebuild_connections :hosts => [ { :scheme => 'http', :host => 'foo', :port => 1 } ], :options => { :http => {} } end should "should replace the connections" do assert_equal 0, @transport.connections.size @transport.__rebuild_connections :hosts => [{ :scheme => 'http', :host => 'foo', :port => 1 }], :options => { :http => {} } assert_equal 1, @transport.connections.size end end context "resurrecting connections" do setup do @transport = DummyTransportPerformer.new end should "delegate to dead connections" do @transport.connections.expects(:dead).returns([]) @transport.resurrect_dead_connections! end should "not resurrect connections until timeout" do @transport.connections.expects(:get_connection).returns(stub_everything :failures => 1).times(5) @transport.expects(:resurrect_dead_connections!).never 5.times { @transport.get_connection } end should "resurrect connections after timeout" do @transport.connections.expects(:get_connection).returns(stub_everything :failures => 1).times(5) @transport.expects(:resurrect_dead_connections!) 4.times { @transport.get_connection } now = Time.now + 60*2 Time.stubs(:now).returns(now) @transport.get_connection end should "mark connection healthy if it succeeds" do c = stub_everything(:failures => 1) @transport.expects(:get_connection).returns(c) c.expects(:healthy!) @transport.perform_request('GET', '/') { |connection, url| Elasticsearch::Transport::Transport::Response.new 200, 'OK' } end end context "errors" do should "raise highest-level Error exception for any ServerError" do assert_kind_of Elasticsearch::Transport::Transport::Error, Elasticsearch::Transport::Transport::ServerError.new end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/unit/transport_curb_test.rb000066400000000000000000000140071462737751600326770ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' if JRUBY puts "'#{File.basename(__FILE__)}' not supported on JRuby #{RUBY_VERSION}" else require 'elasticsearch/transport/transport/http/curb' require 'curb' class Elasticsearch::Transport::Transport::HTTP::FaradayTest < Minitest::Test include Elasticsearch::Transport::Transport::HTTP context "Curb transport" do setup do @transport = Curb.new :hosts => [ { :host => 'foobar', :port => 1234 } ] end should "implement host_unreachable_exceptions" do assert_instance_of Array, @transport.host_unreachable_exceptions end should "implement __build_connections" do assert_equal 1, @transport.hosts.size assert_equal 1, @transport.connections.size assert_instance_of ::Curl::Easy, @transport.connections.first.connection assert_equal 'http://foobar:1234', @transport.connections.first.connection.url end should "perform the request" do @transport.connections.first.connection.expects(:http).returns(stub_everything) @transport.perform_request 'GET', '/' end should "set body for GET request" do @transport.connections.first.connection.expects(:put_data=).with('{"foo":"bar"}') @transport.connections.first.connection.expects(:http).with(:GET).returns(stub_everything) @transport.perform_request 'GET', '/', {}, '{"foo":"bar"}' end should "perform request with headers" do @transport.connections.first.connection.expects(:put_data=).with('{"foo":"bar"}') @transport.connections.first.connection.expects(:http).with(:POST).returns(stub_everything) @transport.connections.first.connection.headers.expects(:merge!).with("Content-Type" => "application/x-ndjson") @transport.perform_request 'POST', '/', {}, {:foo => 'bar'}, {"Content-Type" => "application/x-ndjson"} end should "set body for PUT request" do @transport.connections.first.connection.expects(:put_data=) @transport.connections.first.connection.expects(:http).with(:PUT).returns(stub_everything) @transport.perform_request 'PUT', '/', {}, {:foo => 'bar'} end should "serialize the request body" do @transport.connections.first.connection.expects(:http).with(:POST).returns(stub_everything) @transport.serializer.expects(:dump) @transport.perform_request 'POST', '/', {}, {:foo => 'bar'} end should "not serialize a String request body" do @transport.connections.first.connection.expects(:http).with(:POST).returns(stub_everything) @transport.serializer.expects(:dump).never @transport.perform_request 'POST', '/', {}, '{"foo":"bar"}' end should "set application/json response header" do @transport.connections.first.connection.expects(:http).with(:GET).returns(stub_everything) @transport.connections.first.connection.expects(:body_str).returns('{"foo":"bar"}') @transport.connections.first.connection.expects(:header_str).returns('HTTP/1.1 200 OK\r\nContent-Type: application/json; charset=UTF-8\r\nContent-Length: 311\r\n\r\n') response = @transport.perform_request 'GET', '/' assert_equal 'application/json', response.headers['content-type'] end should "handle HTTP methods" do @transport.connections.first.connection.expects(:http).with(:HEAD).returns(stub_everything) @transport.connections.first.connection.expects(:http).with(:GET).returns(stub_everything) @transport.connections.first.connection.expects(:http).with(:PUT).returns(stub_everything) @transport.connections.first.connection.expects(:http).with(:POST).returns(stub_everything) @transport.connections.first.connection.expects(:http).with(:DELETE).returns(stub_everything) %w| HEAD GET PUT POST DELETE |.each { |method| @transport.perform_request method, '/' } assert_raise(ArgumentError) { @transport.perform_request 'FOOBAR', '/' } end should "properly pass the Content-Type header option" do transport = Curb.new :hosts => [ { :host => 'foobar', :port => 1234 } ], :options => { :transport_options => { :headers => { 'Content-Type' => 'foo/bar' } } } assert_equal "foo/bar", transport.connections.first.connection.headers["Content-Type"] end should "allow to set options for Curb" do transport = Curb.new :hosts => [ { :host => 'foobar', :port => 1234 } ] do |curl| curl.headers["User-Agent"] = "myapp-0.0" end assert_equal "myapp-0.0", transport.connections.first.connection.headers["User-Agent"] end should "set the credentials if passed" do transport = Curb.new :hosts => [ { :host => 'foobar', :port => 1234, :user => 'foo', :password => 'bar' } ] assert_equal 'foo', transport.connections.first.connection.username assert_equal 'bar', transport.connections.first.connection.password end should "use global http configuration" do transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234 } ], :options => { :http => { :scheme => 'https', :user => 'U', :password => 'P' } } assert_equal 'https://U:P@foobar:1234/', transport.connections.first.full_url('') end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/unit/transport_faraday_test.rb000066400000000000000000000244101462737751600333520ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' class Elasticsearch::Transport::Transport::HTTP::FaradayTest < Minitest::Test include Elasticsearch::Transport::Transport::HTTP context "Faraday transport" do setup do @transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234 } ] end should "implement host_unreachable_exceptions" do assert_instance_of Array, @transport.host_unreachable_exceptions end should "implement __build_connections" do assert_equal 1, @transport.hosts.size assert_equal 1, @transport.connections.size assert_instance_of ::Faraday::Connection, @transport.connections.first.connection assert_equal 'http://foobar:1234/', @transport.connections.first.connection.url_prefix.to_s end should "perform the request" do @transport.connections.first.connection.expects(:run_request).returns(stub_everything) @transport.perform_request 'GET', '/' end should "return a Response" do @transport.connections.first.connection.expects(:run_request).returns(stub_everything) response = @transport.perform_request 'GET', '/' assert_instance_of Elasticsearch::Transport::Transport::Response, response end should "properly prepare the request" do @transport.connections.first.connection.expects(:run_request).with do |method, url, body, headers| assert_equal :post, method assert_equal '{"foo":"bar"}', body assert_nil headers['Accept'] true end.returns(stub_everything) @transport.perform_request 'POST', '/', {}, {:foo => 'bar'} end should "properly prepare the request with custom headers" do @transport.connections.first.connection.expects(:run_request).with do |method, url, body, headers| assert_equal :post, method assert_equal '{"foo":"bar"}', body assert_nil headers['Accept'] assert_equal "application/x-ndjson", headers['Content-Type'] true end.returns(stub_everything) @transport.perform_request 'POST', '/', {}, {:foo => 'bar'}, {"Content-Type" => "application/x-ndjson"} end should "properly pass the Content-Type header option" do transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234 } ], :options => { :transport_options => { :headers => { 'Content-Type' => 'foo/bar' } } } transport.connections.first.connection.expects(:run_request).with do |method, url, body, headers| assert_equal 'foo/bar', headers['Content-Type'] true end.returns(stub_everything) transport.perform_request 'GET', '/' end should "serialize the request body" do @transport.connections.first.connection.expects(:run_request).returns(stub_everything) @transport.serializer.expects(:dump) @transport.perform_request 'POST', '/', {}, {:foo => 'bar'} end should "not serialize a String request body" do @transport.connections.first.connection.expects(:run_request).returns(stub_everything) @transport.serializer.expects(:dump).never @transport.perform_request 'POST', '/', {}, '{"foo":"bar"}' end should "pass the selector_class options to collection" do @transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234 } ], :options => { :selector_class => Elasticsearch::Transport::Transport::Connections::Selector::Random } assert_instance_of Elasticsearch::Transport::Transport::Connections::Selector::Random, @transport.connections.selector end should "pass the selector option to collection" do @transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234 } ], :options => { :selector => Elasticsearch::Transport::Transport::Connections::Selector::Random.new } assert_instance_of Elasticsearch::Transport::Transport::Connections::Selector::Random, @transport.connections.selector end should "pass a configuration block to the Faraday constructor" do config_block = lambda do |f| f.response :logger f.path_prefix = '/moo' end transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234 } ], &config_block handlers = transport.connections.first.connection.builder.handlers assert_equal 1, handlers.size assert handlers.include?(::Faraday::Response::Logger), "#{handlers.inspect} does not include <::Faraday::Adapter::Logger>" assert_equal '/moo', transport.connections.first.connection.path_prefix assert_equal 'http://foobar:1234/moo', transport.connections.first.connection.url_prefix.to_s end should "pass transport_options to the Faraday constructor" do transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234 } ], :options => { :transport_options => { :request => { :open_timeout => 1 }, :headers => { :foo_bar => 'bar' }, :ssl => { :verify => false } } } assert_equal 1, transport.connections.first.connection.options.open_timeout assert_equal 'bar', transport.connections.first.connection.headers['Foo-Bar'] assert_equal false, transport.connections.first.connection.ssl.verify? end should "merge in parameters defined in the Faraday connection parameters" do transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234 } ], :options => { :transport_options => { :params => { :format => 'yaml' } } } # transport.logger = Logger.new(STDERR) transport.connections.first.connection.expects(:run_request). with do |method, url, params, body| assert_match(/\?format=yaml/, url) true end. returns(stub_everything) transport.perform_request 'GET', '' end should "not overwrite request parameters with the Faraday connection parameters" do transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234 } ], :options => { :transport_options => { :params => { :format => 'yaml' } } } # transport.logger = Logger.new(STDERR) transport.connections.first.connection.expects(:run_request). with do |method, url, params, body| assert_match(/\?format=json/, url) true end. returns(stub_everything) transport.perform_request 'GET', '', { :format => 'json' } end should "set the credentials if passed" do transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234, :user => 'foo', :password => 'bar' } ] assert_equal 'Basic Zm9vOmJhcg==', transport.connections.first.connection.headers['Authorization'] end should "set the credentials if they exist in options" do transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234 } ], :options => { :user => 'foo', :password => 'bar' } assert_equal 'Basic Zm9vOmJhcg==', transport.connections.first.connection.headers['Authorization'] end should "override options credentials if passed explicitly" do transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234, :user => 'foo', :password => 'bar' }, { :host => 'foobar2', :port => 1234 } ], :options => { :user => 'foo2', :password => 'bar2' } assert_equal 'Basic Zm9vOmJhcg==', transport.connections.first.connection.headers['Authorization'] assert_equal 'Basic Zm9vMjpiYXIy', transport.connections[1].connection.headers['Authorization'] end should "set connection scheme to https if passed" do transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234, :scheme => 'https' } ] assert_instance_of ::Faraday::Connection, transport.connections.first.connection assert_equal 'https://foobar:1234/', transport.connections.first.connection.url_prefix.to_s end should "set connection scheme to https if it exist in options" do transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234} ], :options => { :scheme => 'https' } assert_instance_of ::Faraday::Connection, transport.connections.first.connection assert_equal 'https://foobar:1234/', transport.connections.first.connection.url_prefix.to_s end should "override options scheme if passed explicitly" do transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234, :scheme => 'http'} ], :options => { :scheme => 'https' } assert_instance_of ::Faraday::Connection, transport.connections.first.connection assert_equal 'http://foobar:1234/', transport.connections.first.connection.url_prefix.to_s end should "use global http configuration" do transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234 } ], :options => { :http => { :scheme => 'https', :user => 'U', :password => 'P' } } assert_equal 'https://U:P@foobar:1234/', transport.connections.first.full_url('') end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-transport/test/unit/transport_manticore_test.rb000066400000000000000000000263071462737751600337330ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' if JRUBY require 'elasticsearch/transport/transport/http/manticore' require 'manticore' module Elasticsearch module Transport module Transport module HTTP class ManticoreTest < Minitest::Test include Elasticsearch::Transport::Transport::HTTP def common_headers { 'Content-Type' => 'application/json', 'User-Agent' => @transport.send(:user_agent_header) } end context 'Manticore transport' do setup do @transport = Manticore.new(hosts: [{ host: '127.0.0.1', port: 8080 }]) end should 'implement host_unreachable_exceptions' do assert_instance_of Array, @transport.host_unreachable_exceptions end should 'implement __build_connections' do assert_equal 1, @transport.hosts.size assert_equal 1, @transport.connections.size assert_instance_of(::Manticore::Client, @transport.connections.first.connection) end should 'not close connections in __close_connections' do assert_equal 1, @transport.connections.size @transport.__close_connections assert_equal 1, @transport.connections.size end should 'perform the request' do @transport.connections.first.connection.expects(:get).returns(stub_everything) response = @transport.perform_request('GET', '/') end should 'set body for GET request' do @transport.connections.first.connection.expects(:get) .with( 'http://127.0.0.1:8080/', { body: '{"foo":"bar"}', headers: common_headers } ).returns(stub_everything) @transport.perform_request 'GET', '/', {}, '{"foo":"bar"}' end should 'set body for PUT request' do @transport.connections.first.connection.expects(:put) .with( 'http://127.0.0.1:8080/', { body: '{"foo":"bar"}', headers: { 'Content-Type' => 'application/json', 'User-Agent' => @transport.send(:user_agent_header) } } ).returns(stub_everything) @transport.perform_request 'PUT', '/', {}, { foo: 'bar' } end should 'serialize the request body' do @transport.connections.first.connection.expects(:post) .with( 'http://127.0.0.1:8080/', { body: '{"foo":"bar"}', headers: { 'Content-Type' => 'application/json', 'User-Agent' => @transport.send(:user_agent_header) } } ).returns(stub_everything) @transport.perform_request 'POST', '/', {}, { 'foo' => 'bar' } end should 'set custom headers for PUT request' do @transport.connections.first.connection.expects(:put) .with( 'http://127.0.0.1:8080/', { body: '{"foo":"bar"}', headers: { 'Content-Type' => 'application/x-ndjson', 'User-Agent' => @transport.send(:user_agent_header) } } ).returns(stub_everything) @transport.perform_request 'PUT', '/', {}, '{"foo":"bar"}', { 'Content-Type' => 'application/x-ndjson' } end should 'not serialize a String request body' do @transport.connections.first.connection.expects(:post) .with( 'http://127.0.0.1:8080/', { body: '{"foo":"bar"}', headers: { 'Content-Type' => 'application/json', 'User-Agent' => @transport.send(:user_agent_header) } } ).returns(stub_everything) @transport.serializer.expects(:dump).never @transport.perform_request 'POST', '/', {}, '{"foo":"bar"}' end should 'set application/json header' do options = { headers: { 'content-type' => 'application/json' } } transport = Manticore.new(hosts: [{ host: 'localhost', port: 8080 }], options: options) transport.connections.first.connection.stub( 'http://localhost:8080/', body: '""', headers: { 'Content-Type' => 'application/x-ndjson', 'User-Agent' => @transport.send(:user_agent_header) }, code: 200 ) response = transport.perform_request('GET', '/', {}) assert_equal response.status, 200 end should "set headers from 'transport_options'" do options = { transport_options: { headers: { 'Content-Type' => 'foo/bar' } } } transport = Manticore.new(hosts: [{ host: 'localhost', port: 8080 }], options: options) assert_equal( 'foo/bar', transport.connections.first.connection.instance_variable_get(:@options)[:headers]['Content-Type'] ) # TODO: Needs to check @request_options end should 'handle HTTP methods' do @transport.connections.first.connection.expects(:delete).with('http://127.0.0.1:8080/', { headers: common_headers }).returns(stub_everything) @transport.connections.first.connection.expects(:head).with('http://127.0.0.1:8080/', { headers: common_headers }).returns(stub_everything) @transport.connections.first.connection.expects(:get).with('http://127.0.0.1:8080/', { headers: common_headers }).returns(stub_everything) @transport.connections.first.connection.expects(:put).with('http://127.0.0.1:8080/', { headers: common_headers }).returns(stub_everything) @transport.connections.first.connection.expects(:post).with('http://127.0.0.1:8080/', { headers: common_headers }).returns(stub_everything) %w[HEAD GET PUT POST DELETE].each { |method| @transport.perform_request method, '/' } assert_raise(ArgumentError) { @transport.perform_request 'FOOBAR', '/' } end should 'allow to set options for Manticore' do options = { headers: { 'User-Agent' => 'myapp-0.0' } } transport = Manticore.new(hosts: [{ host: 'foobar', port: 1234 }], options: options) transport.connections.first.connection .expects(:get) .with do |_host, _options| assert_equal 'myapp-0.0', _options[:headers]['User-Agent'] true end .returns(stub_everything) transport.perform_request 'GET', '/', {} end should 'allow to set ssl options for Manticore' do options = { ssl: { truststore: 'test.jks', truststore_password: 'test', verify: false } } ::Manticore::Client.expects(:new).with(options) transport = Manticore.new(hosts: [{ host: 'foobar', port: 1234 }], options: options) assert_equal(transport.options[:ssl][:truststore_password], 'test') end should 'pass :transport_options to Manticore::Client' do options = { transport_options: { potatoes: 1 } } ::Manticore::Client.expects(:new).with(potatoes: 1, ssl: {}) transport = Manticore.new(hosts: [{ host: 'foobar', port: 1234 }], options: options) assert_equal(transport.options[:transport_options][:potatoes], 1) end context 'custom headers' do should 'allow authorization headers' do transport_options = { headers: { 'Authorization' => 'Basic token' } } transport = Manticore.new( hosts: [{ host: 'foobar', port: 1234 }], transport_options: transport_options ) assert_equal( transport.instance_variable_get(:@request_options)[:headers]['Authorization'], 'Basic token' ) transport.connections.first.connection.expects(:get).with do |_host, options| assert_equal('Basic token', options[:headers]['Authorization']) true end.returns(stub_everything) transport.perform_request('GET', '/', {}) end should 'allow user agent headers' do transport_options = { headers: { 'User-Agent' => 'Custom UA' } } transport = Manticore.new( hosts: [{ host: 'localhost' }], transport_options: transport_options ) transport.connections.first.connection.expects(:get).with do |_host, options| assert_equal('Custom UA', options[:headers]['User-Agent']) true end.returns(stub_everything) transport.perform_request('GET', '/', {}) assert_equal( transport.instance_variable_get('@request_options')[:headers]['User-Agent'], 'Custom UA' ) end end end end end end end end else version = "#{defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'Ruby'} #{RUBY_VERSION}" puts "SKIP: '#{File.basename(__FILE__)}' only supported on JRuby (you're running #{version})" end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/000077500000000000000000000000001462737751600233565ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/.gitignore000066400000000000000000000002321462737751600253430ustar00rootroot00000000000000*.gem *.rbc .bundle .config .yardoc Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/Gemfile000066400000000000000000000034711462737751600246560ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. source 'https://rubygems.org' # Specify your gem's dependencies in elasticsearch-xpack.gemspec gemspec group :development do gem 'rspec' gem 'rspec_junit_formatter' if defined?(JRUBY_VERSION) gem 'pry-nav' else gem 'pry-byebug', '~> 3.9' end end if File.exist? File.expand_path('../../elasticsearch-api/elasticsearch-api.gemspec', __FILE__) gem 'elasticsearch-api', path: File.expand_path('../../elasticsearch-api', __FILE__), require: false end if File.exist? File.expand_path('../../elasticsearch-transport/elasticsearch-transport.gemspec', __FILE__) gem 'elasticsearch-transport', path: File.expand_path('../../elasticsearch-transport', __FILE__), require: false end if File.exist? File.expand_path('../../elasticsearch/elasticsearch.gemspec', __FILE__) gem 'elasticsearch', path: File.expand_path('../../elasticsearch/', __FILE__) end if File.exist? File.expand_path('../../elasticsearch/elasticsearch-extensions.gemspec', __FILE__) gem 'elasticsearch-extensions', path: File.expand_path('../../elasticsearch-extensions/', __FILE__) end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/LICENSE000066400000000000000000000261361462737751600243730ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/README.md000066400000000000000000000037631462737751600246460ustar00rootroot00000000000000# Elasticsearch::XPack ---- ⚠ **This library is deprecated** ⚠ The API endpoints currently living in `elasticsearch-xpack` will be moved into `elasticsearch-api` in version 8.0.0 and forward. You should be able to keep using `elasticsearch-xpack` and the `xpack` namespace in `7.x`. We're running the same tests in `elasticsearch-xpack`, but if you encounter any problems, please let us know [in this issue](https://github.com/elastic/elasticsearch-ruby/issues/1274). However, be aware in `8.0`, the xpack library and namespace won't be available anymore. ---- A Ruby integration for the [X-Pack extension](https://www.elastic.co/guide/en/x-pack/current/xpack-introduction.html) for Elasticsearch. ## Installation Install the package from [Rubygems](https://rubygems.org): gem install elasticsearch-xpack ## Usage If you use the official [Ruby client for Elasticsearch](https://github.com/elastic/elasticsearch-ruby), require the library in your code, and all the methods will be automatically available in the `xpack` namespace: ```ruby require 'elasticsearch' require 'elasticsearch/xpack client = Elasticsearch::Client.new(url: 'http://elastic:changeme@localhost:9200') client.xpack.info # => {"build"=> ..., "features"=> ...} ``` The integration is designed as a standalone `Elasticsearch::XPack::API` module, so it's easy to mix it into a different client, and the methods will be available in the top namespace. For documentation, look into the RDoc annotations in the source files, which contain links to the official [X-Pack for the Elastic Stack](https://www.elastic.co/guide/en/x-pack/current/index.html) documentation. For examples, look into the [`examples`](examples) folder in this repository. You can use the provided `test:elasticsearch` Rake task to launch a [Docker-based](https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html) Elasticsearch node with the full X-Pack license preinstalled. ## License This software is licensed under the [Apache 2 license](./LICENSE). elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/Rakefile000066400000000000000000000051251462737751600250260ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'bundler/gem_tasks' require 'rake/testtask' require 'rspec/core/rake_task' task :default do exec "rake --tasks" end Rake::TestTask.new('test:unit') do |test| test.libs << 'test' test.test_files = FileList['test/unit/**/*_test.rb'] test.verbose = false test.warning = false end namespace :test do desc 'Run REST API YAML tests' RSpec::Core::RakeTask.new(:rest_api) do |t| ENV['TEST_SUITE'] = 'platinum' t.pattern = 'spec/xpack/rest_api_yaml_spec.rb' end RSpec::Core::RakeTask.new(:spec) do |t| t.pattern = 'spec/xpack/**/*_spec.rb' t.exclude_pattern = 'spec/xpack/rest_api_yaml_spec.rb' end desc "Run integration tests" task :integration do Rake::Task['test:rest_api'].invoke end desc "Run all tests" task :all do Rake::Task['test:unit'].invoke Rake::Task['test:spec'].invoke Rake::Task['test:rest_api'].invoke end desc "Run Elasticsearch with X-Pack installed (Docker)" task :elasticsearch, :stack_version do |_, args| sh <<-COMMAND.gsub(/^\s*/, '').gsub(/\s{1,}/, ' ') docker run \ --name elasticsearch-xpack \ --env "discovery.type=single-node" \ --env "cluster.name=elasticsearch-api-test" \ --env "node.name=es-01" \ --env "http.port=9200" \ --env "cluster.routing.allocation.disk.threshold_enabled=false" \ --env "node.attr.testattr=test" \ --env "path.repo=/tmp" \ --env "repositories.url.allowed_urls=http://snapshot.test*" \ --env "bootstrap.memory_lock=true" \ --env "ELASTIC_PASSWORD=changeme" \ --ulimit nofile=65536:65536 \ --ulimit memlock=-1:-1 \ --publish 9260:9200 \ --memory 4g \ --rm \ docker.elastic.co/elasticsearch/elasticsearch:#{args[:stack_version]} COMMAND end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/elasticsearch-xpack.gemspec000066400000000000000000000064421462737751600306470ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'elasticsearch/xpack/version' Gem::Specification.new do |spec| spec.name = 'elasticsearch-xpack' spec.version = Elasticsearch::XPack::VERSION spec.authors = ['Karel Minarik'] spec.email = ['karel@elastic.co'] spec.summary = 'Ruby integrations for the X-Pack extensions for Elasticsearch' spec.description = 'Ruby integrations for the X-Pack extensions for Elasticsearch' spec.homepage = 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.16/index.html' spec.license = 'Apache-2.0' spec.metadata = { 'homepage_uri' => 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.16/index.html', 'changelog_uri' => 'https://github.com/elastic/elasticsearch-ruby/blob/7.16/CHANGELOG.md', 'source_code_uri' => 'https://github.com/elastic/elasticsearch-ruby/tree/7.16/elasticsearch-xpack', 'bug_tracker_uri' => 'https://github.com/elastic/elasticsearch-ruby/issues' } spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.require_paths = ['lib'] spec.add_development_dependency 'bundler' spec.add_development_dependency 'rake', '~> 13' spec.add_development_dependency 'ruby-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius) spec.add_dependency 'elasticsearch-api', '>= 6' spec.add_development_dependency 'elasticsearch', '>= 6' spec.add_development_dependency 'elasticsearch-extensions' spec.add_development_dependency 'elasticsearch-transport', '>= 6' spec.add_development_dependency 'activesupport' spec.add_development_dependency 'ansi' spec.add_development_dependency 'minitest' spec.add_development_dependency 'minitest-reporters' spec.add_development_dependency 'mocha' spec.add_development_dependency 'pry' spec.add_development_dependency 'shoulda-context' spec.add_development_dependency 'yard' spec.post_install_message = <<~MSG WARNING: This library is deprecated The API endpoints currently living in elasticsearch-xpack will be moved into elasticsearch-api in version 8.0.0 and forward. You should be able to keep using elasticsearch-xpack and the xpack namespace in 7.x. We're running the same tests in elasticsearch-xpack, but if you encounter any problems, please let us know in this issue: https://github.com/elastic/elasticsearch-ruby/issues/1274 \n MSG end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/examples/000077500000000000000000000000001462737751600251745ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/examples/watcher/000077500000000000000000000000001462737751600266315ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/examples/watcher/error_500.rb000066400000000000000000000141711462737751600306770ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # An example of a complex configuration for Elasticsearch Watcher alerting and notification system. # # Execute this file from the root of the repository: # # ALERT_EMAIL=email@example.com bundle exec ruby -I lib ./examples/watcher/error_500.rb # # The watch searches for `500` errors in a specific index on a periodic basis, and performs three # actions when at least 3 errors have been received in the last 5 minutes: # # 1. indexes the error documents and aggregations returned from search, # 2. sends a notification via e-mail, and # 3. sends the data to a webhook. # # If you want to test sending the e-mail, you have to configure Watcher: # # # NOTE: If you want to use Gmail and you have 2-factor authentication enabled, # generate an "App password", and use it in the `password` field. # # You can run a simple Sinatra application to test the webhook action with this script: # # $ ruby -r sinatra -r json -e 'post("/") { json = JSON.parse(request.body.read); puts %Q~Received [#{json["watch_id"]}] with payload: #{json["payload"]}~ }' # require 'elasticsearch' require 'elasticsearch/xpack' password = ENV.fetch('ELASTIC_PASSWORD', 'changeme') client = Elasticsearch::Client.new url: "http://elastic:#{password}@localhost:9260", log: true client.transport.logger.formatter = proc do |severity, datetime, progname, msg| "\e[2m#{msg}\e[0m\n" end # Print information about the Watcher plugin # cluster_info = client.info xpack_info = client.xpack.info puts "Elasticsearch #{cluster_info['version']['number']} | X-Pack build [#{xpack_info['build']['hash']}]" # Delete the Watcher and test indices # ['test_errors', 'alerts', '.watcher-history-*'].each do |index| client.indices.delete index: index, ignore: 404 end # Register a new watch # client.xpack.watcher.put_watch id: 'error_500', body: { # Label the watch # metadata: { tags: ['errors'] }, # Run the watch every 10 seconds # trigger: { schedule: { interval: '10s' } }, # Search for at least 3 documents matching the condition # condition: { compare: { 'ctx.payload.hits.total' => { gt: 3 } } }, # Throttle the watch execution for 30 seconds # throttle_period: '30s', # The search request to execute # input: { search: { request: { indices: ['test_errors'], body: { query: { bool: { must: [ { match: { status: 500 } } , { range: { timestamp: { from: '{{ctx.trigger.scheduled_time}}||-5m', to: '{{ctx.trigger.triggered_time}}' } } } ] } }, # Return hosts with most errors # aggregations: { hosts: { terms: { field: 'host' } } } }}} }, # The actions to perform # actions: { send_email: { transform: { # Transform the data for the template # script: { source: "[ 'total': ctx.payload.hits.total, 'hosts': ctx.payload.aggregations.hosts.buckets.collect(bucket -> [ 'host': bucket.key, 'errors': bucket.doc_count ]), 'errors': ctx.payload.hits.hits.collect(d -> d._source) ]" } }, email: { to: ENV.fetch('ALERT_EMAIL', 'alert@example.com'), subject: '[ALERT] {{ctx.watch_id}}', body: <<-BODY.gsub(/^ {28}/, ''), Received {{ctx.payload.total}} errors in the last 5 minutes. Hosts: {{#ctx.payload.hosts}}- {{host}} ({{errors}} errors)\n{{/ctx.payload.hosts}} A file with complete data is attached to this message.\n BODY attachments: { 'data.yml' => { data: { format: 'yaml' } } } } }, index_payload: { # Transform the data to be stored # transform: { script: { lang: 'painless', source: "[ 'watch_id': ctx.watch_id, 'payload': ctx.payload ]" } }, index: { index: 'alerts', doc_type: 'alert' } }, ping_webhook: { webhook: { method: 'post', url: 'http://localhost:4567', body: %q|{"watch_id" : "{{ctx.watch_id}}", "payload" : "{{ctx.payload}}"}| } } } } # Create the index with example documents # client.indices.create index: 'test_errors', body: { mappings: { properties: { host: { type: 'keyword' } } } } # Index documents to trigger the watch # 10.times do client.index index: 'test_errors', type: 'd', body: { timestamp: Time.now.utc.iso8601, status: "#{rand(4..5)}00", host: "10.0.0.#{rand(1..3)}" } end # Wait a bit... # print "Waiting 30 seconds..." $i=0; while $i < 30 do sleep(1); print('.'); $i+=1 end; puts "\n" # Display information about watch execution # client.search(index: '.watcher-history-*', q: 'watch_id:error_500', sort: 'trigger_event.triggered_time:asc')['hits']['hits'].each do |r| print "[#{r['_source']['watch_id']}] #{r['_source']['state'].upcase} at #{r['_source']['result']['execution_time']}" if r['_source']['state'] == 'executed' print " > Actions: " print r['_source']['result']['actions'].map { |a| "[#{a['id']}] #{a['status']}#{a['error'] ? ': '+a['error']['type'] : ''}" }.join(', ') end print "\n" end # Delete the watch # client.xpack.watcher.delete_watch id: 'error_500' elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/000077500000000000000000000000001462737751600241245ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/000077500000000000000000000000001462737751600267365ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack.rb000066400000000000000000000102211462737751600303650ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'elasticsearch/api' require 'elasticsearch/xpack/version' require 'elasticsearch/xpack/api/actions/params_registry' Dir[ File.expand_path('../xpack/api/actions/**/params_registry.rb', __FILE__) ].each { |f| require f } Dir[ File.expand_path('../xpack/api/actions/**/*.rb', __FILE__) ].each { |f| require f } Dir[ File.expand_path('../xpack/api/namespace/**/*.rb', __FILE__) ].each { |f| require f } module Elasticsearch module XPack module API def self.included(base) Elasticsearch::XPack::API.constants.reject {|c| c == :Client }.each do |m| base.__send__ :include, Elasticsearch::XPack::API.const_get(m) end end class Client include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base include Elasticsearch::XPack::API end end end end Elasticsearch::API::COMMON_PARAMS.push :job_id, :datafeed_id, :filter_id, :snapshot_id, :category_id, :policy_id module Elasticsearch class Client # When a method is called on the client, if it's one of the xpack root # namespace methods, send them to the xpack client. # E.g.: client.xpack.usage => client.usage # Excluding `info` since OSS and XPACK both have info endpoints. TOP_LEVEL_METHODS = [ :usage, :terms_enum ].freeze TOP_LEVEL_METHODS.each do |method_name| define_method method_name do |attr| xpack.send(method_name, attr) end end def xpack unless @xpack warn( 'Deprecation notice: The elasticsearch-xpack gem will be deprecated and all the ' \ "functionality will be available from elasticsearch-api starting in 8.0.0.\n" \ 'See https://github.com/elastic/elasticsearch-ruby/issues/1274' ) end @xpack ||= Elasticsearch::XPack::API::Client.new(self) end def security @security ||= xpack.security end def ml @ml ||= xpack.ml end def rollup @rollup ||= xpack.rollup end def watcher @watcher ||= xpack.watcher end def graph @graph ||= xpack.graph end def migration @migration ||= xpack.migration end def sql @sql ||= xpack.sql end def deprecation @deprecation ||= xpack.deprecation end def data_frame @data_frame ||= xpack.data_frame end def ilm @ilm ||= xpack.ilm end def license @license ||= xpack.license end def transform @transform ||= xpack.transform end def async_search @async_search ||= xpack.async_search end def cat @cat ||= xpack.cat end def indices @indices ||= xpack.indices end def searchable_snapshots @searchable_snapshots ||= xpack.searchable_snapshots end def cross_cluster_replication @cross_cluster_replication ||= xpack.cross_cluster_replication end def autoscaling @autoscaling ||= xpack.autoscaling end def enrich @enrich ||= xpack.enrich end def eql @eql ||= xpack.eql end def snapshot_lifecycle_management @snapshot_lifecycle_management ||= xpack.snapshot_lifecycle_management end def text_structure @text_structure ||= xpack.text_structure end def logstash @logstash ||= xpack.logstash end def fleet @fleet ||= xpack.fleet end end end if defined?(Elasticsearch::Client) elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/000077500000000000000000000000001462737751600300445ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/000077500000000000000000000000001462737751600306155ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/000077500000000000000000000000001462737751600322555ustar00rootroot00000000000000async_search/000077500000000000000000000000001462737751600346405ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actionsdelete.rb000066400000000000000000000035141462737751600364320ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/async_search# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module AsyncSearch module Actions # Deletes an async search by ID. If the search is still running, the search request will be cancelled. Otherwise, the saved search results are deleted. # # @option arguments [String] :id The async search ID # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/async-search.html # def delete(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_DELETE path = "_async_search/#{Elasticsearch::API::Utils.__listify(_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get.rb000066400000000000000000000050711462737751600357470ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/async_search# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module AsyncSearch module Actions # Retrieves the results of a previously submitted async search request given its ID. # # @option arguments [String] :id The async search ID # @option arguments [Time] :wait_for_completion_timeout Specify the time that the request should block waiting for the final response # @option arguments [Time] :keep_alive Specify the time interval in which the results (partial or final) for this search will be available # @option arguments [Boolean] :typed_keys Specify whether aggregation and suggester names should be prefixed by their respective types in the response # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/async-search.html # def get(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = "_async_search/#{Elasticsearch::API::Utils.__listify(_id)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get, [ :wait_for_completion_timeout, :keep_alive, :typed_keys ].freeze) end end end end end params_registry.rb000066400000000000000000000040461462737751600404040ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/async_search# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module AsyncSearch module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end status.rb000066400000000000000000000034141462737751600365120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/async_search# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module AsyncSearch module Actions # Retrieves the status of a previously submitted async search request given its ID. # # @option arguments [String] :id The async search ID # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/async-search.html # def status(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = "_async_search/status/#{Elasticsearch::API::Utils.__listify(_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end submit.rb000066400000000000000000000214211462737751600364700ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/async_search# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module AsyncSearch module Actions # Executes a search request asynchronously. # # @option arguments [List] :index A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices # @option arguments [Time] :wait_for_completion_timeout Specify the time that the request should block waiting for the final response # @option arguments [Boolean] :keep_on_completion Control whether the response should be stored in the cluster if it completed within the provided [wait_for_completion] time (default: false) # @option arguments [Time] :keep_alive Update the time interval in which the results (partial or final) for this search will be available # @option arguments [Number] :batched_reduce_size The number of shard results that should be reduced at once on the coordinating node. This value should be used as the granularity at which progress results will be made available. # @option arguments [Boolean] :request_cache Specify if request cache should be used for this request or not, defaults to true # @option arguments [String] :analyzer The analyzer to use for the query string # @option arguments [Boolean] :analyze_wildcard Specify whether wildcard and prefix queries should be analyzed (default: false) # @option arguments [String] :default_operator The default operator for query string query (AND or OR) (options: AND, OR) # @option arguments [String] :df The field to use as default where no field prefix is given in the query string # @option arguments [Boolean] :explain Specify whether to return detailed information about score computation as part of a hit # @option arguments [List] :stored_fields A comma-separated list of stored fields to return as part of a hit # @option arguments [List] :docvalue_fields A comma-separated list of fields to return as the docvalue representation of a field for each hit # @option arguments [Number] :from Starting offset (default: 0) # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :ignore_throttled Whether specified concrete, expanded or aliased indices should be ignored when throttled # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Boolean] :lenient Specify whether format-based query failures (such as providing text to a numeric field) should be ignored # @option arguments [String] :preference Specify the node or shard the operation should be performed on (default: random) # @option arguments [String] :q Query in the Lucene query string syntax # @option arguments [List] :routing A comma-separated list of specific routing values # @option arguments [String] :search_type Search operation type (options: query_then_fetch, dfs_query_then_fetch) # @option arguments [Number] :size Number of hits to return (default: 10) # @option arguments [List] :sort A comma-separated list of : pairs # @option arguments [List] :_source True or false to return the _source field or not, or a list of fields to return # @option arguments [List] :_source_excludes A list of fields to exclude from the returned _source field # @option arguments [List] :_source_includes A list of fields to extract and return from the _source field # @option arguments [Number] :terminate_after The maximum number of documents to collect for each shard, upon reaching which the query execution will terminate early. # @option arguments [List] :stats Specific 'tag' of the request for logging and statistical purposes # @option arguments [String] :suggest_field Specify which field to use for suggestions # @option arguments [String] :suggest_mode Specify suggest mode (options: missing, popular, always) # @option arguments [Number] :suggest_size How many suggestions to return in response # @option arguments [String] :suggest_text The source text for which the suggestions should be returned # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Boolean] :track_scores Whether to calculate and return scores even if they are not used for sorting # @option arguments [Boolean] :track_total_hits Indicate if the number of documents that match the query should be tracked # @option arguments [Boolean] :allow_partial_search_results Indicate if an error should be returned if there is a partial search failure or timeout # @option arguments [Boolean] :typed_keys Specify whether aggregation and suggester names should be prefixed by their respective types in the response # @option arguments [Boolean] :version Specify whether to return document version as part of a hit # @option arguments [Boolean] :seq_no_primary_term Specify whether to return sequence number and primary term of the last modification of each hit # @option arguments [Number] :max_concurrent_shard_requests The number of concurrent shard requests per node this search executes concurrently. This value should be used to limit the impact of the search on the cluster in order to limit the number of concurrent shard requests # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The search definition using the Query DSL # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/async-search.html # def submit(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = if _index "#{Elasticsearch::API::Utils.__listify(_index)}/_async_search" else "_async_search" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:submit, [ :wait_for_completion_timeout, :keep_on_completion, :keep_alive, :batched_reduce_size, :request_cache, :analyzer, :analyze_wildcard, :default_operator, :df, :explain, :stored_fields, :docvalue_fields, :from, :ignore_unavailable, :ignore_throttled, :allow_no_indices, :expand_wildcards, :lenient, :preference, :q, :routing, :search_type, :size, :sort, :_source, :_source_excludes, :_source_includes, :terminate_after, :stats, :suggest_field, :suggest_mode, :suggest_size, :suggest_text, :timeout, :track_scores, :track_total_hits, :allow_partial_search_results, :typed_keys, :version, :seq_no_primary_term, :max_concurrent_shard_requests ].freeze) end end end end end autoscaling/000077500000000000000000000000001462737751600345075ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actionsdelete_autoscaling_policy.rb000066400000000000000000000035551462737751600422560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/autoscaling# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Autoscaling module Actions # Deletes an autoscaling policy. Designed for indirect use by ECE/ESS and ECK. Direct use is not supported. # # @option arguments [String] :name the name of the autoscaling policy # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/autoscaling-delete-autoscaling-policy.html # def delete_autoscaling_policy(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_DELETE path = "_autoscaling/policy/#{Elasticsearch::API::Utils.__listify(_name)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_autoscaling_capacity.rb000066400000000000000000000032251462737751600420630ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/autoscaling# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Autoscaling module Actions # Gets the current autoscaling capacity based on the configured autoscaling policy. Designed for indirect use by ECE/ESS and ECK. Direct use is not supported. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/autoscaling-get-autoscaling-capacity.html # def get_autoscaling_capacity(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_autoscaling/capacity" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_autoscaling_decision.rb000066400000000000000000000036361462737751600420710ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/autoscaling# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Autoscaling module Actions # Gets the current autoscaling decision based on the configured autoscaling policy, indicating whether or not autoscaling is needed. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.16/autoscaling-get-autoscaling-decision.html # def get_autoscaling_decision(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_autoscaling/decision" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_autoscaling_policy.rb000066400000000000000000000035461462737751600415730ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/autoscaling# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Autoscaling module Actions # Retrieves an autoscaling policy. Designed for indirect use by ECE/ESS and ECK. Direct use is not supported. # # @option arguments [String] :name the name of the autoscaling policy # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/autoscaling-get-autoscaling-policy.html # def get_autoscaling_policy(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = "_autoscaling/policy/#{Elasticsearch::API::Utils.__listify(_name)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040461462737751600402530ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/autoscaling# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Autoscaling module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end put_autoscaling_policy.rb000066400000000000000000000040641462737751600416200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/autoscaling# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Autoscaling module Actions # Creates a new autoscaling policy. Designed for indirect use by ECE/ESS and ECK. Direct use is not supported. # # @option arguments [String] :name the name of the autoscaling policy # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body the specification of the autoscaling policy (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/autoscaling-put-autoscaling-policy.html # def put_autoscaling_policy(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_PUT path = "_autoscaling/policy/#{Elasticsearch::API::Utils.__listify(_name)}" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cat/000077500000000000000000000000001462737751600330245ustar00rootroot00000000000000ml_data_frame_analytics.rb000066400000000000000000000062401462737751600401160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Cat module Actions # Gets configuration and usage information about data frame analytics jobs. # # @option arguments [String] :id The ID of the data frame analytics to fetch # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no configs. (This includes `_all` string or when no configs have been specified) # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, kb, m, mb, g, gb, t, tb, p, pb) # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [String] :time The unit in which to display time values (options: d, h, m, s, ms, micros, nanos) # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see http://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-dfanalytics.html # def ml_data_frame_analytics(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = if _id "_cat/ml/data_frame/analytics/#{Elasticsearch::API::Utils.__listify(_id)}" else "_cat/ml/data_frame/analytics" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:ml_data_frame_analytics, [ :allow_no_match, :bytes, :format, :h, :help, :s, :time, :v ].freeze) end end end end end ml_datafeeds.rb000066400000000000000000000063451462737751600357120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Cat module Actions # Gets configuration and usage information about datafeeds. # # @option arguments [String] :datafeed_id The ID of the datafeeds stats to fetch # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no datafeeds. (This includes `_all` string or when no datafeeds have been specified) # @option arguments [Boolean] :allow_no_datafeeds Whether to ignore if a wildcard expression matches no datafeeds. (This includes `_all` string or when no datafeeds have been specified) *Deprecated* # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [String] :time The unit in which to display time values (options: d, h, m, s, ms, micros, nanos) # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see http://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-datafeeds.html # def ml_datafeeds(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _datafeed_id = arguments.delete(:datafeed_id) method = Elasticsearch::API::HTTP_GET path = if _datafeed_id "_cat/ml/datafeeds/#{Elasticsearch::API::Utils.__listify(_datafeed_id)}" else "_cat/ml/datafeeds" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:ml_datafeeds, [ :allow_no_match, :allow_no_datafeeds, :format, :h, :help, :s, :time, :v ].freeze) end end end end end ml_jobs.rb000066400000000000000000000065371462737751600347320ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Cat module Actions # Gets configuration and usage information about anomaly detection jobs. # # @option arguments [String] :job_id The ID of the jobs stats to fetch # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no jobs. (This includes `_all` string or when no jobs have been specified) # @option arguments [Boolean] :allow_no_jobs Whether to ignore if a wildcard expression matches no jobs. (This includes `_all` string or when no jobs have been specified) *Deprecated* # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, kb, m, mb, g, gb, t, tb, p, pb) # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [String] :time The unit in which to display time values (options: d, h, m, s, ms, micros, nanos) # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see http://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-anomaly-detectors.html # def ml_jobs(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_GET path = if _job_id "_cat/ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}" else "_cat/ml/anomaly_detectors" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:ml_jobs, [ :allow_no_match, :allow_no_jobs, :bytes, :format, :h, :help, :s, :time, :v ].freeze) end end end end end ml_trained_models.rb000066400000000000000000000066111462737751600367570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Cat module Actions # Gets configuration and usage information about inference trained models. # # @option arguments [String] :model_id The ID of the trained models stats to fetch # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no trained models. (This includes `_all` string or when no trained models have been specified) # @option arguments [Integer] :from skips a number of trained models # @option arguments [Integer] :size specifies a max number of trained models to get # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, kb, m, mb, g, gb, t, tb, p, pb) # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [String] :time The unit in which to display time values (options: d, h, m, s, ms, micros, nanos) # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-trained-model.html # def ml_trained_models(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _model_id = arguments.delete(:model_id) method = Elasticsearch::API::HTTP_GET path = if _model_id "_cat/ml/trained_models/#{Elasticsearch::API::Utils.__listify(_model_id)}" else "_cat/ml/trained_models" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:ml_trained_models, [ :allow_no_match, :from, :size, :bytes, :format, :h, :help, :s, :time, :v ].freeze) end end end end end params_registry.rb000066400000000000000000000040361462737751600365100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Cat module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end transform.rb000066400000000000000000000062741462737751600353160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Cat module Actions # TODO: Description # # @option arguments [String] :transform_id The id of the transform for which to get stats. '_all' or '*' implies all transforms # @option arguments [Int] :from skips a number of transform configs, defaults to 0 # @option arguments [Int] :size specifies a max number of transforms to get, defaults to 100 # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no transforms. (This includes `_all` string or when no transforms have been specified) # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [String] :time The unit in which to display time values # (options: d (Days),h (Hours),m (Minutes),s (Seconds),ms (Milliseconds),micros (Microseconds),nanos (Nanoseconds)) # @option arguments [Boolean] :v Verbose mode. Display column headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/cat-transforms.html # def transform(arguments = {}) arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_GET path = if _transform_id "_cat/transforms/#{Elasticsearch::API::Utils.__listify(_transform_id)}" else "_cat/transforms" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:transform, [ :from, :size, :allow_no_match, :format, :h, :help, :s, :time, :v ].freeze) end end end end end transforms.rb000066400000000000000000000064251462737751600354770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cat# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Cat module Actions # Gets configuration and usage information about transforms. # # @option arguments [String] :transform_id The id of the transform for which to get stats. '_all' or '*' implies all transforms # @option arguments [Integer] :from skips a number of transform configs, defaults to 0 # @option arguments [Integer] :size specifies a max number of transforms to get, defaults to 100 # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no transforms. (This includes `_all` string or when no transforms have been specified) # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [List] :h Comma-separated list of column names to display # @option arguments [Boolean] :help Return help information # @option arguments [List] :s Comma-separated list of column names or column aliases to sort by # @option arguments [String] :time The unit in which to display time values (options: d, h, m, s, ms, micros, nanos) # @option arguments [Boolean] :v Verbose mode. Display column headers # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cat-transforms.html # def transforms(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_GET path = if _transform_id "_cat/transforms/#{Elasticsearch::API::Utils.__listify(_transform_id)}" else "_cat/transforms" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:transforms, [ :from, :size, :allow_no_match, :format, :h, :help, :s, :time, :v ].freeze) end end end end end cross_cluster_replication/000077500000000000000000000000001462737751600374615ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actionsdelete_auto_follow_pattern.rb000066400000000000000000000034461462737751600454260ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cross_cluster_replication# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions # Deletes auto-follow patterns. # # @option arguments [String] :name The name of the auto follow pattern. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ccr-delete-auto-follow-pattern.html # def delete_auto_follow_pattern(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_DELETE path = "_ccr/auto_follow/#{Elasticsearch::API::Utils.__listify(_name)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end follow.rb000066400000000000000000000052061462737751600413130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cross_cluster_replication# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions # Creates a new follower index configured to follow the referenced leader index. # # @option arguments [String] :index The name of the follower index # @option arguments [String] :wait_for_active_shards Sets the number of shard copies that must be active before returning. Defaults to 0. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The name of the leader index and other optional ccr related parameters (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ccr-put-follow.html # def follow(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_PUT path = "#{Elasticsearch::API::Utils.__listify(_index)}/_ccr/follow" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:follow, [ :wait_for_active_shards ].freeze) end end end end end follow_info.rb000066400000000000000000000036121462737751600423250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cross_cluster_replication# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions # Retrieves information about all follower indices, including parameters and status for each follower index # # @option arguments [List] :index A comma-separated list of index patterns; use `_all` to perform the operation on all indices # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ccr-get-follow-info.html # def follow_info(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = "#{Elasticsearch::API::Utils.__listify(_index)}/_ccr/info" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end follow_stats.rb000066400000000000000000000036461462737751600425370ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cross_cluster_replication# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions # Retrieves follower stats. return shard-level stats about the following tasks associated with each shard for the specified indices. # # @option arguments [List] :index A comma-separated list of index patterns; use `_all` to perform the operation on all indices # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ccr-get-follow-stats.html # def follow_stats(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = "#{Elasticsearch::API::Utils.__listify(_index)}/_ccr/stats" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end forget_follower.rb000066400000000000000000000043251462737751600432110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cross_cluster_replication# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions # Removes the follower retention leases from the leader. # # @option arguments [String] :index the name of the leader index for which specified follower retention leases should be removed # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body the name and UUID of the follower index, the name of the cluster containing the follower index, and the alias from the perspective of that cluster for the remote cluster containing the leader index (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ccr-post-forget-follower.html # def forget_follower(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = "#{Elasticsearch::API::Utils.__listify(_index)}/_ccr/forget_follower" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end get_auto_follow_pattern.rb000066400000000000000000000035731462737751600447440ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cross_cluster_replication# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions # Gets configured auto-follow patterns. Returns the specified auto-follow pattern collection. # # @option arguments [String] :name The name of the auto follow pattern. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ccr-get-auto-follow-pattern.html # def get_auto_follow_pattern(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = if _name "_ccr/auto_follow/#{Elasticsearch::API::Utils.__listify(_name)}" else "_ccr/auto_follow" end params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040621462737751600432230ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cross_cluster_replication# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end pause_auto_follow_pattern.rb000066400000000000000000000035341462737751600452770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cross_cluster_replication# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions # Pauses an auto-follow pattern # # @option arguments [String] :name The name of the auto follow pattern that should pause discovering new indices to follow. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ccr-pause-auto-follow-pattern.html # def pause_auto_follow_pattern(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_POST path = "_ccr/auto_follow/#{Elasticsearch::API::Utils.__listify(_name)}/pause" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end pause_follow.rb000066400000000000000000000036121462737751600425070ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cross_cluster_replication# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions # Pauses a follower index. The follower index will not fetch any additional operations from the leader index. # # @option arguments [String] :index The name of the follower index that should pause following its leader index. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ccr-post-pause-follow.html # def pause_follow(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = "#{Elasticsearch::API::Utils.__listify(_index)}/_ccr/pause_follow" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end put_auto_follow_pattern.rb000066400000000000000000000042611462737751600447700ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cross_cluster_replication# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions # Creates a new named collection of auto-follow patterns against a specified remote cluster. Newly created indices on the remote cluster matching any of the specified patterns will be automatically configured as follower indices. # # @option arguments [String] :name The name of the auto follow pattern. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The specification of the auto follow pattern (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ccr-put-auto-follow-pattern.html # def put_auto_follow_pattern(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_PUT path = "_ccr/auto_follow/#{Elasticsearch::API::Utils.__listify(_name)}" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end resume_auto_follow_pattern.rb000066400000000000000000000035551462737751600454650ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cross_cluster_replication# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions # Resumes an auto-follow pattern that has been paused # # @option arguments [String] :name The name of the auto follow pattern to resume discovering new indices to follow. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ccr-resume-auto-follow-pattern.html # def resume_auto_follow_pattern(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_POST path = "_ccr/auto_follow/#{Elasticsearch::API::Utils.__listify(_name)}/resume" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end resume_follow.rb000066400000000000000000000036631462737751600427000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cross_cluster_replication# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions # Resumes a follower index that has been paused # # @option arguments [String] :index The name of the follow index to resume following. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The name of the leader index and other optional ccr related parameters # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ccr-post-resume-follow.html # def resume_follow(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = "#{Elasticsearch::API::Utils.__listify(_index)}/_ccr/resume_follow" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end stats.rb000066400000000000000000000030041462737751600411410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cross_cluster_replication# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions # Gets all stats related to cross-cluster replication. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ccr-get-stats.html # def stats(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_ccr/stats" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end unfollow.rb000066400000000000000000000036351462737751600416620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/cross_cluster_replication# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions # Stops the following task associated with a follower index and removes index metadata and settings associated with cross-cluster replication. # # @option arguments [String] :index The name of the follower index that should be turned into a regular index. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ccr-post-unfollow.html # def unfollow(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = "#{Elasticsearch::API::Utils.__listify(_index)}/_ccr/unfollow" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end data_frame_transform_deprecated/000077500000000000000000000000001462737751600405345ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actionsdelete_transform.rb000066400000000000000000000054611462737751600444240ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/data_frame_transform_deprecated# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module DataFrameTransformDeprecated module Actions # Deletes an existing transform. # This functionality is in Beta and is subject to change. The design and # code is less mature than official GA features and is being provided # as-is with no warranties. Beta features are not subject to the support # SLA of official GA features. # # @option arguments [String] :transform_id The id of the transform to delete # @option arguments [Boolean] :force When `true`, the transform is deleted regardless of its current state. The default value is `false`, meaning that the transform must be `stopped` before it can be deleted. # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # [_data_frame/transforms/] is deprecated, use [_transform/] in the future. # Deprecated since version 7.5.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/delete-transform.html # def delete_transform(arguments = {}) raise ArgumentError, "Required argument 'transform_id' missing" unless arguments[:transform_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_DELETE path = "_data_frame/transforms/#{Elasticsearch::API::Utils.__listify(_transform_id)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_transform, [ :force ].freeze) end end end end end get_transform.rb000066400000000000000000000065401462737751600437400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/data_frame_transform_deprecated# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module DataFrameTransformDeprecated module Actions # Retrieves configuration information for transforms. # This functionality is in Beta and is subject to change. The design and # code is less mature than official GA features and is being provided # as-is with no warranties. Beta features are not subject to the support # SLA of official GA features. # # @option arguments [String] :transform_id The id or comma delimited list of id expressions of the transforms to get, '_all' or '*' implies get all transforms # @option arguments [Integer] :from skips a number of transform configs, defaults to 0 # @option arguments [Integer] :size specifies a max number of transforms to get, defaults to 100 # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no transforms. (This includes `_all` string or when no transforms have been specified) # @option arguments [Boolean] :exclude_generated Omits generated fields. Allows transform configurations to be easily copied between clusters and within the same cluster # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # [_data_frame/transforms/] is deprecated, use [_transform/] in the future. # Deprecated since version 7.5.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-transform.html # def get_transform(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_GET path = if _transform_id "_data_frame/transforms/#{Elasticsearch::API::Utils.__listify(_transform_id)}" else "_data_frame/transforms" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_transform, [ :from, :size, :allow_no_match, :exclude_generated ].freeze) end end end end end get_transform_stats.rb000066400000000000000000000061411462737751600451530ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/data_frame_transform_deprecated# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module DataFrameTransformDeprecated module Actions # Retrieves usage information for transforms. # This functionality is in Beta and is subject to change. The design and # code is less mature than official GA features and is being provided # as-is with no warranties. Beta features are not subject to the support # SLA of official GA features. # # @option arguments [String] :transform_id The id of the transform for which to get stats. '_all' or '*' implies all transforms # @option arguments [Number] :from skips a number of transform stats, defaults to 0 # @option arguments [Number] :size specifies a max number of transform stats to get, defaults to 100 # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no transforms. (This includes `_all` string or when no transforms have been specified) # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # [_data_frame/transforms/] is deprecated, use [_transform/] in the future. # Deprecated since version 7.5.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-transform-stats.html # def get_transform_stats(arguments = {}) raise ArgumentError, "Required argument 'transform_id' missing" unless arguments[:transform_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_GET path = "_data_frame/transforms/#{Elasticsearch::API::Utils.__listify(_transform_id)}/_stats" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_transform_stats, [ :from, :size, :allow_no_match ].freeze) end end end end end params_registry.rb000066400000000000000000000040671462737751600443030ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/data_frame_transform_deprecated# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module DataFrameTransformDeprecated module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end preview_transform.rb000066400000000000000000000042701462737751600446400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/data_frame_transform_deprecated# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module DataFrameTransformDeprecated module Actions # Previews a transform. # This functionality is in Beta and is subject to change. The design and # code is less mature than official GA features and is being provided # as-is with no warranties. Beta features are not subject to the support # SLA of official GA features. # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The definition for the transform to preview (*Required*) # # *Deprecation notice*: # [_data_frame/transforms/] is deprecated, use [_transform/] in the future. # Deprecated since version 7.5.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/preview-transform.html # def preview_transform(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_data_frame/transforms/_preview" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end put_transform.rb000066400000000000000000000056141462737751600437720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/data_frame_transform_deprecated# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module DataFrameTransformDeprecated module Actions # Instantiates a transform. # This functionality is in Beta and is subject to change. The design and # code is less mature than official GA features and is being provided # as-is with no warranties. Beta features are not subject to the support # SLA of official GA features. # # @option arguments [String] :transform_id The id of the new transform. # @option arguments [Boolean] :defer_validation If validations should be deferred until transform starts, defaults to false. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The transform definition (*Required*) # # *Deprecation notice*: # [_data_frame/transforms/] is deprecated, use [_transform/] in the future. # Deprecated since version 7.5.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/put-transform.html # def put_transform(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'transform_id' missing" unless arguments[:transform_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_PUT path = "_data_frame/transforms/#{Elasticsearch::API::Utils.__listify(_transform_id)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_transform, [ :defer_validation ].freeze) end end end end end start_transform.rb000066400000000000000000000052741462737751600443210ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/data_frame_transform_deprecated# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module DataFrameTransformDeprecated module Actions # Starts one or more transforms. # This functionality is in Beta and is subject to change. The design and # code is less mature than official GA features and is being provided # as-is with no warranties. Beta features are not subject to the support # SLA of official GA features. # # @option arguments [String] :transform_id The id of the transform to start # @option arguments [Time] :timeout Controls the time to wait for the transform to start # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # [_data_frame/transforms/] is deprecated, use [_transform/] in the future. # Deprecated since version 7.5.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/start-transform.html # def start_transform(arguments = {}) raise ArgumentError, "Required argument 'transform_id' missing" unless arguments[:transform_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_POST path = "_data_frame/transforms/#{Elasticsearch::API::Utils.__listify(_transform_id)}/_start" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:start_transform, [ :timeout ].freeze) end end end end end stop_transform.rb000066400000000000000000000061521462737751600441450ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/data_frame_transform_deprecated# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module DataFrameTransformDeprecated module Actions # Stops one or more transforms. # This functionality is in Beta and is subject to change. The design and # code is less mature than official GA features and is being provided # as-is with no warranties. Beta features are not subject to the support # SLA of official GA features. # # @option arguments [String] :transform_id The id of the transform to stop # @option arguments [Boolean] :wait_for_completion Whether to wait for the transform to fully stop before returning or not. Default to false # @option arguments [Time] :timeout Controls the time to wait until the transform has stopped. Default to 30 seconds # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no transforms. (This includes `_all` string or when no transforms have been specified) # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # [_data_frame/transforms/] is deprecated, use [_transform/] in the future. # Deprecated since version 7.5.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/stop-transform.html # def stop_transform(arguments = {}) raise ArgumentError, "Required argument 'transform_id' missing" unless arguments[:transform_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_POST path = "_data_frame/transforms/#{Elasticsearch::API::Utils.__listify(_transform_id)}/_stop" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:stop_transform, [ :wait_for_completion, :timeout, :allow_no_match ].freeze) end end end end end update_transform.rb000066400000000000000000000056771462737751600444550ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/data_frame_transform_deprecated# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module DataFrameTransformDeprecated module Actions # Updates certain properties of a transform. # This functionality is in Beta and is subject to change. The design and # code is less mature than official GA features and is being provided # as-is with no warranties. Beta features are not subject to the support # SLA of official GA features. # # @option arguments [String] :transform_id The id of the transform. (*Required*) # @option arguments [Boolean] :defer_validation If validations should be deferred until transform starts, defaults to false. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The update transform definition (*Required*) # # *Deprecation notice*: # [_data_frame/transforms/] is deprecated, use [_transform/] in the future. # Deprecated since version 7.5.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/update-transform.html # def update_transform(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'transform_id' missing" unless arguments[:transform_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_POST path = "_data_frame/transforms/#{Elasticsearch::API::Utils.__listify(_transform_id)}/_update" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:update_transform, [ :defer_validation ].freeze) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/enrich/000077500000000000000000000000001462737751600335255ustar00rootroot00000000000000delete_policy.rb000066400000000000000000000034231462737751600366160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/enrich# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Enrich module Actions # Deletes an existing enrich policy and its enrich index. # # @option arguments [String] :name The name of the enrich policy # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/delete-enrich-policy-api.html # def delete_policy(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_DELETE path = "_enrich/policy/#{Elasticsearch::API::Utils.__listify(_name)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end execute_policy.rb000066400000000000000000000043321462737751600370160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/enrich# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Enrich module Actions # Creates the enrich index for an existing enrich policy. # # @option arguments [String] :name The name of the enrich policy # @option arguments [Boolean] :wait_for_completion Should the request should block until the execution is complete. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/execute-enrich-policy-api.html # def execute_policy(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_PUT path = "_enrich/policy/#{Elasticsearch::API::Utils.__listify(_name)}/_execute" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:execute_policy, [ :wait_for_completion ].freeze) end end end end end get_policy.rb000066400000000000000000000034471462737751600361410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/enrich# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Enrich module Actions # Gets information about an enrich policy. # # @option arguments [List] :name A comma-separated list of enrich policy names # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-enrich-policy-api.html # def get_policy(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = if _name "_enrich/policy/#{Elasticsearch::API::Utils.__listify(_name)}" else "_enrich/policy" end params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040411462737751600372050ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/enrich# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Enrich module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end put_policy.rb000066400000000000000000000036561462737751600361740ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/enrich# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Enrich module Actions # Creates a new enrich policy. # # @option arguments [String] :name The name of the enrich policy # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The enrich policy to register (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/put-enrich-policy-api.html # def put_policy(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_PUT path = "_enrich/policy/#{Elasticsearch::API::Utils.__listify(_name)}" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end stats.rb000066400000000000000000000030541462737751600351330ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/enrich# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Enrich module Actions # Gets enrich coordinator statistics and information about enrich policies that are currently executing. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/enrich-stats-api.html # def stats(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_enrich/_stats" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/eql/000077500000000000000000000000001462737751600330365ustar00rootroot00000000000000delete.rb000066400000000000000000000035101462737751600345450ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/eql# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Eql module Actions # Deletes an async EQL search by ID. If the search is still running, the search request will be cancelled. Otherwise, the saved search results are deleted. # # @option arguments [String] :id The async search ID # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/eql-search-api.html # def delete(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_DELETE path = "_eql/search/#{Elasticsearch::API::Utils.__listify(_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get.rb000066400000000000000000000045641462737751600340740ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/eql# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Eql module Actions # Returns async results from previously executed Event Query Language (EQL) search # # @option arguments [String] :id The async search ID # @option arguments [Time] :wait_for_completion_timeout Specify the time that the request should block waiting for the final response # @option arguments [Time] :keep_alive Update the time interval in which the results (partial or final) for this search will be available # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/eql-search-api.html # def get(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = "_eql/search/#{Elasticsearch::API::Utils.__listify(_id)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get, [ :wait_for_completion_timeout, :keep_alive ].freeze) end end end end end get_status.rb000066400000000000000000000034251462737751600354720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/eql# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Eql module Actions # Returns the status of a previously submitted async or stored Event Query Language (EQL) search # # @option arguments [String] :id The async search ID # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/eql-search-api.html # def get_status(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = "_eql/search/status/#{Elasticsearch::API::Utils.__listify(_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040361462737751600365220ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/eql# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Eql module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end search.rb000066400000000000000000000056761462737751600345670ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/eql# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Eql module Actions # Returns results matching a query expressed in Event Query Language (EQL) # # @option arguments [String] :index The name of the index to scope the operation # @option arguments [Time] :wait_for_completion_timeout Specify the time that the request should block waiting for the final response # @option arguments [Boolean] :keep_on_completion Control whether the response should be stored in the cluster if it completed within the provided [wait_for_completion] time (default: false) # @option arguments [Time] :keep_alive Update the time interval in which the results (partial or final) for this search will be available # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Eql request body. Use the `query` to limit the query scope. (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/eql-search-api.html # def search(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone arguments[:index] = UNDERSCORE_ALL if !arguments[:index] && arguments[:type] _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = "#{Elasticsearch::API::Utils.__listify(_index)}/_eql/search" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:search, [ :wait_for_completion_timeout, :keep_on_completion, :keep_alive ].freeze) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/fleet/000077500000000000000000000000001462737751600333545ustar00rootroot00000000000000global_checkpoints.rb000066400000000000000000000052731462737751600374630ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/fleet# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Fleet module Actions # Returns the current global checkpoints for an index. This API is design for internal use by the fleet server project. # # @option arguments [String] :index The name of the index. # @option arguments [Boolean] :wait_for_advance Whether to wait for the global checkpoint to advance past the specified current checkpoints # @option arguments [Boolean] :wait_for_index Whether to wait for the target index to exist and all primary shards be active # @option arguments [List] :checkpoints Comma separated list of checkpoints # @option arguments [Time] :timeout Timeout to wait for global checkpoint to advance # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-global-checkpoints.html # def global_checkpoints(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = "#{Elasticsearch::API::Utils.__listify(_index)}/_fleet/global_checkpoints" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:global_checkpoints, [ :wait_for_advance, :wait_for_index, :checkpoints, :timeout ].freeze) end end end end end msearch.rb000066400000000000000000000064761462737751600352610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/fleet# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Fleet module Actions # Multi Search API where the search will only be executed after specified checkpoints are available due to a refresh. This API is designed for internal use by the fleet server project. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :index The index name to use as the default # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The request definitions (metadata-fleet search request definition pairs), separated by newlines (*Required*) # # @see [TODO] # def msearch(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = if _index "#{Elasticsearch::API::Utils.__listify(_index)}/_fleet/_fleet_msearch" else "_fleet/_fleet_msearch" end params = {} body = arguments[:body] case when body.is_a?(Array) && body.any? { |d| d.has_key? :search } payload = body .inject([]) do |sum, item| meta = item data = meta.delete(:search) sum << meta sum << data sum end .map { |item| Elasticsearch::API.serializer.dump(item) } payload << "" unless payload.empty? payload = payload.join("\n") when body.is_a?(Array) payload = body.map { |d| d.is_a?(String) ? d : Elasticsearch::API.serializer.dump(d) } payload << "" unless payload.empty? payload = payload.join("\n") else payload = body end headers = Elasticsearch::API::Utils.ndjson_headers(headers) perform_request(method, path, params, payload, headers).body end end end end end end params_registry.rb000066400000000000000000000040401462737751600370330ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/fleet# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Fleet module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end search.rb000066400000000000000000000062541462737751600350760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/fleet# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Fleet module Actions # Search API where the search will only be executed after specified checkpoints are available due to a refresh. This API is designed for internal use by the fleet server project. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :index The index name to search. # @option arguments [List] :wait_for_checkpoints Comma separated list of checkpoints, one per shard # @option arguments [Time] :wait_for_checkpoints_timeout Explicit wait_for_checkpoints timeout # @option arguments [Boolean] :allow_partial_search_results Indicate if an error should be returned if there is a partial search failure or timeout # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The search definition using the Query DSL # # @see [TODO] # def search(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone arguments[:index] = UNDERSCORE_ALL if !arguments[:index] && arguments[:type] _index = arguments.delete(:index) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = "#{Elasticsearch::API::Utils.__listify(_index)}/_fleet/_fleet_search" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:search, [ :wait_for_checkpoints, :wait_for_checkpoints_timeout, :allow_partial_search_results ].freeze) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/graph/000077500000000000000000000000001462737751600333565ustar00rootroot00000000000000explore.rb000066400000000000000000000061551462737751600353110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/graph# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Graph module Actions # Explore extracted and summarized information about the documents and terms in an index. # # @option arguments [List] :index A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices # @option arguments [List] :type A comma-separated list of document types to search; leave empty to perform the operation on all types *Deprecated* # @option arguments [String] :routing Specific routing value # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Graph Query DSL # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/graph-explore-api.html # def explore(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _index && _type "#{Elasticsearch::API::Utils.__listify(_index)}/#{Elasticsearch::API::Utils.__listify(_type)}/_graph/explore" else "#{Elasticsearch::API::Utils.__listify(_index)}/_graph/explore" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:explore, [ :routing, :timeout ].freeze) end end end end end params_registry.rb000066400000000000000000000040401462737751600370350ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/graph# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Graph module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end index_lifecycle_management/000077500000000000000000000000001462737751600375205ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actionsdelete_lifecycle.rb000066400000000000000000000035341462737751600433330ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Deletes the specified lifecycle policy definition. A currently used policy cannot be deleted. # # @option arguments [String] :policy The name of the index lifecycle policy # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ilm-delete-lifecycle.html # def delete_lifecycle(arguments = {}) raise ArgumentError, "Required argument 'policy' missing" unless arguments[:policy] headers = arguments.delete(:headers) || {} arguments = arguments.clone _policy = arguments.delete(:policy) method = Elasticsearch::API::HTTP_DELETE path = "_ilm/policy/#{Elasticsearch::API::Utils.__listify(_policy)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end delete_policy.rb000066400000000000000000000043121462737751600426660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Deletes a lifecycle policy # # @option arguments [String] :policy_id Identifier for the policy # @option arguments [Time] :master_timeout Specifies the period of time to wait for a connection to the master node # @option arguments [Time] :timeout Specifies the period of time to wait for a response. # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/ilm-delete-lifecycle.html # def delete_policy(arguments = {}) raise ArgumentError, "Required argument 'policy_id' missing" unless arguments[:policy_id] method = Elasticsearch::API::HTTP_DELETE path = Elasticsearch::API::Utils.__pathify "_ilm/policy", Elasticsearch::API::Utils.__escape(arguments[:policy_id]) params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body).body end # Register this action with its valid params when the module is loaded. # ParamsRegistry.register(:delete_policy, [:master_timeout, :timeout].freeze) end end end end end explain.rb000066400000000000000000000042451462737751600415120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Shows an index’s current lifecycle status # # @option arguments [String] :index The target index (*Required*) # @option arguments [Time] :master_timeout Specifies the period of time to wait for a connection to the master node # @option arguments [Time] :timeout Specifies the period of time to wait for a response. # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/ilm-explain-lifecycle.html # def explain(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] index = Elasticsearch::API::Utils.__escape(arguments.delete(:index)) method = Elasticsearch::API::HTTP_GET path = Elasticsearch::API::Utils.__pathify index, "_ilm/explain" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body).body end # Register this action with its valid params when the module is loaded. # ParamsRegistry.register(:explain, [:master_timeout, :timeout].freeze) end end end end end explain_lifecycle.rb000066400000000000000000000047231462737751600435320ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Retrieves information about the index's current lifecycle state, such as the currently executing phase, action, and step. # # @option arguments [String] :index The name of the index to explain # @option arguments [Boolean] :only_managed filters the indices included in the response to ones managed by ILM # @option arguments [Boolean] :only_errors filters the indices included in the response to ones in an ILM error state, implies only_managed # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ilm-explain-lifecycle.html # def explain_lifecycle(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = "#{Elasticsearch::API::Utils.__listify(_index)}/_ilm/explain" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:explain_lifecycle, [ :only_managed, :only_errors ].freeze) end end end end end get_lifecycle.rb000066400000000000000000000035531462737751600426510ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Returns the specified policy definition. Includes the policy version and last modified date. # # @option arguments [String] :policy The name of the index lifecycle policy # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ilm-get-lifecycle.html # def get_lifecycle(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _policy = arguments.delete(:policy) method = Elasticsearch::API::HTTP_GET path = if _policy "_ilm/policy/#{Elasticsearch::API::Utils.__listify(_policy)}" else "_ilm/policy" end params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_policy.rb000066400000000000000000000041261462737751600422060ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Retrieves a lifecycle policy # # @option arguments [String] :policy_id Identifier for the policy # @option arguments [Time] :master_timeout Specifies the period of time to wait for a connection to the master node # @option arguments [Time] :timeout Specifies the period of time to wait for a response. # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/ilm-get-lifecycle.html # def get_policy(arguments = {}) method = Elasticsearch::API::HTTP_GET path = Elasticsearch::API::Utils.__pathify "_ilm/policy", Elasticsearch::API::Utils.__escape(arguments[:policy_id]) params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body).body end # Register this action with its valid params when the module is loaded. # ParamsRegistry.register(:get_policy, [:master_timeout, :timeout].freeze) end end end end end get_status.rb000066400000000000000000000030261462737751600422300ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Retrieves the current index lifecycle management (ILM) status. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ilm-get-status.html # def get_status(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_ilm/status" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end migrate_to_data_tiers.rb000066400000000000000000000045011462737751600443760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Migrates the indices and ILM policies away from custom node attribute allocation routing to data tiers routing # # @option arguments [Boolean] :dry_run If set to true it will simulate the migration, providing a way to retrieve the ILM policies and indices that need to be migrated. The default is false # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Optionally specify a legacy index template name to delete and optionally specify a node attribute name used for index shard routing (defaults to "data") # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ilm-migrate-to-data-tiers.html # def migrate_to_data_tiers(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_ilm/migrate_to_data_tiers" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:migrate_to_data_tiers, [ :dry_run ].freeze) end end end end end move_to_step.rb000066400000000000000000000036371462737751600425610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Manually moves an index into the specified step and executes that step. # # @option arguments [String] :index The name of the index whose lifecycle step is to change # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The new lifecycle step to move to # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ilm-move-to-step.html # def move_to_step(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = "_ilm/move/#{Elasticsearch::API::Utils.__listify(_index)}" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040631462737751600432630ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end put_lifecycle.rb000066400000000000000000000035641462737751600427040ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Creates a lifecycle policy # # @option arguments [String] :policy The name of the index lifecycle policy # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The lifecycle policy definition to register # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ilm-put-lifecycle.html # def put_lifecycle(arguments = {}) raise ArgumentError, "Required argument 'policy' missing" unless arguments[:policy] headers = arguments.delete(:headers) || {} arguments = arguments.clone _policy = arguments.delete(:policy) method = Elasticsearch::API::HTTP_PUT path = "_ilm/policy/#{Elasticsearch::API::Utils.__listify(_policy)}" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end put_policy.rb000066400000000000000000000046131462737751600422400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Register a new watch in or update an existing one # # @option arguments [String] :policy_id Identifier for the policy (*Required*) # @option arguments [Hash] :body The policy (*Required*) # @option arguments [Time] :master_timeout Specifies the period of time to wait for a connection to the master node # @option arguments [Time] :timeout Specifies the period of time to wait for a response. # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/ilm-put-lifecycle.html # def put_policy(arguments = {}) raise ArgumentError, "Required argument 'policy_id' missing" unless arguments[:policy_id] raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] method = Elasticsearch::API::HTTP_PUT path = Elasticsearch::API::Utils.__pathify "_ilm/policy", Elasticsearch::API::Utils.__escape(arguments[:policy_id]) params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body).body end # Register this action with its valid params when the module is loaded. # ParamsRegistry.register(:put_policy, [:master_timeout, :timeout].freeze) end end end end end remove_policy.rb000066400000000000000000000035001462737751600427170ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Removes the assigned lifecycle policy and stops managing the specified index # # @option arguments [String] :index The name of the index to remove policy on # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ilm-remove-policy.html # def remove_policy(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = "#{Elasticsearch::API::Utils.__listify(_index)}/_ilm/remove" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end retry.rb000066400000000000000000000035311462737751600412140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Retries executing the policy for an index that is in the ERROR step. # # @option arguments [String] :index The name of the indices (comma-separated) whose failed lifecycle step is to be retry # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ilm-retry-policy.html # def retry(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = "#{Elasticsearch::API::Utils.__listify(_index)}/_ilm/retry" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end retry_policy.rb000066400000000000000000000043011462737751600425670ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Retry executing the policy for an index that is in the ERROR step # # @option arguments [String] :index The target index (*Required*) # @option arguments [Time] :master_timeout Specifies the period of time to wait for a connection to the master node # @option arguments [Time] :timeout Specifies the period of time to wait for a response. # # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/ilm-move-to-step.html # def retry_policy(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] method = Elasticsearch::API::HTTP_POST index = Elasticsearch::API::Utils.__escape(arguments.delete(:index)) path = Elasticsearch::API::Utils.__pathify index, "_ilm/retry" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body).body end # Register this action with its valid params when the module is loaded. # ParamsRegistry.register(:retry_policy, [:master_timeout, :timeout].freeze) end end end end end start.rb000066400000000000000000000030001462737751600411730ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Start the index lifecycle management (ILM) plugin. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ilm-start.html # def start(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_ilm/start" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end stop.rb000066400000000000000000000030521462737751600410320ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions # Halts all lifecycle management operations and stops the index lifecycle management (ILM) plugin # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ilm-stop.html # def stop(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_ilm/stop" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/indices/000077500000000000000000000000001462737751600336735ustar00rootroot00000000000000create_data_stream.rb000066400000000000000000000033441462737751600377540ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Indices module Actions # Creates a data stream # # @option arguments [String] :name The name of the data stream # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/data-streams.html # def create_data_stream(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_PUT path = "_data_stream/#{Elasticsearch::API::Utils.__listify(_name)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end data_streams_stats.rb000066400000000000000000000036151462737751600400330ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Indices module Actions # Provides statistics on operations happening in a data stream. # # @option arguments [List] :name A comma-separated list of data stream names; use `_all` or empty string to perform the operation on all data streams # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/data-streams.html # def data_streams_stats(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = if _name "_data_stream/#{Elasticsearch::API::Utils.__listify(_name)}/_stats" else "_data_stream/_stats" end params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end delete_data_stream.rb000066400000000000000000000044401462737751600377510ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Indices module Actions # Deletes a data stream. # # @option arguments [List] :name A comma-separated list of data streams to delete; use `*` to delete all data streams # @option arguments [String] :expand_wildcards Whether wildcard expressions should get expanded to open or closed indices (default: open) (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/data-streams.html # def delete_data_stream(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_DELETE path = "_data_stream/#{Elasticsearch::API::Utils.__listify(_name)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_data_stream, [ :expand_wildcards ].freeze) end end end end end freeze.rb000066400000000000000000000066051462737751600354300ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Indices module Actions # Freezes an index. A frozen index has almost no overhead on the cluster (except for maintaining its metadata in memory) and is read-only. # # @option arguments [String] :index The name of the index to freeze # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [String] :wait_for_active_shards Sets the number of active shards to wait for before the operation returns. # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # Frozen indices are deprecated because they provide no benefit given improvements in heap memory utilization. They will be removed in a future release. # Deprecated since version 7.14.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/freeze-index-api.html # def freeze(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = "#{Elasticsearch::API::Utils.__listify(_index)}/_freeze" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:freeze, [ :timeout, :master_timeout, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :wait_for_active_shards ].freeze) end end end end end get_data_stream.rb000066400000000000000000000044541462737751600372730ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Indices module Actions # Returns data streams. # # @option arguments [List] :name A comma-separated list of data streams to get; use `*` to get all data streams # @option arguments [String] :expand_wildcards Whether wildcard expressions should get expanded to open or closed indices (default: open) (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/data-streams.html # def get_data_stream(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = if _name "_data_stream/#{Elasticsearch::API::Utils.__listify(_name)}" else "_data_stream" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_data_stream, [ :expand_wildcards ].freeze) end end end end end migrate_to_data_stream.rb000066400000000000000000000034041462737751600406400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Indices module Actions # Migrates an alias to a data stream # # @option arguments [String] :name The name of the alias to migrate # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/data-streams.html # def migrate_to_data_stream(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_POST path = "_data_stream/_migrate/#{Elasticsearch::API::Utils.__listify(_name)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end modify_data_stream.rb000066400000000000000000000032551462737751600400010ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Indices module Actions # Modifies a data stream # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The data stream modifications (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/data-streams.html # def modify_data_stream(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_data_stream/_modify" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040421462737751600373540ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Indices module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end promote_data_stream.rb000066400000000000000000000034661462737751600402030ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Indices module Actions # Promotes a data stream from a replicated data stream managed by CCR to a regular data stream # # @option arguments [String] :name The name of the data stream # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/data-streams.html # def promote_data_stream(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_POST path = "_data_stream/_promote/#{Elasticsearch::API::Utils.__listify(_name)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end reload_search_analyzers.rb000066400000000000000000000053711462737751600410320ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Indices module Actions # Reloads an index's search analyzers and their resources. # # @option arguments [List] :index A comma-separated list of index names to reload analyzers for # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-reload-analyzers.html # def reload_search_analyzers(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = "#{Elasticsearch::API::Utils.__listify(_index)}/_reload_search_analyzers" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:reload_search_analyzers, [ :ignore_unavailable, :allow_no_indices, :expand_wildcards ].freeze) end end end end end unfreeze.rb000066400000000000000000000066131462737751600357720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Indices module Actions # Unfreezes an index. When a frozen index is unfrozen, the index goes through the normal recovery process and becomes writeable again. # # @option arguments [String] :index The name of the index to unfreeze # @option arguments [Time] :timeout Explicit operation timeout # @option arguments [Time] :master_timeout Specify timeout for connection to master # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all) # @option arguments [String] :wait_for_active_shards Sets the number of active shards to wait for before the operation returns. # @option arguments [Hash] :headers Custom HTTP headers # # *Deprecation notice*: # Frozen indices are deprecated because they provide no benefit given improvements in heap memory utilization. They will be removed in a future release. # Deprecated since version 7.14.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/unfreeze-index-api.html # def unfreeze(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = "#{Elasticsearch::API::Utils.__listify(_index)}/_unfreeze" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:unfreeze, [ :timeout, :master_timeout, :ignore_unavailable, :allow_no_indices, :expand_wildcards, :wait_for_active_shards ].freeze) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/info.rb000066400000000000000000000040111462737751600335310ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Actions # Retrieves information about the installed X-Pack features. # # @option arguments [List] :categories Comma-separated list of info categories. Can be any of: build, license, features # @option arguments [Boolean] :accept_enterprise If an enterprise license is installed, return the type and mode as 'enterprise' (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/info-api.html # def info(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_xpack" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:info, [ :categories, :accept_enterprise ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/license/000077500000000000000000000000001462737751600336775ustar00rootroot00000000000000delete.rb000066400000000000000000000027601462737751600354140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/license# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module License module Actions # Deletes licensing information for the cluster # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/delete-license.html # def delete(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_DELETE path = "_license" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get.rb000066400000000000000000000041161462737751600347260ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/license# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module License module Actions # Retrieves licensing information for the cluster # # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false) # @option arguments [Boolean] :accept_enterprise If the active license is an enterprise license, return type as 'enterprise' (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-license.html # def get(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_license" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get, [ :local, :accept_enterprise ].freeze) end end end end end get_basic_status.rb000066400000000000000000000030251462737751600374700ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/license# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module License module Actions # Retrieves information about the status of the basic license. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-basic-status.html # def get_basic_status(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_license/basic_status" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_trial_status.rb000066400000000000000000000030251462737751600375220ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/license# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module License module Actions # Retrieves information about the status of the trial license. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-trial-status.html # def get_trial_status(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_license/trial_status" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040421462737751600373600ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/license# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module License module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end post.rb000066400000000000000000000037371462737751600351440ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/license# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module License module Actions # Updates the license for the cluster. # # @option arguments [Boolean] :acknowledge whether the user has acknowledged acknowledge messages (default: false) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body licenses to be installed # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/update-license.html # def post(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_PUT path = "_license" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:post, [ :acknowledge ].freeze) end end end end end post_start_basic.rb000066400000000000000000000036571462737751600375230ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/license# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module License module Actions # Starts an indefinite basic license. # # @option arguments [Boolean] :acknowledge whether the user has acknowledged acknowledge messages (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/start-basic.html # def post_start_basic(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_license/start_basic" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:post_start_basic, [ :acknowledge ].freeze) end end end end end post_start_trial.rb000066400000000000000000000040511462737751600375420ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/license# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module License module Actions # starts a limited time trial license. # # @option arguments [String] :type The type of trial license to generate (default: "trial") # @option arguments [Boolean] :acknowledge whether the user has acknowledged acknowledge messages (default: false) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/start-trial.html # def post_start_trial(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_license/start_trial" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:post_start_trial, [ :type, :acknowledge ].freeze) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/logstash/000077500000000000000000000000001462737751600341015ustar00rootroot00000000000000delete_pipeline.rb000066400000000000000000000034121462737751600374760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/logstash# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Logstash module Actions # Deletes Logstash Pipelines used by Central Management # # @option arguments [String] :id The ID of the Pipeline # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/logstash-api-delete-pipeline.html # def delete_pipeline(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_DELETE path = "_logstash/pipeline/#{Elasticsearch::API::Utils.__listify(_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_pipeline.rb000066400000000000000000000034231462737751600370150ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/logstash# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Logstash module Actions # Retrieves Logstash Pipelines used by Central Management # # @option arguments [String] :id A comma-separated list of Pipeline IDs # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/logstash-api-get-pipeline.html # def get_pipeline(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = "_logstash/pipeline/#{Elasticsearch::API::Utils.__listify(_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end put_pipeline.rb000066400000000000000000000037121462737751600370470ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/logstash# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Logstash module Actions # Adds and updates Logstash Pipelines used for Central Management # # @option arguments [String] :id The ID of the Pipeline # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The Pipeline to add or update (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/logstash-api-put-pipeline.html # def put_pipeline(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_PUT path = "_logstash/pipeline/#{Elasticsearch::API::Utils.__listify(_id)}" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end machine_learning/000077500000000000000000000000001462737751600354615ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actionsclose_job.rb000066400000000000000000000056071462737751600377550ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Closes one or more anomaly detection jobs. A job can be opened and closed multiple times throughout its lifecycle. # # @option arguments [String] :job_id The name of the job to close # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no jobs. (This includes `_all` string or when no jobs have been specified) # @option arguments [Boolean] :allow_no_jobs Whether to ignore if a wildcard expression matches no jobs. (This includes `_all` string or when no jobs have been specified) *Deprecated* # @option arguments [Boolean] :force True if the job should be forcefully closed # @option arguments [Time] :timeout Controls the time to wait until a job has closed. Default to 30 minutes # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The URL params optionally sent in the body # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-close-job.html # def close_job(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_POST path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/_close" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:close_job, [ :allow_no_match, :allow_no_jobs, :force, :timeout ].freeze) end end end end end delete_calendar.rb000066400000000000000000000034401462737751600411020ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Deletes a calendar. # # @option arguments [String] :calendar_id The ID of the calendar to delete # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-delete-calendar.html # def delete_calendar(arguments = {}) raise ArgumentError, "Required argument 'calendar_id' missing" unless arguments[:calendar_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _calendar_id = arguments.delete(:calendar_id) method = Elasticsearch::API::HTTP_DELETE path = "_ml/calendars/#{Elasticsearch::API::Utils.__listify(_calendar_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end delete_calendar_event.rb000066400000000000000000000041651462737751600423100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Deletes scheduled events from a calendar. # # @option arguments [String] :calendar_id The ID of the calendar to modify # @option arguments [String] :event_id The ID of the event to remove from the calendar # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-delete-calendar-event.html # def delete_calendar_event(arguments = {}) raise ArgumentError, "Required argument 'calendar_id' missing" unless arguments[:calendar_id] raise ArgumentError, "Required argument 'event_id' missing" unless arguments[:event_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _calendar_id = arguments.delete(:calendar_id) _event_id = arguments.delete(:event_id) method = Elasticsearch::API::HTTP_DELETE path = "_ml/calendars/#{Elasticsearch::API::Utils.__listify(_calendar_id)}/events/#{Elasticsearch::API::Utils.__listify(_event_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end delete_calendar_job.rb000066400000000000000000000041471462737751600417410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Deletes anomaly detection jobs from a calendar. # # @option arguments [String] :calendar_id The ID of the calendar to modify # @option arguments [String] :job_id The ID of the job to remove from the calendar # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-delete-calendar-job.html # def delete_calendar_job(arguments = {}) raise ArgumentError, "Required argument 'calendar_id' missing" unless arguments[:calendar_id] raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _calendar_id = arguments.delete(:calendar_id) _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_DELETE path = "_ml/calendars/#{Elasticsearch::API::Utils.__listify(_calendar_id)}/jobs/#{Elasticsearch::API::Utils.__listify(_job_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end delete_data_frame_analytics.rb000066400000000000000000000045161462737751600434700ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Deletes an existing data frame analytics job. # # @option arguments [String] :id The ID of the data frame analytics to delete # @option arguments [Boolean] :force True if the job should be forcefully deleted # @option arguments [Time] :timeout Controls the time to wait until a job is deleted. Defaults to 1 minute # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/delete-dfanalytics.html # def delete_data_frame_analytics(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_DELETE path = "_ml/data_frame/analytics/#{Elasticsearch::API::Utils.__listify(_id)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_data_frame_analytics, [ :force, :timeout ].freeze) end end end end end delete_datafeed.rb000066400000000000000000000042771462737751600410770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Deletes an existing datafeed. # # @option arguments [String] :datafeed_id The ID of the datafeed to delete # @option arguments [Boolean] :force True if the datafeed should be forcefully deleted # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-delete-datafeed.html # def delete_datafeed(arguments = {}) raise ArgumentError, "Required argument 'datafeed_id' missing" unless arguments[:datafeed_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _datafeed_id = arguments.delete(:datafeed_id) method = Elasticsearch::API::HTTP_DELETE path = "_ml/datafeeds/#{Elasticsearch::API::Utils.__listify(_datafeed_id)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_datafeed, [ :force ].freeze) end end end end end delete_expired_data.rb000066400000000000000000000050251462737751600417630ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Deletes expired and unused machine learning data. # # @option arguments [String] :job_id The ID of the job(s) to perform expired data hygiene for # @option arguments [Number] :requests_per_second The desired requests per second for the deletion processes. # @option arguments [Time] :timeout How long can the underlying delete processes run until they are canceled # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body deleting expired data parameters # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-delete-expired-data.html # def delete_expired_data(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_DELETE path = if _job_id "_ml/_delete_expired_data/#{Elasticsearch::API::Utils.__listify(_job_id)}" else "_ml/_delete_expired_data" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_expired_data, [ :requests_per_second, :timeout ].freeze) end end end end end delete_filter.rb000066400000000000000000000034121462737751600406150ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Deletes a filter. # # @option arguments [String] :filter_id The ID of the filter to delete # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-delete-filter.html # def delete_filter(arguments = {}) raise ArgumentError, "Required argument 'filter_id' missing" unless arguments[:filter_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _filter_id = arguments.delete(:filter_id) method = Elasticsearch::API::HTTP_DELETE path = "_ml/filters/#{Elasticsearch::API::Utils.__listify(_filter_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end delete_forecast.rb000066400000000000000000000055221462737751600411420ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Deletes forecasts from a machine learning job. # # @option arguments [String] :job_id The ID of the job from which to delete forecasts # @option arguments [String] :forecast_id The ID of the forecast to delete, can be comma delimited list. Leaving blank implies `_all` # @option arguments [Boolean] :allow_no_forecasts Whether to ignore if `_all` matches no forecasts # @option arguments [Time] :timeout Controls the time to wait until the forecast(s) are deleted. Default to 30 seconds # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-delete-forecast.html # def delete_forecast(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) _forecast_id = arguments.delete(:forecast_id) method = Elasticsearch::API::HTTP_DELETE path = if _job_id && _forecast_id "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/_forecast/#{Elasticsearch::API::Utils.__listify(_forecast_id)}" else "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/_forecast" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_forecast, [ :allow_no_forecasts, :timeout ].freeze) end end end end end delete_job.rb000066400000000000000000000045101462737751600401020ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Deletes an existing anomaly detection job. # # @option arguments [String] :job_id The ID of the job to delete # @option arguments [Boolean] :force True if the job should be forcefully deleted # @option arguments [Boolean] :wait_for_completion Should this request wait until the operation has completed before returning # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-delete-job.html # def delete_job(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_DELETE path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_job, [ :force, :wait_for_completion ].freeze) end end end end end delete_model_snapshot.rb000066400000000000000000000041311462737751600423460ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Deletes an existing model snapshot. # # @option arguments [String] :job_id The ID of the job to fetch # @option arguments [String] :snapshot_id The ID of the snapshot to delete # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-delete-snapshot.html # def delete_model_snapshot(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] raise ArgumentError, "Required argument 'snapshot_id' missing" unless arguments[:snapshot_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) _snapshot_id = arguments.delete(:snapshot_id) method = Elasticsearch::API::HTTP_DELETE path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/model_snapshots/#{Elasticsearch::API::Utils.__listify(_snapshot_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end delete_trained_model.rb000066400000000000000000000035601462737751600421420ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Deletes an existing trained inference model that is currently not referenced by an ingest pipeline. # # @option arguments [String] :model_id The ID of the trained model to delete # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/delete-trained-models.html # def delete_trained_model(arguments = {}) raise ArgumentError, "Required argument 'model_id' missing" unless arguments[:model_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _model_id = arguments.delete(:model_id) method = Elasticsearch::API::HTTP_DELETE path = "_ml/trained_models/#{Elasticsearch::API::Utils.__listify(_model_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end delete_trained_model_alias.rb000066400000000000000000000042351462737751600433130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Deletes a model alias that refers to the trained model # # @option arguments [String] :model_alias The trained model alias to delete # @option arguments [String] :model_id The trained model where the model alias is assigned # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/delete-trained-models-aliases.html # def delete_trained_model_alias(arguments = {}) raise ArgumentError, "Required argument 'model_id' missing" unless arguments[:model_id] raise ArgumentError, "Required argument 'model_alias' missing" unless arguments[:model_alias] headers = arguments.delete(:headers) || {} arguments = arguments.clone _model_alias = arguments.delete(:model_alias) _model_id = arguments.delete(:model_id) method = Elasticsearch::API::HTTP_DELETE path = "_ml/trained_models/#{Elasticsearch::API::Utils.__listify(_model_id)}/model_aliases/#{Elasticsearch::API::Utils.__listify(_model_alias)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end estimate_memory_usage.rb000066400000000000000000000031341462737751600423760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # TODO: Description # @option arguments [Hash] :body Memory usage estimation definition (*Required*) # # @see http://www.elastic.co/guide/en/elasticsearch/reference/current/estimate-memory-usage-dfanalytics.html # def estimate_memory_usage(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_ml/data_frame/analytics/_estimate_memory_usage" params = {} body = arguments[:body] perform_request(method, path, params, body).body end end end end end end estimate_model_memory.rb000066400000000000000000000033721462737751600423760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Estimates the model memory # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The analysis config, plus cardinality estimates for fields it references (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-apis.html # def estimate_model_memory(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_ml/anomaly_detectors/_estimate_model_memory" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end evaluate_data_frame.rb000066400000000000000000000033421462737751600417610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Evaluates the data frame analytics for an annotated index. # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The evaluation definition (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/evaluate-dfanalytics.html # def evaluate_data_frame(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_ml/data_frame/_evaluate" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end explain_data_frame_analytics.rb000066400000000000000000000041231462737751600436600ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Explains a data frame analytics config. # # @option arguments [String] :id The ID of the data frame analytics to explain # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The data frame analytics config to explain # # @see http://www.elastic.co/guide/en/elasticsearch/reference/7.17/explain-dfanalytics.html # def explain_data_frame_analytics(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _id "_ml/data_frame/analytics/#{Elasticsearch::API::Utils.__listify(_id)}/_explain" else "_ml/data_frame/analytics/_explain" end params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end find_file_structure.rb000066400000000000000000000116661462737751600420570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Finds the structure of a text file. The text file must contain data that is suitable to be ingested into Elasticsearch. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [Integer] :lines_to_sample How many lines of the file should be included in the analysis # @option arguments [Integer] :line_merge_size_limit Maximum number of characters permitted in a single message when lines are merged to create messages. # @option arguments [Time] :timeout Timeout after which the analysis will be aborted # @option arguments [String] :charset Optional parameter to specify the character set of the file # @option arguments [String] :format Optional parameter to specify the high level file format (options: ndjson, xml, delimited, semi_structured_text) # @option arguments [Boolean] :has_header_row Optional parameter to specify whether a delimited file includes the column names in its first row # @option arguments [List] :column_names Optional parameter containing a comma separated list of the column names for a delimited file # @option arguments [String] :delimiter Optional parameter to specify the delimiter character for a delimited file - must be a single character # @option arguments [String] :quote Optional parameter to specify the quote character for a delimited file - must be a single character # @option arguments [Boolean] :should_trim_fields Optional parameter to specify whether the values between delimiters in a delimited file should have whitespace trimmed from them # @option arguments [String] :grok_pattern Optional parameter to specify the Grok pattern that should be used to extract fields from messages in a semi-structured text file # @option arguments [String] :timestamp_field Optional parameter to specify the timestamp field in the file # @option arguments [String] :timestamp_format Optional parameter to specify the timestamp format in the file - may be either a Joda or Java time format # @option arguments [Boolean] :explain Whether to include a commentary on how the structure was derived # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The contents of the file to be analyzed (*Required*) # # *Deprecation notice*: # This endpoint has changed to _text_structure/find_structure, please use that API instead # Deprecated since version 7.12.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/find-structure.html # def find_file_structure(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_ml/find_file_structure" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = Elasticsearch::API::Utils.__bulkify(arguments.delete(:body)) perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:find_file_structure, [ :lines_to_sample, :line_merge_size_limit, :timeout, :charset, :format, :has_header_row, :column_names, :delimiter, :quote, :should_trim_fields, :grok_pattern, :timestamp_field, :timestamp_format, :explain ].freeze) end end end end end flush_job.rb000066400000000000000000000057741462737751600377760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Forces any buffered data to be processed by the job. # # @option arguments [String] :job_id The name of the job to flush # @option arguments [Boolean] :calc_interim Calculates interim results for the most recent bucket or all buckets within the latency period # @option arguments [String] :start When used in conjunction with calc_interim, specifies the range of buckets on which to calculate interim results # @option arguments [String] :end When used in conjunction with calc_interim, specifies the range of buckets on which to calculate interim results # @option arguments [String] :advance_time Advances time to the given value generating results and updating the model for the advanced interval # @option arguments [String] :skip_time Skips time to the given value without generating results or updating the model for the skipped interval # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Flush parameters # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-flush-job.html # def flush_job(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_POST path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/_flush" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:flush_job, [ :calc_interim, :start, :end, :advance_time, :skip_time ].freeze) end end end end end forecast.rb000066400000000000000000000051661462737751600376240ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Predicts the future behavior of a time series by using its historical behavior. # # @option arguments [String] :job_id The ID of the job to forecast for # @option arguments [Time] :duration The duration of the forecast # @option arguments [Time] :expires_in The time interval after which the forecast expires. Expired forecasts will be deleted at the first opportunity. # @option arguments [String] :max_model_memory The max memory able to be used by the forecast. Default is 20mb. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Query parameters can be specified in the body # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-forecast.html # def forecast(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_POST path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/_forecast" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:forecast, [ :duration, :expires_in, :max_model_memory ].freeze) end end end end end get_buckets.rb000066400000000000000000000071571462737751600403170ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves anomaly detection job results for one or more buckets. # # @option arguments [String] :job_id ID of the job to get bucket results from # @option arguments [String] :timestamp The timestamp of the desired single bucket result # @option arguments [Boolean] :expand Include anomaly records # @option arguments [Boolean] :exclude_interim Exclude interim results # @option arguments [Integer] :from skips a number of buckets # @option arguments [Integer] :size specifies a max number of buckets to get # @option arguments [String] :start Start time filter for buckets # @option arguments [String] :end End time filter for buckets # @option arguments [Double] :anomaly_score Filter for the most anomalous buckets # @option arguments [String] :sort Sort buckets by a particular field # @option arguments [Boolean] :desc Set the sort direction # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Bucket selection details if not provided in URI # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-get-bucket.html # def get_buckets(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) _timestamp = arguments.delete(:timestamp) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _job_id && _timestamp "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/results/buckets/#{Elasticsearch::API::Utils.__listify(_timestamp)}" else "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/results/buckets" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_buckets, [ :expand, :exclude_interim, :from, :size, :start, :end, :anomaly_score, :sort, :desc ].freeze) end end end end end get_calendar_events.rb000066400000000000000000000052161462737751600420060ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves information about the scheduled events in calendars. # # @option arguments [String] :calendar_id The ID of the calendar containing the events # @option arguments [String] :job_id Get events for the job. When this option is used calendar_id must be '_all' # @option arguments [String] :start Get events after this time # @option arguments [Date] :end Get events before this time # @option arguments [Integer] :from Skips a number of events # @option arguments [Integer] :size Specifies a max number of events to get # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-get-calendar-event.html # def get_calendar_events(arguments = {}) raise ArgumentError, "Required argument 'calendar_id' missing" unless arguments[:calendar_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _calendar_id = arguments.delete(:calendar_id) method = Elasticsearch::API::HTTP_GET path = "_ml/calendars/#{Elasticsearch::API::Utils.__listify(_calendar_id)}/events" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_calendar_events, [ :job_id, :start, :end, :from, :size ].freeze) end end end end end get_calendars.rb000066400000000000000000000050561462737751600406070ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves configuration information for calendars. # # @option arguments [String] :calendar_id The ID of the calendar to fetch # @option arguments [Integer] :from skips a number of calendars # @option arguments [Integer] :size specifies a max number of calendars to get # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The from and size parameters optionally sent in the body # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-get-calendar.html # def get_calendars(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _calendar_id = arguments.delete(:calendar_id) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _calendar_id "_ml/calendars/#{Elasticsearch::API::Utils.__listify(_calendar_id)}" else "_ml/calendars" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_calendars, [ :from, :size ].freeze) end end end end end get_categories.rb000066400000000000000000000063001462737751600407710ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves anomaly detection job results for one or more categories. # # @option arguments [String] :job_id The name of the job # @option arguments [Long] :category_id The identifier of the category definition of interest # @option arguments [Integer] :from skips a number of categories # @option arguments [Integer] :size specifies a max number of categories to get # @option arguments [String] :partition_field_value Specifies the partition to retrieve categories for. This is optional, and should never be used for jobs where per-partition categorization is disabled. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Category selection details if not provided in URI # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-get-category.html # def get_categories(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) _category_id = arguments.delete(:category_id) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _job_id && _category_id "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/results/categories/#{Elasticsearch::API::Utils.__listify(_category_id)}" else "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/results/categories" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_categories, [ :from, :size, :partition_field_value ].freeze) end end end end end get_data_frame_analytics.rb000066400000000000000000000053351462737751600430050ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves configuration information for data frame analytics jobs. # # @option arguments [String] :id The ID of the data frame analytics to fetch # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no data frame analytics. (This includes `_all` string or when no data frame analytics have been specified) # @option arguments [Integer] :from skips a number of analytics # @option arguments [Integer] :size specifies a max number of analytics to get # @option arguments [Boolean] :exclude_generated Omits fields that are illegal to set on data frame analytics PUT # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-dfanalytics.html # def get_data_frame_analytics(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = if _id "_ml/data_frame/analytics/#{Elasticsearch::API::Utils.__listify(_id)}" else "_ml/data_frame/analytics" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_data_frame_analytics, [ :allow_no_match, :from, :size, :exclude_generated ].freeze) end end end end end get_data_frame_analytics_stats.rb000066400000000000000000000053231462737751600442200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves usage information for data frame analytics jobs. # # @option arguments [String] :id The ID of the data frame analytics stats to fetch # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no data frame analytics. (This includes `_all` string or when no data frame analytics have been specified) # @option arguments [Integer] :from skips a number of analytics # @option arguments [Integer] :size specifies a max number of analytics to get # @option arguments [Boolean] :verbose whether the stats response should be verbose # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-dfanalytics-stats.html # def get_data_frame_analytics_stats(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = if _id "_ml/data_frame/analytics/#{Elasticsearch::API::Utils.__listify(_id)}/_stats" else "_ml/data_frame/analytics/_stats" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_data_frame_analytics_stats, [ :allow_no_match, :from, :size, :verbose ].freeze) end end end end end get_datafeed_stats.rb000066400000000000000000000051261462737751600416240ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves usage information for datafeeds. # # @option arguments [String] :datafeed_id The ID of the datafeeds stats to fetch # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no datafeeds. (This includes `_all` string or when no datafeeds have been specified) # @option arguments [Boolean] :allow_no_datafeeds Whether to ignore if a wildcard expression matches no datafeeds. (This includes `_all` string or when no datafeeds have been specified) *Deprecated* # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-get-datafeed-stats.html # def get_datafeed_stats(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _datafeed_id = arguments.delete(:datafeed_id) method = Elasticsearch::API::HTTP_GET path = if _datafeed_id "_ml/datafeeds/#{Elasticsearch::API::Utils.__listify(_datafeed_id)}/_stats" else "_ml/datafeeds/_stats" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_datafeed_stats, [ :allow_no_match, :allow_no_datafeeds ].freeze) end end end end end get_datafeeds.rb000066400000000000000000000053121462737751600405660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves configuration information for datafeeds. # # @option arguments [String] :datafeed_id The ID of the datafeeds to fetch # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no datafeeds. (This includes `_all` string or when no datafeeds have been specified) # @option arguments [Boolean] :allow_no_datafeeds Whether to ignore if a wildcard expression matches no datafeeds. (This includes `_all` string or when no datafeeds have been specified) *Deprecated* # @option arguments [Boolean] :exclude_generated Omits fields that are illegal to set on datafeed PUT # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-get-datafeed.html # def get_datafeeds(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _datafeed_id = arguments.delete(:datafeed_id) method = Elasticsearch::API::HTTP_GET path = if _datafeed_id "_ml/datafeeds/#{Elasticsearch::API::Utils.__listify(_datafeed_id)}" else "_ml/datafeeds" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_datafeeds, [ :allow_no_match, :allow_no_datafeeds, :exclude_generated ].freeze) end end end end end get_filters.rb000066400000000000000000000043711462737751600403220ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves filters. # # @option arguments [String] :filter_id The ID of the filter to fetch # @option arguments [Integer] :from skips a number of filters # @option arguments [Integer] :size specifies a max number of filters to get # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-get-filter.html # def get_filters(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _filter_id = arguments.delete(:filter_id) method = Elasticsearch::API::HTTP_GET path = if _filter_id "_ml/filters/#{Elasticsearch::API::Utils.__listify(_filter_id)}" else "_ml/filters" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_filters, [ :from, :size ].freeze) end end end end end get_influencers.rb000066400000000000000000000063441462737751600411710ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves anomaly detection job results for one or more influencers. # # @option arguments [String] :job_id Identifier for the anomaly detection job # @option arguments [Boolean] :exclude_interim Exclude interim results # @option arguments [Integer] :from skips a number of influencers # @option arguments [Integer] :size specifies a max number of influencers to get # @option arguments [String] :start start timestamp for the requested influencers # @option arguments [String] :end end timestamp for the requested influencers # @option arguments [Double] :influencer_score influencer score threshold for the requested influencers # @option arguments [String] :sort sort field for the requested influencers # @option arguments [Boolean] :desc whether the results should be sorted in decending order # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Influencer selection criteria # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-get-influencer.html # def get_influencers(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/results/influencers" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_influencers, [ :exclude_interim, :from, :size, :start, :end, :influencer_score, :sort, :desc ].freeze) end end end end end get_job_stats.rb000066400000000000000000000050501462737751600406350ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves usage information for anomaly detection jobs. # # @option arguments [String] :job_id The ID of the jobs stats to fetch # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no jobs. (This includes `_all` string or when no jobs have been specified) # @option arguments [Boolean] :allow_no_jobs Whether to ignore if a wildcard expression matches no jobs. (This includes `_all` string or when no jobs have been specified) *Deprecated* # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-get-job-stats.html # def get_job_stats(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_GET path = if _job_id "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/_stats" else "_ml/anomaly_detectors/_stats" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_job_stats, [ :allow_no_match, :allow_no_jobs ].freeze) end end end end end get_jobs.rb000066400000000000000000000052271462737751600376100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves configuration information for anomaly detection jobs. # # @option arguments [String] :job_id The ID of the jobs to fetch # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no jobs. (This includes `_all` string or when no jobs have been specified) # @option arguments [Boolean] :allow_no_jobs Whether to ignore if a wildcard expression matches no jobs. (This includes `_all` string or when no jobs have been specified) *Deprecated* # @option arguments [Boolean] :exclude_generated Omits fields that are illegal to set on job PUT # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-get-job.html # def get_jobs(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_GET path = if _job_id "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}" else "_ml/anomaly_detectors" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_jobs, [ :allow_no_match, :allow_no_jobs, :exclude_generated ].freeze) end end end end end get_model_snapshot_upgrade_stats.rb000066400000000000000000000053771462737751600446250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Gets stats for anomaly detection job model snapshot upgrades that are in progress. # # @option arguments [String] :job_id The ID of the job. May be a wildcard, comma separated list or `_all`. # @option arguments [String] :snapshot_id The ID of the snapshot. May be a wildcard, comma separated list or `_all`. # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no jobs or no snapshots. (This includes the `_all` string.) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-get-job-model-snapshot-upgrade-stats.html # def get_model_snapshot_upgrade_stats(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] raise ArgumentError, "Required argument 'snapshot_id' missing" unless arguments[:snapshot_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) _snapshot_id = arguments.delete(:snapshot_id) method = Elasticsearch::API::HTTP_GET path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/model_snapshots/#{Elasticsearch::API::Utils.__listify(_snapshot_id)}/_upgrade/_stats" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_model_snapshot_upgrade_stats, [ :allow_no_match ].freeze) end end end end end get_model_snapshots.rb000066400000000000000000000065011462737751600420510ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves information about model snapshots. # # @option arguments [String] :job_id The ID of the job to fetch # @option arguments [String] :snapshot_id The ID of the snapshot to fetch # @option arguments [Integer] :from Skips a number of documents # @option arguments [Integer] :size The default number of documents returned in queries as a string. # @option arguments [Date] :start The filter 'start' query parameter # @option arguments [Date] :end The filter 'end' query parameter # @option arguments [String] :sort Name of the field to sort on # @option arguments [Boolean] :desc True if the results should be sorted in descending order # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Model snapshot selection criteria # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-get-snapshot.html # def get_model_snapshots(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) _snapshot_id = arguments.delete(:snapshot_id) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _job_id && _snapshot_id "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/model_snapshots/#{Elasticsearch::API::Utils.__listify(_snapshot_id)}" else "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/model_snapshots" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_model_snapshots, [ :from, :size, :start, :end, :sort, :desc ].freeze) end end end end end get_overall_buckets.rb000066400000000000000000000072751462737751600420440ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves overall bucket results that summarize the bucket results of multiple anomaly detection jobs. # # @option arguments [String] :job_id The job IDs for which to calculate overall bucket results # @option arguments [Integer] :top_n The number of top job bucket scores to be used in the overall_score calculation # @option arguments [String] :bucket_span The span of the overall buckets. Defaults to the longest job bucket_span # @option arguments [Double] :overall_score Returns overall buckets with overall scores higher than this value # @option arguments [Boolean] :exclude_interim If true overall buckets that include interim buckets will be excluded # @option arguments [String] :start Returns overall buckets with timestamps after this time # @option arguments [String] :end Returns overall buckets with timestamps earlier than this time # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no jobs. (This includes `_all` string or when no jobs have been specified) # @option arguments [Boolean] :allow_no_jobs Whether to ignore if a wildcard expression matches no jobs. (This includes `_all` string or when no jobs have been specified) *Deprecated* # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Overall bucket selection details if not provided in URI # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-get-overall-buckets.html # def get_overall_buckets(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/results/overall_buckets" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_overall_buckets, [ :top_n, :bucket_span, :overall_score, :exclude_interim, :start, :end, :allow_no_match, :allow_no_jobs ].freeze) end end end end end get_records.rb000066400000000000000000000061411462737751600403100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves anomaly records for an anomaly detection job. # # @option arguments [String] :job_id The ID of the job # @option arguments [Boolean] :exclude_interim Exclude interim results # @option arguments [Integer] :from skips a number of records # @option arguments [Integer] :size specifies a max number of records to get # @option arguments [String] :start Start time filter for records # @option arguments [String] :end End time filter for records # @option arguments [Double] :record_score Returns records with anomaly scores greater or equal than this value # @option arguments [String] :sort Sort records by a particular field # @option arguments [Boolean] :desc Set the sort direction # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Record selection criteria # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-get-record.html # def get_records(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/results/records" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_records, [ :exclude_interim, :from, :size, :start, :end, :record_score, :sort, :desc ].freeze) end end end end end get_trained_models.rb000066400000000000000000000067711462737751600416510ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves configuration information for a trained inference model. # # @option arguments [String] :model_id The ID of the trained models to fetch # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no trained models. (This includes `_all` string or when no trained models have been specified) # @option arguments [String] :include A comma-separate list of fields to optionally include. Valid options are 'definition' and 'total_feature_importance'. Default is none. # @option arguments [Boolean] :include_model_definition Should the full model definition be included in the results. These definitions can be large. So be cautious when including them. Defaults to false. *Deprecated* # @option arguments [Boolean] :decompress_definition Should the model definition be decompressed into valid JSON or returned in a custom compressed format. Defaults to true. # @option arguments [Integer] :from skips a number of trained models # @option arguments [Integer] :size specifies a max number of trained models to get # @option arguments [List] :tags A comma-separated list of tags that the model must have. # @option arguments [Boolean] :exclude_generated Omits fields that are illegal to set on model PUT # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-trained-models.html # def get_trained_models(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _model_id = arguments.delete(:model_id) method = Elasticsearch::API::HTTP_GET path = if _model_id "_ml/trained_models/#{Elasticsearch::API::Utils.__listify(_model_id)}" else "_ml/trained_models" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_trained_models, [ :allow_no_match, :include, :include_model_definition, :decompress_definition, :from, :size, :tags, :exclude_generated ].freeze) end end end end end get_trained_models_stats.rb000066400000000000000000000051371462737751600430620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Retrieves usage information for trained inference models. # # @option arguments [String] :model_id The ID of the trained models stats to fetch # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no trained models. (This includes `_all` string or when no trained models have been specified) # @option arguments [Integer] :from skips a number of trained models # @option arguments [Integer] :size specifies a max number of trained models to get # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-trained-models-stats.html # def get_trained_models_stats(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _model_id = arguments.delete(:model_id) method = Elasticsearch::API::HTTP_GET path = if _model_id "_ml/trained_models/#{Elasticsearch::API::Utils.__listify(_model_id)}/_stats" else "_ml/trained_models/_stats" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_trained_models_stats, [ :allow_no_match, :from, :size ].freeze) end end end end end infer_trained_model_deployment.rb000066400000000000000000000051331462737751600442410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Evaluate a trained model. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :model_id The ID of the model to perform inference on # @option arguments [Time] :timeout Controls the time to wait for the inference result # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.16/ml-df-analytics-apis.html # def infer_trained_model_deployment(arguments = {}) raise ArgumentError, "Required argument 'model_id' missing" unless arguments[:model_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _model_id = arguments.delete(:model_id) method = Elasticsearch::API::HTTP_POST path = "_ml/trained_models/#{Elasticsearch::API::Utils.__listify(_model_id)}/deployment/_infer" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:infer_trained_model_deployment, [ :timeout ].freeze) end end end end end info.rb000066400000000000000000000027701462737751600367470ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Returns defaults and limits used by machine learning. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-ml-info.html # def info(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_ml/info" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end open_job.rb000066400000000000000000000035651462737751600376120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Opens one or more anomaly detection jobs. # # @option arguments [String] :job_id The ID of the job to open # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Query parameters can be specified in the body # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-open-job.html # def open_job(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_POST path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/_open" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040521462737751600412220ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end post_calendar_events.rb000066400000000000000000000037621462737751600422200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Posts scheduled events in a calendar. # # @option arguments [String] :calendar_id The ID of the calendar to modify # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body A list of events (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-post-calendar-event.html # def post_calendar_events(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'calendar_id' missing" unless arguments[:calendar_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _calendar_id = arguments.delete(:calendar_id) method = Elasticsearch::API::HTTP_POST path = "_ml/calendars/#{Elasticsearch::API::Utils.__listify(_calendar_id)}/events" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end post_data.rb000066400000000000000000000050321462737751600377640ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Sends data to an anomaly detection job for analysis. # # @option arguments [String] :job_id The name of the job receiving the data # @option arguments [String] :reset_start Optional parameter to specify the start of the bucket resetting range # @option arguments [String] :reset_end Optional parameter to specify the end of the bucket resetting range # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The data to process (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-post-data.html # def post_data(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_POST path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/_data" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:post_data, [ :reset_start, :reset_end ].freeze) end end end end end preview_data_frame_analytics.rb000066400000000000000000000041571462737751600437100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Previews that will be analyzed given a data frame analytics config. # # @option arguments [String] :id The ID of the data frame analytics to preview # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The data frame analytics config to preview # # @see http://www.elastic.co/guide/en/elasticsearch/reference/7.17/preview-dfanalytics.html # def preview_data_frame_analytics(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _id "_ml/data_frame/analytics/#{Elasticsearch::API::Utils.__listify(_id)}/_preview" else "_ml/data_frame/analytics/_preview" end params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end preview_datafeed.rb000066400000000000000000000041321462737751600413040ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Previews a datafeed. # # @option arguments [String] :datafeed_id The ID of the datafeed to preview # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The datafeed config and job config with which to execute the preview # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-preview-datafeed.html # def preview_datafeed(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _datafeed_id = arguments.delete(:datafeed_id) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _datafeed_id "_ml/datafeeds/#{Elasticsearch::API::Utils.__listify(_datafeed_id)}/_preview" else "_ml/datafeeds/_preview" end params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end put_calendar.rb000066400000000000000000000035511462737751600404530ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Instantiates a calendar. # # @option arguments [String] :calendar_id The ID of the calendar to create # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The calendar details # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-put-calendar.html # def put_calendar(arguments = {}) raise ArgumentError, "Required argument 'calendar_id' missing" unless arguments[:calendar_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _calendar_id = arguments.delete(:calendar_id) method = Elasticsearch::API::HTTP_PUT path = "_ml/calendars/#{Elasticsearch::API::Utils.__listify(_calendar_id)}" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end put_calendar_job.rb000066400000000000000000000041261462737751600413040ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Adds an anomaly detection job to a calendar. # # @option arguments [String] :calendar_id The ID of the calendar to modify # @option arguments [String] :job_id The ID of the job to add to the calendar # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-put-calendar-job.html # def put_calendar_job(arguments = {}) raise ArgumentError, "Required argument 'calendar_id' missing" unless arguments[:calendar_id] raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _calendar_id = arguments.delete(:calendar_id) _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_PUT path = "_ml/calendars/#{Elasticsearch::API::Utils.__listify(_calendar_id)}/jobs/#{Elasticsearch::API::Utils.__listify(_job_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end put_data_frame_analytics.rb000066400000000000000000000037411462737751600430350ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Instantiates a data frame analytics job. # # @option arguments [String] :id The ID of the data frame analytics to create # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The data frame analytics configuration (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/put-dfanalytics.html # def put_data_frame_analytics(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_PUT path = "_ml/data_frame/analytics/#{Elasticsearch::API::Utils.__listify(_id)}" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end put_datafeed.rb000066400000000000000000000056401462737751600404400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Instantiates a datafeed. # # @option arguments [String] :datafeed_id The ID of the datafeed to create # @option arguments [Boolean] :ignore_unavailable Ignore unavailable indexes (default: false) # @option arguments [Boolean] :allow_no_indices Ignore if the source indices expressions resolves to no concrete indices (default: true) # @option arguments [Boolean] :ignore_throttled Ignore indices that are marked as throttled (default: true) # @option arguments [String] :expand_wildcards Whether source index expressions should get expanded to open or closed indices (default: open) (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The datafeed config (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-put-datafeed.html # def put_datafeed(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'datafeed_id' missing" unless arguments[:datafeed_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _datafeed_id = arguments.delete(:datafeed_id) method = Elasticsearch::API::HTTP_PUT path = "_ml/datafeeds/#{Elasticsearch::API::Utils.__listify(_datafeed_id)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_datafeed, [ :ignore_unavailable, :allow_no_indices, :ignore_throttled, :expand_wildcards ].freeze) end end end end end put_filter.rb000066400000000000000000000036721462737751600401730ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Instantiates a filter. # # @option arguments [String] :filter_id The ID of the filter to create # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The filter details (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-put-filter.html # def put_filter(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'filter_id' missing" unless arguments[:filter_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _filter_id = arguments.delete(:filter_id) method = Elasticsearch::API::HTTP_PUT path = "_ml/filters/#{Elasticsearch::API::Utils.__listify(_filter_id)}" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end put_job.rb000066400000000000000000000060401462737751600374500ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Instantiates an anomaly detection job. # # @option arguments [String] :job_id The ID of the job to create # @option arguments [Boolean] :ignore_unavailable Ignore unavailable indexes (default: false). Only set if datafeed_config is provided. # @option arguments [Boolean] :allow_no_indices Ignore if the source indices expressions resolves to no concrete indices (default: true). Only set if datafeed_config is provided. # @option arguments [Boolean] :ignore_throttled Ignore indices that are marked as throttled (default: true). Only set if datafeed_config is provided. # @option arguments [String] :expand_wildcards Whether source index expressions should get expanded to open or closed indices (default: open). Only set if datafeed_config is provided. (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The job (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-put-job.html # def put_job(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_PUT path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_job, [ :ignore_unavailable, :allow_no_indices, :ignore_throttled, :expand_wildcards ].freeze) end end end end end put_trained_model.rb000066400000000000000000000050071462737751600415060ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Creates an inference trained model. # # @option arguments [String] :model_id The ID of the trained models to store # @option arguments [Boolean] :defer_definition_decompression If set to `true` and a `compressed_definition` is provided, the request defers definition decompression and skips relevant validations. # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The trained model configuration (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/put-trained-models.html # def put_trained_model(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'model_id' missing" unless arguments[:model_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _model_id = arguments.delete(:model_id) method = Elasticsearch::API::HTTP_PUT path = "_ml/trained_models/#{Elasticsearch::API::Utils.__listify(_model_id)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_trained_model, [ :defer_definition_decompression ].freeze) end end end end end put_trained_model_alias.rb000066400000000000000000000052411462737751600426570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Creates a new model alias (or reassigns an existing one) to refer to the trained model # # @option arguments [String] :model_alias The trained model alias to update # @option arguments [String] :model_id The trained model where the model alias should be assigned # @option arguments [Boolean] :reassign If the model_alias already exists and points to a separate model_id, this parameter must be true. Defaults to false. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/put-trained-models-aliases.html # def put_trained_model_alias(arguments = {}) raise ArgumentError, "Required argument 'model_id' missing" unless arguments[:model_id] raise ArgumentError, "Required argument 'model_alias' missing" unless arguments[:model_alias] headers = arguments.delete(:headers) || {} arguments = arguments.clone _model_alias = arguments.delete(:model_alias) _model_id = arguments.delete(:model_id) method = Elasticsearch::API::HTTP_PUT path = "_ml/trained_models/#{Elasticsearch::API::Utils.__listify(_model_id)}/model_aliases/#{Elasticsearch::API::Utils.__listify(_model_alias)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_trained_model_alias, [ :reassign ].freeze) end end end end end reset_job.rb000066400000000000000000000043301462737751600377620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Resets an existing anomaly detection job. # # @option arguments [String] :job_id The ID of the job to reset # @option arguments [Boolean] :wait_for_completion Should this request wait until the operation has completed before returning # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-reset-job.html # def reset_job(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_POST path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/_reset" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:reset_job, [ :wait_for_completion ].freeze) end end end end end revert_model_snapshot.rb000066400000000000000000000051711462737751600424200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Reverts to a specific snapshot. # # @option arguments [String] :job_id The ID of the job to fetch # @option arguments [String] :snapshot_id The ID of the snapshot to revert to # @option arguments [Boolean] :delete_intervening_results Should we reset the results back to the time of the snapshot? # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Reversion options # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-revert-snapshot.html # def revert_model_snapshot(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] raise ArgumentError, "Required argument 'snapshot_id' missing" unless arguments[:snapshot_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) _snapshot_id = arguments.delete(:snapshot_id) method = Elasticsearch::API::HTTP_POST path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/model_snapshots/#{Elasticsearch::API::Utils.__listify(_snapshot_id)}/_revert" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:revert_model_snapshot, [ :delete_intervening_results ].freeze) end end end end end set_upgrade_mode.rb000066400000000000000000000041761462737751600413240ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Sets a cluster wide upgrade_mode setting that prepares machine learning indices for an upgrade. # # @option arguments [Boolean] :enabled Whether to enable upgrade_mode ML setting or not. Defaults to false. # @option arguments [Time] :timeout Controls the time to wait before action times out. Defaults to 30 seconds # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-set-upgrade-mode.html # def set_upgrade_mode(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_ml/set_upgrade_mode" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:set_upgrade_mode, [ :enabled, :timeout ].freeze) end end end end end start_data_frame_analytics.rb000066400000000000000000000044741462737751600433660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Starts a data frame analytics job. # # @option arguments [String] :id The ID of the data frame analytics to start # @option arguments [Time] :timeout Controls the time to wait until the task has started. Defaults to 20 seconds # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The start data frame analytics parameters # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/start-dfanalytics.html # def start_data_frame_analytics(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_POST path = "_ml/data_frame/analytics/#{Elasticsearch::API::Utils.__listify(_id)}/_start" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:start_data_frame_analytics, [ :timeout ].freeze) end end end end end start_datafeed.rb000066400000000000000000000051051462737751600407610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Starts one or more datafeeds. # # @option arguments [String] :datafeed_id The ID of the datafeed to start # @option arguments [String] :start The start time from where the datafeed should begin # @option arguments [String] :end The end time when the datafeed should stop. When not set, the datafeed continues in real time # @option arguments [Time] :timeout Controls the time to wait until a datafeed has started. Default to 20 seconds # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The start datafeed parameters # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-start-datafeed.html # def start_datafeed(arguments = {}) raise ArgumentError, "Required argument 'datafeed_id' missing" unless arguments[:datafeed_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _datafeed_id = arguments.delete(:datafeed_id) method = Elasticsearch::API::HTTP_POST path = "_ml/datafeeds/#{Elasticsearch::API::Utils.__listify(_datafeed_id)}/_start" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:start_datafeed, [ :start, :end, :timeout ].freeze) end end end end end start_trained_model_deployment.rb000066400000000000000000000051301462737751600442700ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Start a trained model deployment. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :model_id The ID of the model to deploy # @option arguments [Time] :timeout Controls the time to wait until the model is deployed # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.16/ml-df-analytics-apis.html # def start_trained_model_deployment(arguments = {}) raise ArgumentError, "Required argument 'model_id' missing" unless arguments[:model_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _model_id = arguments.delete(:model_id) method = Elasticsearch::API::HTTP_POST path = "_ml/trained_models/#{Elasticsearch::API::Utils.__listify(_model_id)}/deployment/_start" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:start_trained_model_deployment, [ :timeout ].freeze) end end end end end stop_data_frame_analytics.rb000066400000000000000000000052641462737751600432140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Stops one or more data frame analytics jobs. # # @option arguments [String] :id The ID of the data frame analytics to stop # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no data frame analytics. (This includes `_all` string or when no data frame analytics have been specified) # @option arguments [Boolean] :force True if the data frame analytics should be forcefully stopped # @option arguments [Time] :timeout Controls the time to wait until the task has stopped. Defaults to 20 seconds # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The stop data frame analytics parameters # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/stop-dfanalytics.html # def stop_data_frame_analytics(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_POST path = "_ml/data_frame/analytics/#{Elasticsearch::API::Utils.__listify(_id)}/_stop" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:stop_data_frame_analytics, [ :allow_no_match, :force, :timeout ].freeze) end end end end end stop_datafeed.rb000066400000000000000000000055771462737751600406260ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Stops one or more datafeeds. # # @option arguments [String] :datafeed_id The ID of the datafeed to stop # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no datafeeds. (This includes `_all` string or when no datafeeds have been specified) # @option arguments [Boolean] :allow_no_datafeeds Whether to ignore if a wildcard expression matches no datafeeds. (This includes `_all` string or when no datafeeds have been specified) *Deprecated* # @option arguments [Boolean] :force True if the datafeed should be forcefully stopped. # @option arguments [Time] :timeout Controls the time to wait until a datafeed has stopped. Default to 20 seconds # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The URL params optionally sent in the body # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-stop-datafeed.html # def stop_datafeed(arguments = {}) raise ArgumentError, "Required argument 'datafeed_id' missing" unless arguments[:datafeed_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _datafeed_id = arguments.delete(:datafeed_id) method = Elasticsearch::API::HTTP_POST path = "_ml/datafeeds/#{Elasticsearch::API::Utils.__listify(_datafeed_id)}/_stop" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:stop_datafeed, [ :allow_no_match, :allow_no_datafeeds, :force, :timeout ].freeze) end end end end end stop_trained_model_deployment.rb000066400000000000000000000041411462737751600441210ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Stop a trained model deployment. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :model_id The ID of the model to undeploy # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.16/ml-df-analytics-apis.html # def stop_trained_model_deployment(arguments = {}) raise ArgumentError, "Required argument 'model_id' missing" unless arguments[:model_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _model_id = arguments.delete(:model_id) method = Elasticsearch::API::HTTP_POST path = "_ml/trained_models/#{Elasticsearch::API::Utils.__listify(_model_id)}/deployment/_stop" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end update_data_frame_analytics.rb000066400000000000000000000040061462737751600435020ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Updates certain properties of a data frame analytics job. # # @option arguments [String] :id The ID of the data frame analytics to update # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The data frame analytics settings to update (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/update-dfanalytics.html # def update_data_frame_analytics(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_POST path = "_ml/data_frame/analytics/#{Elasticsearch::API::Utils.__listify(_id)}/_update" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end update_datafeed.rb000066400000000000000000000057141462737751600411140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Updates certain properties of a datafeed. # # @option arguments [String] :datafeed_id The ID of the datafeed to update # @option arguments [Boolean] :ignore_unavailable Ignore unavailable indexes (default: false) # @option arguments [Boolean] :allow_no_indices Ignore if the source indices expressions resolves to no concrete indices (default: true) # @option arguments [Boolean] :ignore_throttled Ignore indices that are marked as throttled (default: true) # @option arguments [String] :expand_wildcards Whether source index expressions should get expanded to open or closed indices (default: open) (options: open, closed, hidden, none, all) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The datafeed update settings (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-update-datafeed.html # def update_datafeed(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'datafeed_id' missing" unless arguments[:datafeed_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _datafeed_id = arguments.delete(:datafeed_id) method = Elasticsearch::API::HTTP_POST path = "_ml/datafeeds/#{Elasticsearch::API::Utils.__listify(_datafeed_id)}/_update" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:update_datafeed, [ :ignore_unavailable, :allow_no_indices, :ignore_throttled, :expand_wildcards ].freeze) end end end end end update_filter.rb000066400000000000000000000037641462737751600406470ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Updates the description of a filter, adds items, or removes items. # # @option arguments [String] :filter_id The ID of the filter to update # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The filter update (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-update-filter.html # def update_filter(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'filter_id' missing" unless arguments[:filter_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _filter_id = arguments.delete(:filter_id) method = Elasticsearch::API::HTTP_POST path = "_ml/filters/#{Elasticsearch::API::Utils.__listify(_filter_id)}/_update" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end update_job.rb000066400000000000000000000037361462737751600401330ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Updates certain properties of an anomaly detection job. # # @option arguments [String] :job_id The ID of the job to create # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The job update settings (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-update-job.html # def update_job(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) method = Elasticsearch::API::HTTP_POST path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/_update" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end update_model_snapshot.rb000066400000000000000000000044561462737751600424000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Updates certain properties of a snapshot. # # @option arguments [String] :job_id The ID of the job to fetch # @option arguments [String] :snapshot_id The ID of the snapshot to update # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The model snapshot properties to update (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-update-snapshot.html # def update_model_snapshot(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] raise ArgumentError, "Required argument 'snapshot_id' missing" unless arguments[:snapshot_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) _snapshot_id = arguments.delete(:snapshot_id) method = Elasticsearch::API::HTTP_POST path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/model_snapshots/#{Elasticsearch::API::Utils.__listify(_snapshot_id)}/_update" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end upgrade_job_snapshot.rb000066400000000000000000000053661462737751600422200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Upgrades a given job snapshot to the current major version. # # @option arguments [String] :job_id The ID of the job # @option arguments [String] :snapshot_id The ID of the snapshot # @option arguments [Time] :timeout How long should the API wait for the job to be opened and the old snapshot to be loaded. # @option arguments [Boolean] :wait_for_completion Should the request wait until the task is complete before responding to the caller. Default is false. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/ml-upgrade-job-model-snapshot.html # def upgrade_job_snapshot(arguments = {}) raise ArgumentError, "Required argument 'job_id' missing" unless arguments[:job_id] raise ArgumentError, "Required argument 'snapshot_id' missing" unless arguments[:snapshot_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _job_id = arguments.delete(:job_id) _snapshot_id = arguments.delete(:snapshot_id) method = Elasticsearch::API::HTTP_POST path = "_ml/anomaly_detectors/#{Elasticsearch::API::Utils.__listify(_job_id)}/model_snapshots/#{Elasticsearch::API::Utils.__listify(_snapshot_id)}/_upgrade" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:upgrade_job_snapshot, [ :timeout, :wait_for_completion ].freeze) end end end end end validate.rb000066400000000000000000000032501462737751600375770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Validates an anomaly detection job. # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The job config (*Required*) # # @see https://www.elastic.co/guide/en/machine-learning/7.17/ml-jobs.html # def validate(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_ml/anomaly_detectors/_validate" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end validate_detector.rb000066400000000000000000000032751462737751600414770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions # Validates an anomaly detection detector. # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The detector (*Required*) # # @see https://www.elastic.co/guide/en/machine-learning/7.17/ml-jobs.html # def validate_detector(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_ml/anomaly_detectors/_validate/detector" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end migration/000077500000000000000000000000001462737751600341675ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actionsdeprecations.rb000066400000000000000000000036461462737751600372050ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/migration# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Migration module Actions # Retrieves information about different cluster, node, and index level settings that use deprecated features that will be removed or changed in the next major version. # # @option arguments [String] :index Index pattern # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/migration-api-deprecation.html # def deprecations(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _index "#{Elasticsearch::API::Utils.__listify(_index)}/_migration/deprecations" else "_migration/deprecations" end params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_feature_upgrade_status.rb000066400000000000000000000030621462737751600421210ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/migration# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Migration module Actions # Find out whether system features need to be upgraded or not # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/migration-api-feature-upgrade.html # def get_feature_upgrade_status(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_migration/system_features" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040441462737751600377310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/migration# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Migration module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end post_feature_upgrade.rb000066400000000000000000000030241462737751600407220ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/migration# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Migration module Actions # Begin upgrades for system features # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/migration-api-feature-upgrade.html # def post_feature_upgrade(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_migration/system_features" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end monitoring/000077500000000000000000000000001462737751600343635ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actionsbulk.rb000066400000000000000000000063711462737751600356540ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/monitoring# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Monitoring module Actions # Used by the monitoring features to send monitoring data. # # @option arguments [String] :type Default document type for items which don't provide one *Deprecated* # @option arguments [String] :system_id Identifier of the monitored system # @option arguments [String] :system_api_version API Version of the monitored system # @option arguments [String] :interval Collection interval (e.g., '10s' or '10000ms') of the payload # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [String|Array] :body The operation definition and data (action-data pairs), separated by newlines. Array of Strings, Header/Data pairs, # or the conveniency "combined" format can be passed, refer to Elasticsearch::API::Utils.__bulkify documentation. # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/monitor-elasticsearch-cluster.html # def bulk(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_POST path = if _type "_monitoring/#{Elasticsearch::API::Utils.__listify(_type)}/bulk" else "_monitoring/bulk" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] if body.is_a? Array payload = Elasticsearch::API::Utils.__bulkify(body) else payload = body end headers = Elasticsearch::API::Utils.ndjson_headers(headers) perform_request(method, path, params, payload, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:bulk, [ :system_id, :system_api_version, :interval ].freeze) end end end end end params_registry.rb000066400000000000000000000040451462737751600401260ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/monitoring# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Monitoring module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end params_registry.rb000066400000000000000000000036771462737751600357530ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/rollup/000077500000000000000000000000001462737751600335725ustar00rootroot00000000000000delete_job.rb000066400000000000000000000040031462737751600361310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/rollup# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Rollup module Actions # Deletes an existing rollup job. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :id The ID of the job to delete # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/rollup-delete-job.html # def delete_job(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_DELETE path = "_rollup/job/#{Elasticsearch::API::Utils.__listify(_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_jobs.rb000066400000000000000000000041541462737751600356400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/rollup# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Rollup module Actions # Retrieves the configuration, stats, and status of rollup jobs. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :id The ID of the job(s) to fetch. Accepts glob patterns, or left blank for all jobs # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/rollup-get-job.html # def get_jobs(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = if _id "_rollup/job/#{Elasticsearch::API::Utils.__listify(_id)}" else "_rollup/job" end params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_rollup_caps.rb000066400000000000000000000042521462737751600372250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/rollup# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Rollup module Actions # Returns the capabilities of any rollup jobs that have been configured for a specific index or index pattern. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :id The ID of the index to check rollup capabilities on, or left blank for all jobs # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/rollup-get-rollup-caps.html # def get_rollup_caps(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = if _id "_rollup/data/#{Elasticsearch::API::Utils.__listify(_id)}" else "_rollup/data" end params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_rollup_index_caps.rb000066400000000000000000000042461462737751600404170ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/rollup# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Rollup module Actions # Returns the rollup capabilities of all jobs inside of a rollup index (e.g. the index where rollup data is stored). # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :index The rollup index or index pattern to obtain rollup capabilities from. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/rollup-get-rollup-index-caps.html # def get_rollup_index_caps(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = "#{Elasticsearch::API::Utils.__listify(_index)}/_rollup/data" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040411462737751600372520ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/rollup# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Rollup module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end put_job.rb000066400000000000000000000042471462737751600355110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/rollup# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Rollup module Actions # Creates a rollup job. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :id The ID of the job to create # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The job configuration (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/rollup-put-job.html # def put_job(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_PUT path = "_rollup/job/#{Elasticsearch::API::Utils.__listify(_id)}" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end rollup.rb000066400000000000000000000047761462737751600353730ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/rollup# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Rollup module Actions # Rollup an index # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :index The index to roll up (*Required*) # @option arguments [String] :rollup_index The name of the rollup index to create (*Required*) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The rollup configuration (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/xpack-rollup.html # def rollup(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] raise ArgumentError, "Required argument 'rollup_index' missing" unless arguments[:rollup_index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _rollup_index = arguments.delete(:rollup_index) method = Elasticsearch::API::HTTP_POST path = "#{Elasticsearch::API::Utils.__listify(_index)}/_rollup/#{Elasticsearch::API::Utils.__listify(_rollup_index)}" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end rollup_search.rb000066400000000000000000000067241462737751600367130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/rollup# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Rollup module Actions # Enables searching rolled-up data using the standard query DSL. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [List] :index The indices or index-pattern(s) (containing rollup or regular data) that should be searched # @option arguments [String] :type The doc type inside the index *Deprecated* # @option arguments [Boolean] :typed_keys Specify whether aggregation and suggester names should be prefixed by their respective types in the response # @option arguments [Boolean] :rest_total_hits_as_int Indicates whether hits.total should be rendered as an integer or an object in the rest search response # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The search request body (*Required*) # # *Deprecation notice*: # Specifying types in urls has been deprecated # Deprecated since version 7.0.0 # # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/rollup-search.html # def rollup_search(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) _type = arguments.delete(:type) method = Elasticsearch::API::HTTP_POST path = if _index && _type "#{Elasticsearch::API::Utils.__listify(_index)}/#{Elasticsearch::API::Utils.__listify(_type)}/_rollup_search" else "#{Elasticsearch::API::Utils.__listify(_index)}/_rollup_search" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:rollup_search, [ :typed_keys, :rest_total_hits_as_int ].freeze) end end end end end start_job.rb000066400000000000000000000040151462737751600360270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/rollup# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Rollup module Actions # Starts an existing, stopped rollup job. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :id The ID of the job to start # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/rollup-start-job.html # def start_job(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_POST path = "_rollup/job/#{Elasticsearch::API::Utils.__listify(_id)}/_start" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end stop_job.rb000066400000000000000000000052331462737751600356620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/rollup# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Rollup module Actions # Stops an existing, started rollup job. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :id The ID of the job to stop # @option arguments [Boolean] :wait_for_completion True if the API should block until the job has fully stopped, false if should be executed async. Defaults to false. # @option arguments [Time] :timeout Block for (at maximum) the specified duration while waiting for the job to stop. Defaults to 30s. # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/rollup-stop-job.html # def stop_job(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_POST path = "_rollup/job/#{Elasticsearch::API::Utils.__listify(_id)}/_stop" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:stop_job, [ :wait_for_completion, :timeout ].freeze) end end end end end searchable_snapshots/000077500000000000000000000000001462737751600363715ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actionscache_stats.rb000066400000000000000000000044771462737751600412130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/searchable_snapshots# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SearchableSnapshots module Actions # Retrieve node-level cache statistics about searchable snapshots. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [List] :node_id A comma-separated list of node IDs or names to limit the returned information; use `_local` to return information from the node you're connecting to, leave empty to get information from all nodes # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/searchable-snapshots-apis.html # def cache_stats(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _node_id = arguments.delete(:node_id) method = Elasticsearch::API::HTTP_GET path = if _node_id "_searchable_snapshots/#{Elasticsearch::API::Utils.__listify(_node_id)}/cache/stats" else "_searchable_snapshots/cache/stats" end params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end clear_cache.rb000066400000000000000000000060571462737751600411370ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/searchable_snapshots# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SearchableSnapshots module Actions # Clear the cache of searchable snapshots. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [List] :index A comma-separated list of index names # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed) # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, none, all) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/searchable-snapshots-apis.html # def clear_cache(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_POST path = if _index "#{Elasticsearch::API::Utils.__listify(_index)}/_searchable_snapshots/cache/clear" else "_searchable_snapshots/cache/clear" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:clear_cache, [ :ignore_unavailable, :allow_no_indices, :expand_wildcards, :index ].freeze) end end end end end mount.rb000066400000000000000000000061571462737751600400710ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/searchable_snapshots# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SearchableSnapshots module Actions # Mount a snapshot as a searchable index. # # @option arguments [String] :repository The name of the repository containing the snapshot of the index to mount # @option arguments [String] :snapshot The name of the snapshot of the index to mount # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node # @option arguments [Boolean] :wait_for_completion Should this request wait until the operation has completed before returning # @option arguments [String] :storage Selects the kind of local storage used to accelerate searches. Experimental, and defaults to `full_copy` # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The restore configuration for mounting the snapshot as searchable (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/searchable-snapshots-api-mount-snapshot.html # def mount(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository] raise ArgumentError, "Required argument 'snapshot' missing" unless arguments[:snapshot] headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) _snapshot = arguments.delete(:snapshot) method = Elasticsearch::API::HTTP_POST path = "_snapshot/#{Elasticsearch::API::Utils.__listify(_repository)}/#{Elasticsearch::API::Utils.__listify(_snapshot)}/_mount" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:mount, [ :master_timeout, :wait_for_completion, :storage ].freeze) end end end end end params_registry.rb000066400000000000000000000040561462737751600421360ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/searchable_snapshots# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SearchableSnapshots module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end repository_stats.rb000066400000000000000000000042051462737751600423540ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/searchable_snapshots# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SearchableSnapshots module Actions # DEPRECATED: This API is replaced by the Repositories Metering API. # This functionality is Experimental and may be changed or removed # completely in a future release. Elastic will take a best effort approach # to fix any issues, but experimental features are not subject to the # support SLA of official GA features. # # @option arguments [String] :repository The repository for which to get the stats for # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/searchable-snapshots-apis.html # def repository_stats(arguments = {}) raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository] headers = arguments.delete(:headers) || {} arguments = arguments.clone _repository = arguments.delete(:repository) method = Elasticsearch::API::HTTP_GET path = "_snapshot/#{Elasticsearch::API::Utils.__listify(_repository)}/_stats" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end stats.rb000066400000000000000000000044221462737751600400560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/searchable_snapshots# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SearchableSnapshots module Actions # Retrieve shard-level statistics about searchable snapshots. # # @option arguments [List] :index A comma-separated list of index names # @option arguments [String] :level Return stats aggregated at cluster, index or shard level (options: cluster, indices, shards) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/searchable-snapshots-apis.html # def stats(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = Elasticsearch::API::HTTP_GET path = if _index "#{Elasticsearch::API::Utils.__listify(_index)}/_searchable_snapshots/stats" else "_searchable_snapshots/stats" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:stats, [ :level ].freeze) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security/000077500000000000000000000000001462737751600341245ustar00rootroot00000000000000authenticate.rb000066400000000000000000000030701462737751600370500ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Enables authentication as a user and retrieve information about the authenticated user. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-authenticate.html # def authenticate(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_security/_authenticate" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end change_password.rb000066400000000000000000000052501462737751600375430ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Changes the passwords of users in the native realm and built-in users. # # @option arguments [String] :username The username of the user to change the password for # @option arguments [String] :refresh If `true` (the default) then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body the new password for the user (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-change-password.html # def change_password(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone _username = arguments.delete(:username) method = Elasticsearch::API::HTTP_PUT path = if _username "_security/user/#{Elasticsearch::API::Utils.__listify(_username)}/_password" else "_security/user/_password" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:change_password, [ :refresh ].freeze) end end end end end clear_api_key_cache.rb000066400000000000000000000035131462737751600403060ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Clear a subset or all entries from the API key cache. # # @option arguments [List] :ids A comma-separated list of IDs of API keys to clear from the cache # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-clear-api-key-cache.html # def clear_api_key_cache(arguments = {}) raise ArgumentError, "Required argument 'ids' missing" unless arguments[:ids] headers = arguments.delete(:headers) || {} arguments = arguments.clone _ids = arguments.delete(:ids) method = Elasticsearch::API::HTTP_POST path = "_security/api_key/#{Elasticsearch::API::Utils.__listify(_ids)}/_clear_cache" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end clear_cached_privileges.rb000066400000000000000000000036031462737751600412020ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Evicts application privileges from the native application privileges cache. # # @option arguments [List] :application A comma-separated list of application names # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-clear-privilege-cache.html # def clear_cached_privileges(arguments = {}) raise ArgumentError, "Required argument 'application' missing" unless arguments[:application] headers = arguments.delete(:headers) || {} arguments = arguments.clone _application = arguments.delete(:application) method = Elasticsearch::API::HTTP_POST path = "_security/privilege/#{Elasticsearch::API::Utils.__listify(_application)}/_clear_cache" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end clear_cached_realms.rb000066400000000000000000000044031462737751600403130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Evicts users from the user cache. Can completely clear the cache or evict specific users. # # @option arguments [List] :realms Comma-separated list of realms to clear # @option arguments [List] :usernames Comma-separated list of usernames to clear from the cache # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-clear-cache.html # def clear_cached_realms(arguments = {}) raise ArgumentError, "Required argument 'realms' missing" unless arguments[:realms] headers = arguments.delete(:headers) || {} arguments = arguments.clone _realms = arguments.delete(:realms) method = Elasticsearch::API::HTTP_POST path = "_security/realm/#{Elasticsearch::API::Utils.__listify(_realms)}/_clear_cache" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:clear_cached_realms, [ :usernames ].freeze) end end end end end clear_cached_roles.rb000066400000000000000000000034051462737751600401550ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Evicts roles from the native role cache. # # @option arguments [List] :name Role name # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-clear-role-cache.html # def clear_cached_roles(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_POST path = "_security/role/#{Elasticsearch::API::Utils.__listify(_name)}/_clear_cache" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end clear_cached_service_tokens.rb000066400000000000000000000046271462737751600420630ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Evicts tokens from the service account token caches. # # @option arguments [String] :namespace An identifier for the namespace # @option arguments [String] :service An identifier for the service name # @option arguments [List] :name A comma-separated list of service token names # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-clear-service-token-caches.html # def clear_cached_service_tokens(arguments = {}) raise ArgumentError, "Required argument 'namespace' missing" unless arguments[:namespace] raise ArgumentError, "Required argument 'service' missing" unless arguments[:service] raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _namespace = arguments.delete(:namespace) _service = arguments.delete(:service) _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_POST path = "_security/service/#{Elasticsearch::API::Utils.__listify(_namespace)}/#{Elasticsearch::API::Utils.__listify(_service)}/credential/token/#{Elasticsearch::API::Utils.__listify(_name)}/_clear_cache" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end create_api_key.rb000066400000000000000000000045231462737751600373420ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Creates an API key for access without requiring basic authentication. # # @option arguments [String] :refresh If `true` (the default) then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The api key request to create an API key (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-create-api-key.html # def create_api_key(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_PUT path = "_security/api_key" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:create_api_key, [ :refresh ].freeze) end end end end end create_service_token.rb000066400000000000000000000062521462737751600405620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Creates a service account token for access without requiring basic authentication. # # @option arguments [String] :namespace An identifier for the namespace # @option arguments [String] :service An identifier for the service name # @option arguments [String] :name An identifier for the token name # @option arguments [String] :refresh If `true` then refresh the affected shards to make this operation visible to search, if `wait_for` (the default) then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-create-service-token.html # def create_service_token(arguments = {}) raise ArgumentError, "Required argument 'namespace' missing" unless arguments[:namespace] raise ArgumentError, "Required argument 'service' missing" unless arguments[:service] headers = arguments.delete(:headers) || {} arguments = arguments.clone _namespace = arguments.delete(:namespace) _service = arguments.delete(:service) _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_PUT path = if _namespace && _service && _name "_security/service/#{Elasticsearch::API::Utils.__listify(_namespace)}/#{Elasticsearch::API::Utils.__listify(_service)}/credential/token/#{Elasticsearch::API::Utils.__listify(_name)}" else "_security/service/#{Elasticsearch::API::Utils.__listify(_namespace)}/#{Elasticsearch::API::Utils.__listify(_service)}/credential/token" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:create_service_token, [ :refresh ].freeze) end end end end end delete_privileges.rb000066400000000000000000000052021462737751600400640ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Removes application privileges. # # @option arguments [String] :application Application name # @option arguments [String] :name Privilege name # @option arguments [String] :refresh If `true` (the default) then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-delete-privilege.html # def delete_privileges(arguments = {}) raise ArgumentError, "Required argument 'application' missing" unless arguments[:application] raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _application = arguments.delete(:application) _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_DELETE path = "_security/privilege/#{Elasticsearch::API::Utils.__listify(_application)}/#{Elasticsearch::API::Utils.__listify(_name)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_privileges, [ :refresh ].freeze) end end end end end delete_role.rb000066400000000000000000000045131462737751600366600ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Removes roles in the native realm. # # @option arguments [String] :name Role name # @option arguments [String] :refresh If `true` (the default) then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-delete-role.html # def delete_role(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_DELETE path = "_security/role/#{Elasticsearch::API::Utils.__listify(_name)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_role, [ :refresh ].freeze) end end end end end delete_role_mapping.rb000066400000000000000000000045471462737751600404020ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Removes role mappings. # # @option arguments [String] :name Role-mapping name # @option arguments [String] :refresh If `true` (the default) then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-delete-role-mapping.html # def delete_role_mapping(arguments = {}) raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_DELETE path = "_security/role_mapping/#{Elasticsearch::API::Utils.__listify(_name)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_role_mapping, [ :refresh ].freeze) end end end end end delete_service_token.rb000066400000000000000000000057121462737751600405610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Deletes a service account token. # # @option arguments [String] :namespace An identifier for the namespace # @option arguments [String] :service An identifier for the service name # @option arguments [String] :name An identifier for the token name # @option arguments [String] :refresh If `true` then refresh the affected shards to make this operation visible to search, if `wait_for` (the default) then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-delete-service-token.html # def delete_service_token(arguments = {}) raise ArgumentError, "Required argument 'namespace' missing" unless arguments[:namespace] raise ArgumentError, "Required argument 'service' missing" unless arguments[:service] raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _namespace = arguments.delete(:namespace) _service = arguments.delete(:service) _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_DELETE path = "_security/service/#{Elasticsearch::API::Utils.__listify(_namespace)}/#{Elasticsearch::API::Utils.__listify(_service)}/credential/token/#{Elasticsearch::API::Utils.__listify(_name)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_service_token, [ :refresh ].freeze) end end end end end delete_user.rb000066400000000000000000000045441462737751600367010ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Deletes users from the native realm. # # @option arguments [String] :username username # @option arguments [String] :refresh If `true` (the default) then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-delete-user.html # def delete_user(arguments = {}) raise ArgumentError, "Required argument 'username' missing" unless arguments[:username] headers = arguments.delete(:headers) || {} arguments = arguments.clone _username = arguments.delete(:username) method = Elasticsearch::API::HTTP_DELETE path = "_security/user/#{Elasticsearch::API::Utils.__listify(_username)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_user, [ :refresh ].freeze) end end end end end disable_user.rb000066400000000000000000000046071462737751600370420ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Disables users in the native realm. # # @option arguments [String] :username The username of the user to disable # @option arguments [String] :refresh If `true` (the default) then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-disable-user.html # def disable_user(arguments = {}) raise ArgumentError, "Required argument 'username' missing" unless arguments[:username] headers = arguments.delete(:headers) || {} arguments = arguments.clone _username = arguments.delete(:username) method = Elasticsearch::API::HTTP_PUT path = "_security/user/#{Elasticsearch::API::Utils.__listify(_username)}/_disable" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:disable_user, [ :refresh ].freeze) end end end end end enable_user.rb000066400000000000000000000046011462737751600366570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Enables users in the native realm. # # @option arguments [String] :username The username of the user to enable # @option arguments [String] :refresh If `true` (the default) then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-enable-user.html # def enable_user(arguments = {}) raise ArgumentError, "Required argument 'username' missing" unless arguments[:username] headers = arguments.delete(:headers) || {} arguments = arguments.clone _username = arguments.delete(:username) method = Elasticsearch::API::HTTP_PUT path = "_security/user/#{Elasticsearch::API::Utils.__listify(_username)}/_enable" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:enable_user, [ :refresh ].freeze) end end end end end enroll_kibana.rb000066400000000000000000000031101462737751600371650ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Allows a kibana instance to configure itself to communicate with a secured elasticsearch cluster. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.16/security-api-kibana-enrollment.html # def enroll_kibana(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_security/enroll/kibana" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end enroll_node.rb000066400000000000000000000030521462737751600366720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Allows a new node to enroll to an existing cluster with security enabled. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.16/security-api-node-enrollment.html # def enroll_node(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_security/enroll/node" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_api_key.rb000066400000000000000000000046151462737751600366600ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Retrieves information for one or more API keys. # # @option arguments [String] :id API key id of the API key to be retrieved # @option arguments [String] :name API key name of the API key to be retrieved # @option arguments [String] :username user name of the user who created this API key to be retrieved # @option arguments [String] :realm_name realm name of the user who created this API key to be retrieved # @option arguments [Boolean] :owner flag to query API keys owned by the currently authenticated user # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-get-api-key.html # def get_api_key(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_security/api_key" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_api_key, [ :id, :name, :username, :realm_name, :owner ].freeze) end end end end end get_builtin_privileges.rb000066400000000000000000000031541462737751600411330ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Retrieves the list of cluster privileges and index privileges that are available in this version of Elasticsearch. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-get-builtin-privileges.html # def get_builtin_privileges(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_security/privilege/_builtin" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_privileges.rb000066400000000000000000000041501462737751600374020ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Retrieves application privileges. # # @option arguments [String] :application Application name # @option arguments [String] :name Privilege name # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-get-privileges.html # def get_privileges(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _application = arguments.delete(:application) _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = if _application && _name "_security/privilege/#{Elasticsearch::API::Utils.__listify(_application)}/#{Elasticsearch::API::Utils.__listify(_name)}" elsif _application "_security/privilege/#{Elasticsearch::API::Utils.__listify(_application)}" else "_security/privilege" end params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_role.rb000066400000000000000000000037621462737751600362020ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Retrieves roles in the native realm. # # @option arguments [List] :name A comma-separated list of role names # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-get-role.html # def get_role(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = if _name "_security/role/#{Elasticsearch::API::Utils.__listify(_name)}" else "_security/role" end params = {} body = nil if Array(arguments[:ignore]).include?(404) Elasticsearch::API::Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end end end end end end get_role_mapping.rb000066400000000000000000000034661462737751600377160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Retrieves role mappings. # # @option arguments [List] :name A comma-separated list of role-mapping names # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-get-role-mapping.html # def get_role_mapping(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_GET path = if _name "_security/role_mapping/#{Elasticsearch::API::Utils.__listify(_name)}" else "_security/role_mapping" end params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_service_accounts.rb000066400000000000000000000042361462737751600405750ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Retrieves information about service accounts. # # @option arguments [String] :namespace An identifier for the namespace # @option arguments [String] :service An identifier for the service name # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-get-service-accounts.html # def get_service_accounts(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _namespace = arguments.delete(:namespace) _service = arguments.delete(:service) method = Elasticsearch::API::HTTP_GET path = if _namespace && _service "_security/service/#{Elasticsearch::API::Utils.__listify(_namespace)}/#{Elasticsearch::API::Utils.__listify(_service)}" elsif _namespace "_security/service/#{Elasticsearch::API::Utils.__listify(_namespace)}" else "_security/service" end params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_service_credentials.rb000066400000000000000000000041771462737751600412570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Retrieves information of all service credentials for a service account. # # @option arguments [String] :namespace An identifier for the namespace # @option arguments [String] :service An identifier for the service name # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-get-service-credentials.html # def get_service_credentials(arguments = {}) raise ArgumentError, "Required argument 'namespace' missing" unless arguments[:namespace] raise ArgumentError, "Required argument 'service' missing" unless arguments[:service] headers = arguments.delete(:headers) || {} arguments = arguments.clone _namespace = arguments.delete(:namespace) _service = arguments.delete(:service) method = Elasticsearch::API::HTTP_GET path = "_security/service/#{Elasticsearch::API::Utils.__listify(_namespace)}/#{Elasticsearch::API::Utils.__listify(_service)}/credential" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_token.rb000066400000000000000000000033371462737751600363570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Creates a bearer token for access without requiring basic authentication. # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The token request to get (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-get-token.html # def get_token(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_security/oauth2/token" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end get_user.rb000066400000000000000000000040521462737751600362100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Retrieves information about users in the native realm and built-in users. # # @option arguments [List] :username A comma-separated list of usernames # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-get-user.html # def get_user(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _username = arguments.delete(:username) method = Elasticsearch::API::HTTP_GET path = if _username "_security/user/#{Elasticsearch::API::Utils.__listify(_username)}" else "_security/user" end params = {} body = nil if Array(arguments[:ignore]).include?(404) Elasticsearch::API::Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end end end end end end get_user_privileges.rb000066400000000000000000000030471462737751600404440ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Retrieves security privileges for the logged in user. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-get-user-privileges.html # def get_user_privileges(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_security/user/_privileges" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end grant_api_key.rb000066400000000000000000000044771462737751600372220ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Creates an API key on behalf of another user. # # @option arguments [String] :refresh If `true` (the default) then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The api key request to create an API key (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-grant-api-key.html # def grant_api_key(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_security/api_key/grant" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:grant_api_key, [ :refresh ].freeze) end end end end end has_privileges.rb000066400000000000000000000040131462737751600373740ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Determines whether the specified user has a specified list of privileges. # # @option arguments [String] :user Username # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The privileges to test (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-has-privileges.html # def has_privileges(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone _user = arguments.delete(:user) method = Elasticsearch::API::HTTP_POST path = if _user "_security/user/#{Elasticsearch::API::Utils.__listify(_user)}/_has_privileges" else "_security/user/_has_privileges" end params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end invalidate_api_key.rb000066400000000000000000000033321462737751600402140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Invalidates one or more API keys. # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The api key request to invalidate API key(s) (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-invalidate-api-key.html # def invalidate_api_key(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_DELETE path = "_security/api_key" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end invalidate_token.rb000066400000000000000000000033351462737751600377160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Invalidates one or more access tokens or refresh tokens. # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The token to invalidate (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-invalidate-token.html # def invalidate_token(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_DELETE path = "_security/oauth2/token" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040431462737751600376060ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end put_privileges.rb000066400000000000000000000044461462737751600374430ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Adds or updates application privileges. # # @option arguments [String] :refresh If `true` (the default) then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The privilege(s) to add (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-put-privileges.html # def put_privileges(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_PUT path = "_security/privilege" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_privileges, [ :refresh ].freeze) end end end end end put_role.rb000066400000000000000000000047711462737751600362340ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Adds and updates roles in the native realm. # # @option arguments [String] :name Role name # @option arguments [String] :refresh If `true` (the default) then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The role to add (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-put-role.html # def put_role(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_PUT path = "_security/role/#{Elasticsearch::API::Utils.__listify(_name)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_role, [ :refresh ].freeze) end end end end end put_role_mapping.rb000066400000000000000000000050401462737751600377350ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Creates and updates role mappings. # # @option arguments [String] :name Role-mapping name # @option arguments [String] :refresh If `true` (the default) then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The role mapping to add (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-put-role-mapping.html # def put_role_mapping(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'name' missing" unless arguments[:name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _name = arguments.delete(:name) method = Elasticsearch::API::HTTP_PUT path = "_security/role_mapping/#{Elasticsearch::API::Utils.__listify(_name)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_role_mapping, [ :refresh ].freeze) end end end end end put_user.rb000066400000000000000000000051261462737751600362440ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Adds and updates users in the native realm. These users are commonly referred to as native users. # # @option arguments [String] :username The username of the User # @option arguments [String] :refresh If `true` (the default) then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes. (options: true, false, wait_for) # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The user to add (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-put-user.html # def put_user(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'username' missing" unless arguments[:username] headers = arguments.delete(:headers) || {} arguments = arguments.clone _username = arguments.delete(:username) method = Elasticsearch::API::HTTP_PUT path = "_security/user/#{Elasticsearch::API::Utils.__listify(_username)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_user, [ :refresh ].freeze) end end end end end query_api_keys.rb000066400000000000000000000034301462737751600374230ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Retrieves information for API keys using a subset of query DSL # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body From, size, query, sort and search_after # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-query-api-key.html # def query_api_keys(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = "_security/_query/api_key" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end saml_authenticate.rb000066400000000000000000000034161462737751600400700ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Exchanges a SAML Response message for an Elasticsearch access token and refresh token pair # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The SAML response to authenticate (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-saml-authenticate.html # def saml_authenticate(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_security/saml/authenticate" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end saml_complete_logout.rb000066400000000000000000000033541462737751600406140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Verifies the logout response sent from the SAML IdP # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The logout response to verify (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-saml-complete-logout.html # def saml_complete_logout(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_security/saml/complete_logout" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end saml_invalidate.rb000066400000000000000000000033031462737751600375250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Consumes a SAML LogoutRequest # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The LogoutRequest message (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-saml-invalidate.html # def saml_invalidate(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_security/saml/invalidate" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end saml_logout.rb000066400000000000000000000033721462737751600367240ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Invalidates an access token and a refresh token that were generated via the SAML Authenticate API # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The tokens to invalidate (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-saml-logout.html # def saml_logout(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_security/saml/logout" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end saml_prepare_authentication.rb000066400000000000000000000034551462737751600421520ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Creates a SAML authentication request # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The realm for which to create the authentication request, identified by either its name or the ACS URL (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-saml-prepare-authentication.html # def saml_prepare_authentication(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_security/saml/prepare" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end saml_service_provider_metadata.rb000066400000000000000000000035721462737751600426270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions # Generates SAML metadata for the Elastic stack SAML 2.0 Service Provider # # @option arguments [String] :realm_name The name of the SAML realm to get the metadata for # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-saml-sp-metadata.html # def saml_service_provider_metadata(arguments = {}) raise ArgumentError, "Required argument 'realm_name' missing" unless arguments[:realm_name] headers = arguments.delete(:headers) || {} arguments = arguments.clone _realm_name = arguments.delete(:realm_name) method = Elasticsearch::API::HTTP_GET path = "_security/saml/metadata/#{Elasticsearch::API::Utils.__listify(_realm_name)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end snapshot_lifecycle_management/000077500000000000000000000000001462737751600402505ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actionsdelete_lifecycle.rb000066400000000000000000000035161462737751600440630ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/snapshot_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SnapshotLifecycleManagement module Actions # Deletes an existing snapshot lifecycle policy. # # @option arguments [String] :policy_id The id of the snapshot lifecycle policy to remove # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/slm-api-delete-policy.html # def delete_lifecycle(arguments = {}) raise ArgumentError, "Required argument 'policy_id' missing" unless arguments[:policy_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _policy_id = arguments.delete(:policy_id) method = Elasticsearch::API::HTTP_DELETE path = "_slm/policy/#{Elasticsearch::API::Utils.__listify(_policy_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end execute_lifecycle.rb000066400000000000000000000036311462737751600442610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/snapshot_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SnapshotLifecycleManagement module Actions # Immediately creates a snapshot according to the lifecycle policy, without waiting for the scheduled time. # # @option arguments [String] :policy_id The id of the snapshot lifecycle policy to be executed # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/slm-api-execute-lifecycle.html # def execute_lifecycle(arguments = {}) raise ArgumentError, "Required argument 'policy_id' missing" unless arguments[:policy_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _policy_id = arguments.delete(:policy_id) method = Elasticsearch::API::HTTP_PUT path = "_slm/policy/#{Elasticsearch::API::Utils.__listify(_policy_id)}/_execute" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end execute_retention.rb000066400000000000000000000031131462737751600443240ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/snapshot_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SnapshotLifecycleManagement module Actions # Deletes any snapshots that are expired according to the policy's retention rules. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/slm-api-execute-retention.html # def execute_retention(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_slm/_execute_retention" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_lifecycle.rb000066400000000000000000000036501462737751600433770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/snapshot_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SnapshotLifecycleManagement module Actions # Retrieves one or more snapshot lifecycle policy definitions and information about the latest snapshot attempts. # # @option arguments [List] :policy_id Comma-separated list of snapshot lifecycle policies to retrieve # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/slm-api-get-policy.html # def get_lifecycle(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _policy_id = arguments.delete(:policy_id) method = Elasticsearch::API::HTTP_GET path = if _policy_id "_slm/policy/#{Elasticsearch::API::Utils.__listify(_policy_id)}" else "_slm/policy" end params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_stats.rb000066400000000000000000000030741462737751600425760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/snapshot_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SnapshotLifecycleManagement module Actions # Returns global and policy-level statistics about actions taken by snapshot lifecycle management. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/slm-api-get-stats.html # def get_stats(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_slm/stats" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_status.rb000066400000000000000000000030331462737751600427560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/snapshot_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SnapshotLifecycleManagement module Actions # Retrieves the status of snapshot lifecycle management (SLM). # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/slm-api-get-status.html # def get_status(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_slm/status" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040661462737751600440160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/snapshot_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SnapshotLifecycleManagement module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end put_lifecycle.rb000066400000000000000000000036511462737751600434310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/snapshot_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SnapshotLifecycleManagement module Actions # Creates or updates a snapshot lifecycle policy. # # @option arguments [String] :policy_id The id of the snapshot lifecycle policy # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The snapshot lifecycle policy definition to register # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/slm-api-put-policy.html # def put_lifecycle(arguments = {}) raise ArgumentError, "Required argument 'policy_id' missing" unless arguments[:policy_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _policy_id = arguments.delete(:policy_id) method = Elasticsearch::API::HTTP_PUT path = "_slm/policy/#{Elasticsearch::API::Utils.__listify(_policy_id)}" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end start.rb000066400000000000000000000030021462737751600417250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/snapshot_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SnapshotLifecycleManagement module Actions # Turns on snapshot lifecycle management (SLM). # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/slm-api-start.html # def start(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_slm/start" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end stop.rb000066400000000000000000000030001462737751600415530ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/snapshot_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SnapshotLifecycleManagement module Actions # Turns off snapshot lifecycle management (SLM). # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/slm-api-stop.html # def stop(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_slm/stop" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/sql/000077500000000000000000000000001462737751600330545ustar00rootroot00000000000000clear_cursor.rb000066400000000000000000000033101462737751600360020ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/sql# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SQL module Actions # Clears the SQL cursor # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Specify the cursor value in the `cursor` element to clean the cursor. (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/clear-sql-cursor-api.html # def clear_cursor(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_sql/close" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end delete_async.rb000066400000000000000000000034731462737751600357700ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/sql# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SQL module Actions # Deletes an async SQL search or a stored synchronous SQL search. If the search is still running, the API cancels it. # # @option arguments [String] :id The async search ID # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/delete-async-sql-search-api.html # def delete_async(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_DELETE path = "_sql/async/delete/#{Elasticsearch::API::Utils.__listify(_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end get_async.rb000066400000000000000000000050431462737751600353000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/sql# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SQL module Actions # Returns the current status and available results for an async SQL search or stored synchronous SQL search # # @option arguments [String] :id The async search ID # @option arguments [String] :delimiter Separator for CSV results # @option arguments [String] :format Short version of the Accept header, e.g. json, yaml # @option arguments [Time] :keep_alive Retention period for the search and its results # @option arguments [Time] :wait_for_completion_timeout Duration to wait for complete results # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-async-sql-search-api.html # def get_async(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = "_sql/async/#{Elasticsearch::API::Utils.__listify(_id)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_async, [ :delimiter, :format, :keep_alive, :wait_for_completion_timeout ].freeze) end end end end end get_async_status.rb000066400000000000000000000034411462737751600367030ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/sql# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SQL module Actions # Returns the current status of an async SQL search or a stored synchronous SQL search # # @option arguments [String] :id The async search ID # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-async-sql-search-status-api.html # def get_async_status(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = "_sql/async/status/#{Elasticsearch::API::Utils.__listify(_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040361462737751600365400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/sql# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SQL module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end query.rb000066400000000000000000000041301462737751600344650ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/sql# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SQL module Actions # Executes a SQL request # # @option arguments [String] :format a short version of the Accept header, e.g. json, yaml # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Use the `query` element to start a query. Use the `cursor` element to continue a query. (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/sql-search-api.html # def query(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_sql" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:query, [ :format ].freeze) end end end end end translate.rb000066400000000000000000000032761462737751600353270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/sql# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SQL module Actions # Translates SQL into Elasticsearch queries # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Specify the query in the `query` element. (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/sql-translate-api.html # def translate(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_sql/translate" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/ssl/000077500000000000000000000000001462737751600330565ustar00rootroot00000000000000certificates.rb000066400000000000000000000030561462737751600357750ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/ssl# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SSL module Actions # Retrieves information about the X.509 certificates used to encrypt communications in the cluster. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-ssl.html # def certificates(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_ssl/certificates" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040361462737751600365420ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/ssl# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SSL module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end terms_enum.rb000066400000000000000000000042741462737751600347100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Actions # The terms enum API can be used to discover terms in the index that begin with the provided string. It is designed for low-latency look-ups used in auto-complete scenarios. # # @option arguments [List] :index A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body field name, string which is the prefix expected in matching terms, timeout and size for max number of results # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-terms-enum.html # def terms_enum(arguments = {}) raise ArgumentError, "Required argument 'index' missing" unless arguments[:index] headers = arguments.delete(:headers) || {} arguments = arguments.clone _index = arguments.delete(:index) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = "#{Elasticsearch::API::Utils.__listify(_index)}/_terms_enum" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end text_structure/000077500000000000000000000000001462737751600353025ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actionsfind_structure.rb000066400000000000000000000112031462737751600406640ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/text_structure# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module TextStructure module Actions # Finds the structure of a text file. The text file must contain data that is suitable to be ingested into Elasticsearch. # # @option arguments [Integer] :lines_to_sample How many lines of the file should be included in the analysis # @option arguments [Integer] :line_merge_size_limit Maximum number of characters permitted in a single message when lines are merged to create messages. # @option arguments [Time] :timeout Timeout after which the analysis will be aborted # @option arguments [String] :charset Optional parameter to specify the character set of the file # @option arguments [String] :format Optional parameter to specify the high level file format (options: ndjson, xml, delimited, semi_structured_text) # @option arguments [Boolean] :has_header_row Optional parameter to specify whether a delimited file includes the column names in its first row # @option arguments [List] :column_names Optional parameter containing a comma separated list of the column names for a delimited file # @option arguments [String] :delimiter Optional parameter to specify the delimiter character for a delimited file - must be a single character # @option arguments [String] :quote Optional parameter to specify the quote character for a delimited file - must be a single character # @option arguments [Boolean] :should_trim_fields Optional parameter to specify whether the values between delimiters in a delimited file should have whitespace trimmed from them # @option arguments [String] :grok_pattern Optional parameter to specify the Grok pattern that should be used to extract fields from messages in a semi-structured text file # @option arguments [String] :timestamp_field Optional parameter to specify the timestamp field in the file # @option arguments [String] :timestamp_format Optional parameter to specify the timestamp format in the file - may be either a Joda or Java time format # @option arguments [Boolean] :explain Whether to include a commentary on how the structure was derived # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The contents of the file to be analyzed (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/find-structure.html # def find_structure(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_text_structure/find_structure" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] if body.is_a? Array payload = Elasticsearch::API::Utils.__bulkify(body) else payload = body end headers = Elasticsearch::API::Utils.ndjson_headers(headers) perform_request(method, path, params, payload, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:find_structure, [ :lines_to_sample, :line_merge_size_limit, :timeout, :charset, :format, :has_header_row, :column_names, :delimiter, :quote, :should_trim_fields, :grok_pattern, :timestamp_field, :timestamp_format, :explain ].freeze) end end end end end params_registry.rb000066400000000000000000000040501462737751600410410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/text_structure# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module TextStructure module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end transform/000077500000000000000000000000001462737751600342115ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actionsdelete_transform.rb000066400000000000000000000046611462737751600401020ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/transform# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Transform module Actions # Deletes an existing transform. # # @option arguments [String] :transform_id The id of the transform to delete # @option arguments [Boolean] :force When `true`, the transform is deleted regardless of its current state. The default value is `false`, meaning that the transform must be `stopped` before it can be deleted. # @option arguments [Time] :timeout Controls the time to wait for the transform deletion # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/delete-transform.html # def delete_transform(arguments = {}) raise ArgumentError, "Required argument 'transform_id' missing" unless arguments[:transform_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_DELETE path = "_transform/#{Elasticsearch::API::Utils.__listify(_transform_id)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:delete_transform, [ :force, :timeout ].freeze) end end end end end get_transform.rb000066400000000000000000000054301462737751600374120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/transform# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Transform module Actions # Retrieves configuration information for transforms. # # @option arguments [String] :transform_id The id or comma delimited list of id expressions of the transforms to get, '_all' or '*' implies get all transforms # @option arguments [Integer] :from skips a number of transform configs, defaults to 0 # @option arguments [Integer] :size specifies a max number of transforms to get, defaults to 100 # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no transforms. (This includes `_all` string or when no transforms have been specified) # @option arguments [Boolean] :exclude_generated Omits fields that are illegal to set on transform PUT # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-transform.html # def get_transform(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_GET path = if _transform_id "_transform/#{Elasticsearch::API::Utils.__listify(_transform_id)}" else "_transform" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_transform, [ :from, :size, :allow_no_match, :exclude_generated ].freeze) end end end end end get_transform_stats.rb000066400000000000000000000051501462737751600406270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/transform# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Transform module Actions # Retrieves usage information for transforms. # # @option arguments [String] :transform_id The id of the transform for which to get stats. '_all' or '*' implies all transforms # @option arguments [Number] :from skips a number of transform stats, defaults to 0 # @option arguments [Number] :size specifies a max number of transform stats to get, defaults to 100 # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no transforms. (This includes `_all` string or when no transforms have been specified) # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/get-transform-stats.html # def get_transform_stats(arguments = {}) raise ArgumentError, "Required argument 'transform_id' missing" unless arguments[:transform_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_GET path = "_transform/#{Elasticsearch::API::Utils.__listify(_transform_id)}/_stats" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:get_transform_stats, [ :from, :size, :allow_no_match ].freeze) end end end end end params_registry.rb000066400000000000000000000040441462737751600377530ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/transform# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Transform module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end preview_transform.rb000066400000000000000000000047141462737751600403200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/transform# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Transform module Actions # Previews a transform. # # @option arguments [String] :transform_id The id of the transform to preview. # @option arguments [Time] :timeout Controls the time to wait for the preview # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The definition for the transform to preview # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/preview-transform.html # def preview_transform(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = if _transform_id "_transform/#{Elasticsearch::API::Utils.__listify(_transform_id)}/_preview" else "_transform/_preview" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:preview_transform, [ :timeout ].freeze) end end end end end put_transform.rb000066400000000000000000000050141462737751600374410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/transform# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Transform module Actions # Instantiates a transform. # # @option arguments [String] :transform_id The id of the new transform. # @option arguments [Boolean] :defer_validation If validations should be deferred until transform starts, defaults to false. # @option arguments [Time] :timeout Controls the time to wait for the transform to start # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The transform definition (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/put-transform.html # def put_transform(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'transform_id' missing" unless arguments[:transform_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_PUT path = "_transform/#{Elasticsearch::API::Utils.__listify(_transform_id)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_transform, [ :defer_validation, :timeout ].freeze) end end end end end start_transform.rb000066400000000000000000000043031462737751600377660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/transform# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Transform module Actions # Starts one or more transforms. # # @option arguments [String] :transform_id The id of the transform to start # @option arguments [Time] :timeout Controls the time to wait for the transform to start # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/start-transform.html # def start_transform(arguments = {}) raise ArgumentError, "Required argument 'transform_id' missing" unless arguments[:transform_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_POST path = "_transform/#{Elasticsearch::API::Utils.__listify(_transform_id)}/_start" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:start_transform, [ :timeout ].freeze) end end end end end stop_transform.rb000066400000000000000000000056571462737751600376330ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/transform# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Transform module Actions # Stops one or more transforms. # # @option arguments [String] :transform_id The id of the transform to stop # @option arguments [Boolean] :force Whether to force stop a failed transform or not. Default to false # @option arguments [Boolean] :wait_for_completion Whether to wait for the transform to fully stop before returning or not. Default to false # @option arguments [Time] :timeout Controls the time to wait until the transform has stopped. Default to 30 seconds # @option arguments [Boolean] :allow_no_match Whether to ignore if a wildcard expression matches no transforms. (This includes `_all` string or when no transforms have been specified) # @option arguments [Boolean] :wait_for_checkpoint Whether to wait for the transform to reach a checkpoint before stopping. Default to false # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/stop-transform.html # def stop_transform(arguments = {}) raise ArgumentError, "Required argument 'transform_id' missing" unless arguments[:transform_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_POST path = "_transform/#{Elasticsearch::API::Utils.__listify(_transform_id)}/_stop" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:stop_transform, [ :force, :wait_for_completion, :timeout, :allow_no_match, :wait_for_checkpoint ].freeze) end end end end end update_transform.rb000066400000000000000000000050631462737751600401170ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/transform# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Transform module Actions # Updates certain properties of a transform. # # @option arguments [String] :transform_id The id of the transform. (*Required*) # @option arguments [Boolean] :defer_validation If validations should be deferred until transform starts, defaults to false. # @option arguments [Time] :timeout Controls the time to wait for the update # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The update transform definition (*Required*) # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/update-transform.html # def update_transform(arguments = {}) raise ArgumentError, "Required argument 'body' missing" unless arguments[:body] raise ArgumentError, "Required argument 'transform_id' missing" unless arguments[:transform_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _transform_id = arguments.delete(:transform_id) method = Elasticsearch::API::HTTP_POST path = "_transform/#{Elasticsearch::API::Utils.__listify(_transform_id)}/_update" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:update_transform, [ :defer_validation, :timeout ].freeze) end end end end end upgrade_transforms.rb000066400000000000000000000040021462737751600404370ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/transform# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Transform module Actions # Upgrades all transforms. # # @option arguments [Boolean] :dry_run Whether to only check for updates but don't execute # @option arguments [Time] :timeout Controls the time to wait for the upgrade # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/upgrade-transforms.html # def upgrade_transforms(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_transform/_upgrade" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:upgrade_transforms, [ :dry_run, :timeout ].freeze) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/usage.rb000066400000000000000000000035011462737751600337050ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Actions # Retrieves usage information about the installed X-Pack features. # # @option arguments [Time] :master_timeout Specify timeout for watch write operation # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/usage-api.html # def usage(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_GET path = "_xpack/usage" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:usage, [ :master_timeout ].freeze) end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/watcher/000077500000000000000000000000001462737751600337125ustar00rootroot00000000000000ack_watch.rb000066400000000000000000000042751462737751600361140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/watcher# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Watcher module Actions # Acknowledges a watch, manually throttling the execution of the watch's actions. # # @option arguments [String] :watch_id Watch ID # @option arguments [List] :action_id A comma-separated list of the action ids to be acked # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/watcher-api-ack-watch.html # def ack_watch(arguments = {}) raise ArgumentError, "Required argument 'watch_id' missing" unless arguments[:watch_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _watch_id = arguments.delete(:watch_id) _action_id = arguments.delete(:action_id) method = Elasticsearch::API::HTTP_PUT path = if _watch_id && _action_id "_watcher/watch/#{Elasticsearch::API::Utils.__listify(_watch_id)}/_ack/#{Elasticsearch::API::Utils.__listify(_action_id)}" else "_watcher/watch/#{Elasticsearch::API::Utils.__listify(_watch_id)}/_ack" end params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end activate_watch.rb000066400000000000000000000034171462737751600371530ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/watcher# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Watcher module Actions # Activates a currently inactive watch. # # @option arguments [String] :watch_id Watch ID # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/watcher-api-activate-watch.html # def activate_watch(arguments = {}) raise ArgumentError, "Required argument 'watch_id' missing" unless arguments[:watch_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _watch_id = arguments.delete(:watch_id) method = Elasticsearch::API::HTTP_PUT path = "_watcher/watch/#{Elasticsearch::API::Utils.__listify(_watch_id)}/_activate" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end deactivate_watch.rb000066400000000000000000000034251462737751600374630ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/watcher# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Watcher module Actions # Deactivates a currently active watch. # # @option arguments [String] :watch_id Watch ID # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/watcher-api-deactivate-watch.html # def deactivate_watch(arguments = {}) raise ArgumentError, "Required argument 'watch_id' missing" unless arguments[:watch_id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _watch_id = arguments.delete(:watch_id) method = Elasticsearch::API::HTTP_PUT path = "_watcher/watch/#{Elasticsearch::API::Utils.__listify(_watch_id)}/_deactivate" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end delete_watch.rb000066400000000000000000000036601462737751600366150ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/watcher# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Watcher module Actions # Removes a watch from Watcher. # # @option arguments [String] :id Watch ID # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/watcher-api-delete-watch.html # def delete_watch(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_DELETE path = "_watcher/watch/#{Elasticsearch::API::Utils.__listify(_id)}" params = {} body = nil if Array(arguments[:ignore]).include?(404) Elasticsearch::API::Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body } else perform_request(method, path, params, body, headers).body end end end end end end end execute_watch.rb000066400000000000000000000043671462737751600370220ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/watcher# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Watcher module Actions # Forces the execution of a stored watch. # # @option arguments [String] :id Watch ID # @option arguments [Boolean] :debug indicates whether the watch should execute in debug mode # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body Execution control # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/watcher-api-execute-watch.html # def execute_watch(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_PUT path = if _id "_watcher/watch/#{Elasticsearch::API::Utils.__listify(_id)}/_execute" else "_watcher/watch/_execute" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:execute_watch, [ :debug ].freeze) end end end end end get_watch.rb000066400000000000000000000033161462737751600361300ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/watcher# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Watcher module Actions # Retrieves a watch by its ID. # # @option arguments [String] :id Watch ID # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/watcher-api-get-watch.html # def get_watch(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_GET path = "_watcher/watch/#{Elasticsearch::API::Utils.__listify(_id)}" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end params_registry.rb000066400000000000000000000040421462737751600373730ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/watcher# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Watcher module Actions module ParamsRegistry extend self # A Mapping of all the actions to their list of valid params. # # @since 7.4.0 PARAMS = {} # Register an action with its list of valid params. # # @example Register the action. # ParamsRegistry.register(:benchmark, [ :verbose ]) # # @param [ Symbol ] action The action to register. # @param [ Array[Symbol] ] valid_params The list of valid params. # # @since 7.4.0 def register(action, valid_params) PARAMS[action.to_sym] = valid_params end # Get the list of valid params for a given action. # # @example Get the list of valid params. # ParamsRegistry.get(:benchmark) # # @param [ Symbol ] action The action. # # @return [ Array ] The list of valid params for the action. # # @since 7.4.0 def get(action) PARAMS.fetch(action, []) end end end end end end end put_watch.rb000066400000000000000000000052321462737751600361600ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/watcher# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Watcher module Actions # Creates a new watch, or updates an existing one. # # @option arguments [String] :id Watch ID # @option arguments [Boolean] :active Specify whether the watch is in/active by default # @option arguments [Number] :version Explicit version number for concurrency control # @option arguments [Number] :if_seq_no only update the watch if the last operation that has changed the watch has the specified sequence number # @option arguments [Number] :if_primary_term only update the watch if the last operation that has changed the watch has the specified primary term # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body The watch # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/watcher-api-put-watch.html # def put_watch(arguments = {}) raise ArgumentError, "Required argument 'id' missing" unless arguments[:id] headers = arguments.delete(:headers) || {} arguments = arguments.clone _id = arguments.delete(:id) method = Elasticsearch::API::HTTP_PUT path = "_watcher/watch/#{Elasticsearch::API::Utils.__listify(_id)}" params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = arguments[:body] perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:put_watch, [ :active, :version, :if_seq_no, :if_primary_term ].freeze) end end end end end query_watches.rb000066400000000000000000000033571462737751600370530ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/watcher# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Watcher module Actions # Retrieves stored watches. # # @option arguments [Hash] :headers Custom HTTP headers # @option arguments [Hash] :body From, size, query, sort and search_after # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/watcher-api-query-watches.html # def query_watches(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = if arguments[:body] Elasticsearch::API::HTTP_POST else Elasticsearch::API::HTTP_GET end path = "_watcher/_query/watches" params = {} body = arguments[:body] perform_request(method, path, params, body, headers).body end end end end end end start.rb000066400000000000000000000027661462737751600353300ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/watcher# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Watcher module Actions # Starts Watcher if it is not already running. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/watcher-api-start.html # def start(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_watcher/_start" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end stats.rb000066400000000000000000000044671462737751600353310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/watcher# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Watcher module Actions # Retrieves the current Watcher metrics. # # @option arguments [List] :metric Controls what additional stat metrics should be include in the response (options: _all, queued_watches, current_watches, pending_watches) # @option arguments [Boolean] :emit_stacktraces Emits stack traces of currently running watches # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/watcher-api-stats.html # def stats(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone _metric = arguments.delete(:metric) method = Elasticsearch::API::HTTP_GET path = if _metric "_watcher/stats/#{Elasticsearch::API::Utils.__listify(_metric)}" else "_watcher/stats" end params = Elasticsearch::API::Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__) body = nil perform_request(method, path, params, body, headers).body end # Register this action with its valid params when the module is loaded. # # @since 6.2.0 ParamsRegistry.register(:stats, [ :metric, :emit_stacktraces ].freeze) end end end end end stop.rb000066400000000000000000000027461462737751600351560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/watcher# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Watcher module Actions # Stops Watcher if it is running. # # @option arguments [Hash] :headers Custom HTTP headers # # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/watcher-api-stop.html # def stop(arguments = {}) headers = arguments.delete(:headers) || {} arguments = arguments.clone method = Elasticsearch::API::HTTP_POST path = "_watcher/_stop" params = {} body = nil perform_request(method, path, params, body, headers).body end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace/000077500000000000000000000000001462737751600325515ustar00rootroot00000000000000async_search.rb000066400000000000000000000022141462737751600354600ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module AsyncSearch module Actions; end class AsyncSearchClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, AsyncSearch::Actions end def async_search @async_search ||= AsyncSearchClient.new(self) end end end end end autoscaling.rb000066400000000000000000000022121462737751600353250ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Autoscaling module Actions; end class AutoscalingClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, Autoscaling::Actions end def autoscaling @autoscaling ||= AutoscalingClient.new(self) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace/cat.rb000066400000000000000000000021771462737751600336540ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Cat module Actions; end class CatClient < Elasticsearch::API::Cat::CatClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, Cat::Actions end def cat @cat ||= CatClient.new(self) end end end end end cross_cluster_replication.rb000066400000000000000000000023261462737751600403050ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module CrossClusterReplication module Actions; end class CrossClusterReplicationClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, CrossClusterReplication::Actions end def cross_cluster_replication @cross_cluster_replication ||= CrossClusterReplicationClient.new(self) end end end end end data_frame.rb000066400000000000000000000022201462737751600350760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Graph module Actions; end class DataFrameClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, DataFrameTransformDeprecated::Actions end def data_frame @data_frame ||= DataFrameClient.new(self) end end end end end enrich.rb000066400000000000000000000021541462737751600342710ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Enrich module Actions; end class EnrichClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, Enrich::Actions end def enrich @enrich ||= EnrichClient.new(self) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace/eql.rb000066400000000000000000000021321462737751600336550ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Eql module Actions; end class EqlClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, Eql::Actions end def eql @eql ||= EqlClient.new(self) end end end end end fleet.rb000066400000000000000000000021461462737751600341210ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Fleet module Actions; end class FleetClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, Fleet::Actions end def fleet @fleet ||= FleetClient.new(self) end end end end end graph.rb000066400000000000000000000021471462737751600341240ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Graph module Actions; end class GraphClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, Graph::Actions end def graph @graph ||= GraphClient.new(self) end end end end end index_lifecycle_management.rb000066400000000000000000000022561462737751600403460ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module IndexLifecycleManagement module Actions; end class IndexLifecycleManagementClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, IndexLifecycleManagement::Actions end def ilm @ilm ||= IndexLifecycleManagementClient.new(self) end end end end end indices.rb000066400000000000000000000022371462737751600344410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Indices module Actions; end class IndicesClient < Elasticsearch::API::Indices::IndicesClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, Indices::Actions end def indices @indices ||= IndicesClient.new(self) end end end end end license.rb000066400000000000000000000021631462737751600344430ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module License module Actions; end class LicenseClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, License::Actions end def license @license ||= LicenseClient.new(self) end end end end end logstash.rb000066400000000000000000000021701462737751600346430ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Logstash module Actions; end class LogstashClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, Logstash::Actions end def logstash @logstash ||= LogstashClient.new(self) end end end end end machine_learning.rb000066400000000000000000000023121462737751600363000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module MachineLearning module Actions; end class MachineLearningClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, MachineLearning::Actions end def machine_learning @machine_learning ||= MachineLearningClient.new(self) end alias :ml :machine_learning end end end end migration.rb000066400000000000000000000021771462737751600350170ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Migration module Actions; end class MigrationClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, Migration::Actions end def migration @migration ||= MigrationClient.new(self) end end end end end monitoring.rb000066400000000000000000000022051462737751600352030ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Monitoring module Actions; end class MonitoringClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, Monitoring::Actions end def monitoring @monitoring ||= MonitoringClient.new(self) end end end end end rollup.rb000066400000000000000000000021551462737751600343370ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Rollup module Actions; end class RollupClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, Rollup::Actions end def rollup @rollup ||= RollupClient.new(self) end end end end end searchable_snapshots.rb000066400000000000000000000022741462737751600372170ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SearchableSnapshots module Actions; end class SearchableSnapshotsClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, SearchableSnapshots::Actions end def searchable_snapshots @searchable_snapshots ||= SearchableSnapshotsClient.new(self) end end end end end security.rb000066400000000000000000000021711462737751600346670ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Security module Actions; end class SecurityClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, Security::Actions end def security @security ||= SecurityClient.new(self) end end end end end snapshot_lifecycle_management.rb000066400000000000000000000023561462737751600410770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SnapshotLifecycleManagement module Actions; end class SnapshotLifecycleManagementClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, SnapshotLifecycleManagement::Actions end def snapshot_lifecycle_management @snapshot_lifecycle_management ||= SnapshotLifecycleManagementClient.new(self) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace/sql.rb000066400000000000000000000021331462737751600336740ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SQL module Actions; end class SQLClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, SQL::Actions end def sql @sql ||= SQLClient.new(self) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace/ssl.rb000066400000000000000000000021321462737751600336750ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module SSL module Actions; end class SSLClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, SSL::Actions end def ssl @ssl ||= SSLClient.new(self) end end end end end text_structure.rb000066400000000000000000000022301462737751600361200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module TextStructure module Actions; end class TextStructureClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, TextStructure::Actions end def text_structure @text_structure ||= TextStructureClient.new(self) end end end end end transform.rb000066400000000000000000000021771462737751600350410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Transform module Actions; end class TransformClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, Transform::Actions end def transform @transform ||= TransformClient.new(self) end end end end end watcher.rb000066400000000000000000000021631462737751600344560ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/api/namespace# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack module API module Watcher module Actions; end class WatcherClient include Elasticsearch::API::Common::Client, Elasticsearch::API::Common::Client::Base, Watcher::Actions end def watcher @watcher ||= WatcherClient.new(self) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/lib/elasticsearch/xpack/version.rb000066400000000000000000000015251462737751600320610ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module XPack VERSION = '7.17.11'.freeze end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/000077500000000000000000000000001462737751600243105ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/rest_yaml_tests_helper.rb000066400000000000000000000111401462737751600314120ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require "#{File.expand_path(File.dirname('..'), '..')}/api-spec-testing/test_file" require "#{File.expand_path(File.dirname('..'), '..')}/api-spec-testing/rspec_matchers" require "#{File.expand_path(File.dirname('..'), '..')}/api-spec-testing/wipe_cluster" require "#{File.expand_path(File.dirname('..'), '..')}/api-spec-testing/wipe_cluster_8" include Elasticsearch::RestAPIYAMLTests def testing_compatibility? [1, true, 'true'].include?(ENV['ELASTIC_CLIENT_APIVERSIONING']) end PROJECT_PATH = File.join(File.dirname(__FILE__), '..', '..') TRANSPORT_OPTIONS = if [true, 'true', 1].include? ENV['ELASTIC_CLIENT_APIVERSIONING'] { headers: { 'Accept' => 'application/vnd.elasticsearch+json; compatible-with=7,text/plain' } } else {} end TEST_SUITE = ENV['TEST_SUITE'].freeze || 'platinum' STACK_VERSION = ENV['STACK_VERSION'] if hosts = ENV['TEST_ES_SERVER'] || ENV['ELASTICSEARCH_HOSTS'] split_hosts = hosts.split(',').map do |host| /(http\:s?\/\/)?\S+/.match(host) end uri = URI.parse(split_hosts.first[0]) TEST_HOST = uri.host TEST_PORT = uri.port else TEST_HOST, TEST_PORT = 'localhost', '9200' end raw_certificate = File.read(File.join(PROJECT_PATH, '.ci/certs/testnode.crt')) certificate = OpenSSL::X509::Certificate.new(raw_certificate) raw_key = File.read(File.join(PROJECT_PATH, '/.ci/certs/testnode.key')) key = OpenSSL::PKey::RSA.new(raw_key) ca_file = File.join(PROJECT_PATH, '/.ci/certs/ca.crt') if defined?(TEST_HOST) && defined?(TEST_PORT) if TEST_SUITE == 'platinum' TRANSPORT_OPTIONS.merge!( ssl: { verify: false, client_cert: certificate, client_key: key, ca_file: ca_file } ) password = ENV['ELASTIC_PASSWORD'] || 'changeme' URL = "https://elastic:#{password}@#{TEST_HOST}:#{TEST_PORT}" else URL = "http://#{TEST_HOST}:#{TEST_PORT}" end ADMIN_CLIENT = Elasticsearch::Client.new(host: URL, transport_options: TRANSPORT_OPTIONS) if ENV['QUIET'] == 'true' DEFAULT_CLIENT = Elasticsearch::Client.new(host: URL, transport_options: TRANSPORT_OPTIONS) else DEFAULT_CLIENT = Elasticsearch::Client.new(host: URL, transport_options: TRANSPORT_OPTIONS, tracer: Logger.new($stdout)) end end tests_dir = testing_compatibility? ? 'compatTest' : 'test' YAML_FILES_DIRECTORY = "#{PROJECT_PATH}/tmp/rest-api-spec/#{tests_dir}/platinum".freeze SINGLE_TEST = if ENV['SINGLE_TEST'] && !ENV['SINGLE_TEST'].empty? test_target = ENV['SINGLE_TEST'] path = File.expand_path(File.dirname('..')) if test_target.match?(/\.yml$/) ["#{path}/../tmp/rest-api-spec/#{tests_dir}/platinum/#{test_target}"] else Dir.glob( ["#{PROJECT_PATH}/tmp/rest-api-spec/#{tests_dir}/platinum/#{test_target}/**/*.yml"] ) end end # Skipped tests file = File.expand_path(__dir__ + '/skipped_tests.yml') skipped_tests = YAML.load_file(file) skipped_tests.concat YAML.load_file(File.expand_path(__dir__ + '/skipped_tests_8.yml')) if testing_compatibility? # The directory of rest api YAML files. REST_API_YAML_FILES = if ENV['RUN_SKIPPED_TESTS'] # only run the skipped tests if true SKIPPED_TESTS = [] skipped_tests.map { |test| "#{YAML_FILES_DIRECTORY}/#{test[:file]}" } else # If not, define the skipped tests constant and try the single test or all # the tests SKIPPED_TESTS = skipped_tests SINGLE_TEST || Dir.glob("#{YAML_FILES_DIRECTORY}/**/*.yml") end # The features to skip REST_API_YAML_SKIP_FEATURES = ['warnings', 'node_selector'].freeze elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/skipped_tests.yml000066400000000000000000000026001462737751600277120ustar00rootroot00000000000000# Respone from Elasticsearch includes the ca.crt, so length doesn't match. - :file: 'ssl/10_basic.yml' :description: 'Test get SSL certificates' # Feature is currently experimental. - :file: 'ml/data_frame_analytics_crud.yml' :description: '*' # TODO: Failing due to processing of regexp in test - :file: 'ml/explain_data_frame_analytics.yml' :description: 'Test non-empty data frame given body' # TODO https://github.com/elastic/elasticsearch-ruby/issues/852 - :file: 'analytics/usage.yml' :description: 'Usage stats on analytics indices' # TODO https://github.com/elastic/elasticsearch-ruby/issues/1269 - :file: 'searchable_snapshots/10_usage.yml' :description: 'Tests searchable snapshots usage stats with full_copy and shared_cache indices' # TODO https://github.com/elastic/elasticsearch-ruby/issues/1291 - :file: 'service_accounts/10_basic.yml' :description: 'Test service account tokens' # TODO: https://github.com/elastic/elasticsearch-ruby/issues/1393 - :file: 'ml/jobs_crud.yml' :description: 'Test put job with datafeed with indices options in params' # TODO: https://github.com/elastic/elasticsearch-ruby/issues/1539 - :file: 'ml/categorization_agg.yml' :description: 'Test categorization aggregation with poor settings' - :file: 'data_stream/80_resolve_index_data_streams.yml' :description: 'Resolve index with hidden and closed indices' elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/skipped_tests_8.yml000066400000000000000000000132521462737751600301460ustar00rootroot00000000000000# error: "no handler found for uri [/.ds-simple-data-stream1-%2A000001/_freeze] and method [POST]" - :file: 'indices.freeze/10_basic.yml' :description: 'Cannot freeze write index for data stream' # Expected Length (11) is 12 - :file: 'license/20_put_license.yml' :description: 'Installing and getting license works' - :file: 'license/20_put_license.yml' :description: 'Should install a feature type license' # error: "The [accept_enterprise] parameters may not be false" - :file: 'license/30_enterprise_license.yml' :description: 'Installing enterprise license' # "estimated_heap_memory_usage_bytes" expected to be true, but field not present in response - :file: 'ml/inference_crud.yml' :description: 'Test put model' # error: "no handler found for uri [/foo/doc/1] and method [PUT] - :file: 'roles/11_idx_arrays.yml' :description: 'Test put role api using as array of index names' # error: "[date_histogram] unknown field [interval] did you mean [fixed_interval]?" - :file: 'rollup/rollup_search.yml' :description: 'Search error no matching indices' # Issues with response type - :file: 'security/authz/14_cat_indices.yml' :description: 'Test empty request while no-authorized index' - :file: 'security/authz/14_cat_indices.yml' :description: 'Test empty request while single authorized index' - :file: 'security/authz/14_cat_indices.yml' :description: 'Test explicit request while multiple authorized indices' - :file: 'security/authz/14_cat_indices.yml' :description: 'Test explicit request while multiple opened/closed authorized indices' - :file: 'security/authz/14_cat_indices.yml' :description: 'Test wildcard request with multiple authorized indices' # error: "Action/metadata line [1] contains an unknown parameter [_type]" - :file: 'sql/sql.yml' :description: 'Execute some SQL' - :file: 'sql/sql.yml' :description: 'Paging through results' - :file: 'sql/sql.yml' :description: 'Clean cursor' - :file: 'sql/sql.yml' :description: 'Getting textual representation' - :file: 'sql/translate.yml' :description: 'Translate SQL' # error: request [/test-index] contains unrecognized parameter: [include_type_name] - :file: 'vectors/10_dense_vector_basic.yml' :description: 'Dot Product' - :file: 'vectors/10_dense_vector_basic.yml' :description: 'Cosine Similarity' - :file: 'vectors/20_dense_vector_special_cases.yml' :description: "Indexing of Dense vectors should error when dims don't match defined in the mapping" - :file: 'vectors/20_dense_vector_special_cases.yml' :description: 'Vectors of mixed integers and floats' - :file: 'vectors/20_dense_vector_special_cases.yml' :description: 'Functions with query vectors with dims different from docs vectors should error' - :file: 'vectors/20_dense_vector_special_cases.yml' :description: 'Dense vectors should error with sparse vector functions' - :file: 'vectors/20_dense_vector_special_cases.yml' :description: 'Documents missing a vector field' - :file: 'vectors/15_dense_vector_l1l2.yml' :description: 'L1 norm' - :file: 'vectors/15_dense_vector_l1l2.yml' :description: 'L2 norm' # Matching error incorrectly - :file: 'aggregate-metrics/90_tsdb_mappings.yml' :description: 'aggregate_double_metric with wrong time series mappings' - :file: 'analytics/histogram.yml' :description: 'histogram with wrong time series mappings' - :file: 'api_key/10_basic.yml' :description: 'Test get api key' - :file: 'api_key/11_invalidation.yml' :description: 'Test invalidate api key by realm name' - :file: 'api_key/20_query.yml' :description: 'Test query api key' - :file: 'data_stream/80_resolve_index_data_streams.yml' :description: 'Resolve index with hidden and closed indices' - :file: 'eql/10_basic.yml' :description: 'EQL status API' - :file: 'ml/get_trained_model_stats.yml' :description: 'Test get stats given expression without matches and allow_no_match is false' - :file: 'ml/get_trained_model_stats.yml' :description: 'Test get stats given expression without matches and allow_no_match is true' - :file: 'ml/get_trained_model_stats.yml' :description: 'Test get stats given trained models' - :file: 'ml/inference_crud.yml' :description: '*' - :file: 'ml/inference_processor.yml' :description: 'Test simulate' - :file: 'snapshot/10_basic.yml' :description: 'Create a source only snapshot and then restore it' - :file: 'snapshot/20_operator_privileges_disabled.yml' :description: 'Operator only settings can be set and restored by non-operator user when operator privileges is disabled' - :file: 'token/10_basic.yml' :description: "Test invalidate user's tokens" - :file: 'token/10_basic.yml' :description: "Test invalidate realm's tokens" - :file: 'token/11_invalidation.yml' :description: 'Test invalidate access token return statuses' - :file: 'token/11_invalidation.yml' :description: 'Test invalidate refresh token return statuses' - :file: 'analytics/boxplot.yml' :description: '*' - :file: 'analytics/moving_percentile.yml' :description: 'Basic Search TDigest' - :file: 'ml/evaluate_data_frame.yml' :description: 'Test outlier_detection auc_roc' - :file: 'ml/evaluate_data_frame.yml' :description: 'Test outlier_detection auc_roc given actual_field is int' - :file: 'ml/evaluate_data_frame.yml' :description: 'Test outlier_detection auc_roc include curve' - :file: 'ml/evaluate_data_frame.yml' :description: 'Test outlier_detection auc_roc with default top_classes_field' - :file: 'ml/evaluate_data_frame.yml' :description: 'Test classification auc_roc' - :file: 'ml/evaluate_data_frame.yml' :description: 'Test classification auc_roc with default top_classes_field' elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/spec_helper.rb000066400000000000000000000037041462737751600271320ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. if defined?(JRUBY_VERSION) require 'pry-nav' else require 'pry-byebug' end require 'yaml' require 'elasticsearch' require 'elasticsearch/xpack' require 'logger' require 'openssl' module HelperModule def self.included(context) context.let(:client_double) do Class.new { include Elasticsearch::XPack::API }.new.tap do |client| expect(client).to receive(:perform_request).with(*expected_args).and_return(response_double) end end context.let(:client) do Class.new { include Elasticsearch::XPack::API }.new.tap do |client| expect(client).to receive(:perform_request).with(*expected_args).and_return(response_double) end end context.let(:response_double) do double('response', status: 200, body: {}, headers: {}) end end end RSpec.configure do |config| config.include(HelperModule) config.formatter = 'documentation' config.color = true config.add_formatter('RspecJunitFormatter', '../elasticsearch-api/tmp/elasticsearch-xpack-junit.xml') config.add_formatter( 'RSpec::Core::Formatters::HtmlFormatter', "../elasticsearch-api/tmp/elasticsearch-#{ENV['TEST_SUITE']}-#{RUBY_VERSION}-#{ENV['STACK_VERSION']}.html" ) end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/000077500000000000000000000000001462737751600254165ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/data_frame/000077500000000000000000000000001462737751600275015ustar00rootroot00000000000000update_data_frame_transform_spec.rb000066400000000000000000000040001462737751600364730ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/data_frame# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#update_data_frame_transform' do let(:expected_args) do [ 'POST', '_data_frame/transforms/foo/_update', params, {}, {} ] end let(:params) do {} end it 'performs the request' do expect(client_double.data_frame. update_transform(transform_id: 'foo', body: {})).to eq({}) end context 'when body is not provided' do let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'raises an exception' do expect { client.data_frame.update_transform(transform_id: 'foo') }.to raise_exception(ArgumentError) end end context 'when a transform_id is not provided' do let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'raises an exception' do expect { client.data_frame.update_transform(body: {}) }.to raise_exception(ArgumentError) end end context 'when params are specified' do let(:params) do { defer_validation: true } end it 'performs the request' do expect(client_double.data_frame. update_transform(transform_id: 'foo', body: {}, defer_validation: true)).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/fleet/000077500000000000000000000000001462737751600265155ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/fleet/global_checkpoints_spec.rb000066400000000000000000000024311462737751600337060ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#fleet.global_checkpoints' do let(:expected_args) do [ 'GET', 'foo/_fleet/global_checkpoints', {}, nil, {} ] end it 'performs the request' do expect(client_double.fleet.global_checkpoints(index: 'foo')).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'requires the :index argument' do expect { client.fleet.global_checkpoints }.to raise_exception(ArgumentError) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/fleet/msearch_spec.rb000066400000000000000000000024251462737751600315010ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#fleet.msearch' do let(:expected_args) do [ 'POST', '_fleet/_fleet_msearch', {}, {}, { 'Content-Type' => 'application/x-ndjson' } ] end it 'performs the request' do expect(client_double.fleet.msearch(body: {})).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'requires the :body argument' do expect { client.fleet.msearch }.to raise_exception(ArgumentError) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/fleet/search_spec.rb000066400000000000000000000023601462737751600313220ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#fleet.search' do let(:expected_args) do [ 'GET', 'foo/_fleet/_fleet_search', {}, nil, {} ] end it 'performs the request' do expect(client_double.fleet.search(index: 'foo')).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'requires the :index argument' do expect { client.fleet.search }.to raise_exception(ArgumentError) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/freeze_spec.rb000066400000000000000000000036171462737751600302440ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#freeze' do let(:expected_args) do [ 'POST', url, params, nil, {} ] end let(:params) do {} end context 'when there is no index specified' do let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'raises an exception' do expect { client.indices.freeze }.to raise_exception(ArgumentError) end end context 'when an index is specified' do let(:url) do 'foo/_freeze' end it 'performs the request' do expect(client_double.indices.freeze(index: 'foo')).to eq({}) end end context 'when params are specified' do let(:params) do { timeout: '1s' } end let(:url) do 'foo/_freeze' end it 'performs the request' do expect(client_double.indices.freeze(index: 'foo', timeout: '1s')).to eq({}) end end context 'when the path must be URL-escaped' do let(:url) do 'foo%5Ebar/_freeze' end it 'performs the request' do expect(client_double.indices.freeze(index: 'foo^bar')).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/index_lifecycle_management/000077500000000000000000000000001462737751600327405ustar00rootroot00000000000000migrate_to_data_tiers_spec.rb000066400000000000000000000021411462737751600405470ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.index_lifecycle_management#migrate_to_data_tiers' do let(:expected_args) do [ 'POST', '_ilm/migrate_to_data_tiers', {}, nil, {} ] end let(:index) { 'foo' } it 'performs the request' do expect(client_double.ilm.migrate_to_data_tiers).to eq({}) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/machine_learning/000077500000000000000000000000001462737751600307015ustar00rootroot00000000000000get_model_snapshot_upgrade_stats_spec.rb000066400000000000000000000033111462737751600407620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#ml.get_model_snapshot_upgrade_stats' do let(:expected_args) do [ 'GET', '_ml/anomaly_detectors/foo/model_snapshots/bar/_upgrade/_stats', {}, nil, {} ] end it 'performs the request' do expect( client_double.machine_learning.get_model_snapshot_upgrade_stats(job_id: 'foo', snapshot_id: 'bar') ).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end context 'when a job_id is not provided' do it 'raises an exception' do expect { client.machine_learning.get_model_snapshot_upgrade_stats(snapshot_id: 'foo') }.to raise_exception(ArgumentError) end end context 'when a snapshot_id is not provided' do it 'raises an exception' do expect { client.machine_learning.get_model_snapshot_upgrade_stats(job_id: 'foo') }.to raise_exception(ArgumentError) end end end infer_trained_model_deployment_spec.rb000066400000000000000000000025711462737751600404170ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#ml.infer_trained_model_deployment' do let(:expected_args) do [ 'POST', '_ml/trained_models/foo/deployment/_infer', {}, nil, {} ] end it 'performs the request' do expect(client_double.ml.infer_trained_model_deployment(model_id: 'foo')).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end context 'when a model_id is not provided' do it 'raises an exception' do expect { client.ml.infer_trained_model_deployment }.to raise_exception(ArgumentError) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/machine_learning/reset_job_spec.rb000066400000000000000000000024561462737751600342230ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#ml.reset_job' do let(:expected_args) do [ 'POST', '_ml/anomaly_detectors/foo/_reset', {}, nil, {} ] end it 'performs the request' do expect(client_double.ml.reset_job(job_id: 'foo')).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end context 'when a job_id is not provided' do it 'raises an exception' do expect { client.ml.reset_job }.to raise_exception(ArgumentError) end end end set_upgrade_mode_spec.rb000066400000000000000000000025741462737751600354770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#set_upgrade_mode' do let(:expected_args) do [ 'POST', '_ml/set_upgrade_mode', {}, nil, {} ] end it 'performs the request' do expect(client_double.ml.set_upgrade_mode).to eq({}) end context 'when params are specified' do let(:expected_args) do [ 'POST', '_ml/set_upgrade_mode', { enabled: true, timeout: '10m' }, nil, {} ] end it 'performs the request' do expect(client_double.ml.set_upgrade_mode(enabled: true, timeout: '10m')).to eq({}) end end end start_trained_model_deployment_spec.rb000066400000000000000000000025711462737751600404510ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#ml.start_trained_model_deployment' do let(:expected_args) do [ 'POST', '_ml/trained_models/foo/deployment/_start', {}, nil, {} ] end it 'performs the request' do expect(client_double.ml.start_trained_model_deployment(model_id: 'foo')).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end context 'when a model_id is not provided' do it 'raises an exception' do expect { client.ml.start_trained_model_deployment }.to raise_exception(ArgumentError) end end end stop_trained_model_deployment_spec.rb000066400000000000000000000025651462737751600403040ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#ml.stop_trained_model_deployment' do let(:expected_args) do [ 'POST', '_ml/trained_models/foo/deployment/_stop', {}, nil, {} ] end it 'performs the request' do expect(client_double.ml.stop_trained_model_deployment(model_id: 'foo')).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end context 'when a model_id is not provided' do it 'raises an exception' do expect { client.ml.stop_trained_model_deployment }.to raise_exception(ArgumentError) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/migration/000077500000000000000000000000001462737751600274075ustar00rootroot00000000000000get_feature_upgrade_status_spec.rb000066400000000000000000000021061462737751600362720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/migration# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#migration.get_feature_upgrade_status' do let(:expected_args) do [ 'GET', '_migration/system_features', {}, nil, {} ] end it 'performs the request' do expect(client_double.migration.get_feature_upgrade_status).to eq({}) end end post_feature_upgrade_spec.rb000066400000000000000000000020731462737751600351000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/migration# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#migration.post_feature_upgrade' do let(:expected_args) do [ 'POST', '_migration/system_features', {}, nil, {} ] end it 'performs the request' do expect(client_double.migration.post_feature_upgrade).to eq({}) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/rest_api_yaml_spec.rb000066400000000000000000000165041462737751600316130ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' require 'rest_yaml_tests_helper' describe 'XPack Rest API YAML tests' do if REST_API_YAML_FILES.empty? logger = Logger.new($stdout) logger.error 'No test files found!' logger.info 'Use rake rake elasticsearch:download_artifacts in the root directory of the project to download the test artifacts.' exit 1 end REST_API_YAML_FILES.each do |file| begin test_file = Elasticsearch::RestAPIYAMLTests::TestFile.new(file, ADMIN_CLIENT, REST_API_YAML_SKIP_FEATURES) rescue SkipTestsException => _e # If the test file has a `skip` at the top level that applies to this # version of Elasticsearch, continue with the next text. logger = Logger.new($stdout) logger.info("Skipping test #{file}") next end ctx = file.gsub("#{YAML_FILES_DIRECTORY}/", '') context ctx do before(:all) do # Runs once before all tests in a test file if testing_compatibility? Elasticsearch::RestAPIYAMLTests::WipeCluster8.run(ADMIN_CLIENT) else Elasticsearch::RestAPIYAMLTests::WipeCluster.run(ADMIN_CLIENT) end end test_file.tests.each do |test| context "#{test.description}" do if test.skip_test?(ADMIN_CLIENT) skip 'Test contains feature(s) not yet supported or version is not satisfied' else let(:client) do DEFAULT_CLIENT end # Runs once before each test in a test file before(:all) do begin # watcher/get_watch/30_with_chain_input.yml needs to have a teardown deleting my_watch. ADMIN_CLIENT.xpack.watcher.delete_watch(id: 'my_watch') rescue Elasticsearch::Transport::Transport::Errors::NotFound end test_file.setup end after(:all) do test_file.teardown if testing_compatibility? Elasticsearch::RestAPIYAMLTests::WipeCluster8.run(ADMIN_CLIENT) else Elasticsearch::RestAPIYAMLTests::WipeCluster.run(ADMIN_CLIENT) end end test.task_groups.each do |task_group| before do task_group.run(client) end # 'catch' is in the task group definition if task_group.catch_exception? it 'sends the request and throws the expected error' do expect(task_group.exception).to match_error(task_group.expected_exception_message) end # 'match' on error description is in the task group definition if task_group.has_match_clauses? task_group.match_clauses.each do |match| it 'contains the expected error in the request response' do expect(task_group.exception.message).to match(Regexp.new(Regexp.escape(match['match'].values.first.to_s))) end end end else # 'match' is in the task group definition if task_group.has_match_clauses? task_group.match_clauses.each do |match| it "has the expected value (#{match['match'].values.join(',')}) in the response field (#{match['match'].keys.join(',')})" do expect(task_group.response).to match_response(match['match'], test) end end end # 'length' is in the task group definition if task_group.has_length_match_clauses? task_group.length_match_clauses.each do |match| it "the '#{match['length'].keys.join(',')}' field have the expected length" do expect(task_group.response).to match_response_field_length(match['length'], test) end end end # 'is_true' is in the task group definition if task_group.has_true_clauses? task_group.true_clauses.each do |match| it 'sends the request and the response fields have the expected fields set to true' do expect(task_group.response).to match_true_field(match['is_true'], test) end end end # 'is_false' is in the task group definition if task_group.has_false_clauses? task_group.false_clauses.each do |match| it 'sends the request and the response fields have the expected fields set to false' do expect(task_group.response).to match_false_field(match['is_false'], test) end end end # 'gte' is in the task group definition if task_group.has_gte_clauses? task_group.gte_clauses.each do |match| it 'sends the request and the response fields have values greater than or equal to the expected values' do expect(task_group.response).to match_gte_field(match['gte'], test) end end end # 'gt' is in the task group definition if task_group.has_gt_clauses? task_group.gt_clauses.each do |match| it 'sends the request and the response fields have values greater than to the expected values' do expect(task_group.response).to match_gt_field(match['gt'], test) end end end # 'lte' is in the task group definition if task_group.has_lte_clauses? task_group.lte_clauses.each do |match| it 'sends the request and the response fields have values less than or equal to the expected values' do expect(task_group.response).to match_lte_field(match['lte'], test) end end end # 'lt' is in the task group definition if task_group.has_lt_clauses? task_group.lt_clauses.each do |match| it 'sends the request and the response fields have values less than to the expected values' do expect(task_group.response).to match_lt_field(match['lt'], test) end end end end end end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/searchable_snapshots/000077500000000000000000000000001462737751600316115ustar00rootroot00000000000000cache_stats_spec.rb000066400000000000000000000024721462737751600353570ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/searchable_snapshots# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#searchable_snapshots.cache_stats' do let(:expected_args) do [ 'GET', url, {}, nil, {} ] end let(:url){ '_searchable_snapshots/cache/stats' } it 'performs the request' do expect(client_double.searchable_snapshots.cache_stats).to eq({}) end context 'when using index' do let(:url){ '_searchable_snapshots/foo/cache/stats' } it 'performs the request' do expect(client_double.searchable_snapshots.cache_stats(node_id: 'foo')).to eq({}) end end end clear_cache_spec.rb000066400000000000000000000024711462737751600353060ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/searchable_snapshots# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#searchable_snapshots.clear_cache' do let(:expected_args) do [ 'POST', url, {}, nil, {} ] end let(:url){ '_searchable_snapshots/cache/clear' } it 'performs the request' do expect(client_double.searchable_snapshots.clear_cache).to eq({}) end context 'when using index' do let(:url){ 'foo/_searchable_snapshots/cache/clear' } it 'performs the request' do expect(client_double.searchable_snapshots.clear_cache(index: 'foo')).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/searchable_snapshots/mount_spec.rb000066400000000000000000000032631462737751600343160ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#searchable_snapshots.mount' do let(:expected_args) do [ 'POST', '_snapshot/foo/bar/_mount', {}, {}, {} ] end it 'performs the request' do expect(client_double.searchable_snapshots.mount(body: {}, repository: 'foo', snapshot: 'bar')).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'requires the :body argument' do expect { client.searchable_snapshots.mount(repository: 'foo', snapshot: 'bar') }.to raise_exception(ArgumentError) end it 'requires the :repository argument' do expect { client.searchable_snapshots.mount(body: {}, snapshot: 'bar') }.to raise_exception(ArgumentError) end it 'requires the :snapshot argument' do expect { client.searchable_snapshots.mount(body: {}, repository: 'bar') }.to raise_exception(ArgumentError) end end repository_stats_spec.rb000066400000000000000000000025011462737751600365240ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/searchable_snapshots# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#searchable_snapshots.repository_stats' do let(:expected_args) do [ 'GET', '_snapshot/foo/_stats', {}, nil, {} ] end it 'performs the request' do expect(client_double.searchable_snapshots.repository_stats(repository: 'foo')).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'requires the :repository argument' do expect { client.searchable_snapshots.repository_stats }.to raise_exception(ArgumentError) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/searchable_snapshots/stats_spec.rb000066400000000000000000000024261462737751600343120ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#searchable_snapshots.stats' do let(:expected_args) do [ 'GET', url, {}, nil, {} ] end let(:url) { '_searchable_snapshots/stats' } it 'performs the request' do expect(client_double.searchable_snapshots.stats).to eq({}) end context 'using index' do let(:url) { 'foo/_searchable_snapshots/stats' } it 'performs the request' do expect(client_double.searchable_snapshots.stats(index: 'foo')).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security/000077500000000000000000000000001462737751600272655ustar00rootroot00000000000000clear_cached_service_tokens_spec.rb000066400000000000000000000035131462737751600362270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#security#clear_cached_service_tokens' do let(:expected_args) do [ 'POST', '_security/service/foo/bar/credential/token/service_token/_clear_cache', {}, nil, {} ] end it 'performs the request' do expect(client_double.security.clear_cached_service_tokens( namespace: 'foo', service: 'bar', name: 'service_token') ).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'requires the :namespace argument' do expect { client.security.clear_cached_service_tokens(service: 'bar', name: 'service_token') }.to raise_exception(ArgumentError) end it 'requires the :service argument' do expect { client.security.clear_cached_service_tokens(namespace: 'foo', name: 'service_token') }.to raise_exception(ArgumentError) end it 'requires the :name argument' do expect { client.security.clear_cached_service_tokens(service: 'bar', namespace: 'foo') }.to raise_exception(ArgumentError) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security/create_api_key_spec.rb000066400000000000000000000040401462737751600335660ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#security#create_api_key' do let(:expected_args) do [ 'PUT', '_security/api_key', {}, body, {} ] end let(:body) do { "name": "my-api-key", "expiration": "1d", "role_descriptors": { "role-a": { "cluster": ["all"], "index": [ { "names": ["index-a"], "privileges": ["read"] } ] }, "role-b": { "cluster": ["manage"], "index": [ { "names": ["index-b"], "privileges": ["all"] } ] } } } end it 'performs the request' do expect(client_double.security.create_api_key(body: body)).to eq({}) end context 'when params are specified' do let(:expected_args) do [ 'PUT', '_security/api_key', { refresh: 'wait_for' }, body, {} ] end it 'performs the request' do expect(client_double.security.create_api_key(body: body, refresh: 'wait_for')).to eq({}) end end end create_service_token_spec.rb000066400000000000000000000030331462737751600347270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#security#create_service_token' do let(:expected_args) do [ 'PUT', '_security/service/foo/bar/credential/token', {}, nil, {} ] end it 'performs the request' do expect( client_double.security.create_service_token( namespace: 'foo', service: 'bar' ) ).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'requires the :namespace argument' do expect { client.security.create_service_token(service: 'bar') }.to raise_exception(ArgumentError) end it 'requires the :service argument' do expect { client.security.create_service_token(namespace: 'foo') }.to raise_exception(ArgumentError) end end delete_service_token_spec.rb000066400000000000000000000034401462737751600347300ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#security#delete_service_token' do let(:expected_args) do [ 'DELETE', '_security/service/foo/bar/credential/token/service_token', {}, nil, {} ] end it 'performs the request' do expect( client_double.security.delete_service_token( namespace: 'foo', service: 'bar', name: 'service_token' ) ).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'requires the :namespace argument' do expect { client.security.delete_service_token(service: 'bar', name: 'service_token') }.to raise_exception(ArgumentError) end it 'requires the :service argument' do expect { client.security.delete_service_token(namespace: 'foo', name: 'service_token') }.to raise_exception(ArgumentError) end it 'requires the :name argument' do expect { client.security.delete_service_token(namespace: 'foo', service: 'bar') }.to raise_exception(ArgumentError) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security/enroll_kibana_spec.rb000066400000000000000000000020471462737751600334270ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#security#enroll_kibana' do let(:expected_args) do [ 'GET', '_security/enroll/kibana', {}, nil, {} ] end it 'performs the request' do expect(client_double.security.enroll_kibana).to eq({}) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security/enroll_node_spec.rb000066400000000000000000000020411462737751600331210ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#security#enroll_node' do let(:expected_args) do [ 'GET', '_security/enroll/node', {}, nil, {} ] end it 'performs the request' do expect(client_double.security.enroll_node).to eq({}) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security/get_api_key_spec.rb000066400000000000000000000031141462737751600331030ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#security#get_api_key' do let(:expected_args) do [ 'GET', '_security/api_key', params, nil, {} ] end let(:params) do {} end it 'performs the request' do expect(client_double.security.get_api_key).to eq({}) end context 'when params are specified' do let(:params) do { id: '1', username: 'user', name: 'my-api-key', realm_name: '_es_api_key' } end it 'performs the request' do expect(client_double.security.get_api_key(id: '1', username: 'user', name: 'my-api-key', realm_name: '_es_api_key')).to eq({}) end end end get_builtin_privileges_spec.rb000066400000000000000000000021111462737751600352760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#security#get_builtin_privileges' do let(:expected_args) do [ 'GET', '_security/privilege/_builtin', {}, nil, {} ] end it 'performs the request' do expect(client_double.security.get_builtin_privileges).to eq({}) end end get_service_accounts_spec.rb000066400000000000000000000030721462737751600347450ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#security#get_service_accounts' do let(:expected_args) do [ 'GET', url, {}, nil, {} ] end let(:url) { '_security/service' } it 'performs the request' do expect( client_double.security.get_service_accounts ).to eq({}) end context 'when using namespace' do let(:url) { '_security/service/foo' } it 'performs the request' do expect( client_double.security.get_service_accounts(namespace: 'foo') ).to eq({}) end end context 'when using namespace and service' do let(:url) { '_security/service/foo/bar' } it 'performs the request' do expect( client_double.security.get_service_accounts(namespace: 'foo', service: 'bar') ).to eq({}) end end end get_service_credentials_spec.rb000066400000000000000000000030221462737751600354160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#security#get_service_credentials' do let(:expected_args) do [ 'GET', '_security/service/foo/bar/credential', {}, nil, {} ] end it 'performs the request' do expect( client_double.security.get_service_credentials(namespace: 'foo', service: 'bar') ).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'requires the :namespace argument' do expect { client.security.get_service_credentials(service: 'bar') }.to raise_exception(ArgumentError) end it 'requires the :service argument' do expect { client.security.get_service_credentials(namespace: 'foo') }.to raise_exception(ArgumentError) end end invalidate_api_key_spec.rb000066400000000000000000000021471462737751600343720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#security#create_api_key' do let(:expected_args) do [ 'DELETE', '_security/api_key', {}, body, {} ] end let(:body) do { id: 1 } end it 'performs the request' do expect(client_double.security.invalidate_api_key(body: body)).to eq({}) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security/query_api_keys_spec.rb000066400000000000000000000025231462737751600336570ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#security#query_api_keys' do let(:expected_args) do [ method, '_security/_query/api_key', {}, body, {} ] end let(:body) { nil } let(:method) { 'GET' } it 'performs the request' do expect(client_double.security.query_api_keys).to eq({}) end context 'when body is specified' do let(:body) do { size: 1, query: 'test' } end let(:method) { 'POST' } it 'performs the request' do expect(client_double.security.query_api_keys(body: body)).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security/saml_authenticate_spec.rb000066400000000000000000000024521462737751600343210ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.security#saml_authenticate' do let(:expected_args) do [ 'POST', '_security/saml/authenticate', {}, {}, {} ] end it 'performs the request' do expect(client_double.security.saml_authenticate(body: {})).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'raises an error if no body is provided' do expect { client.security.saml_authenticate }.to raise_exception(ArgumentError) end end saml_complete_logout_spec.rb000066400000000000000000000024511462737751600347640ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.security#saml_complete_logout' do let(:expected_args) do [ 'POST', '_security/saml/complete_logout', {}, {}, {} ] end it 'performs the request' do expect(client_double.security.saml_complete_logout(body: {})).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'requires the :namespace argument' do expect { client.security.saml_complete_logout }.to raise_exception(ArgumentError) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security/saml_invalidate_spec.rb000066400000000000000000000024361462737751600337650ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.security#saml_invalidate' do let(:expected_args) do [ 'POST', '_security/saml/invalidate', {}, {}, {} ] end it 'performs the request' do expect(client_double.security.saml_invalidate(body: {})).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'raises an error if no body is provided' do expect do client.security.saml_invalidate end.to raise_exception(ArgumentError) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security/saml_logout_spec.rb000066400000000000000000000024161462737751600331540ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.security#saml_logout' do let(:expected_args) do [ 'POST', '_security/saml/logout', {}, {}, {} ] end it 'performs the request' do expect(client_double.security.saml_logout(body: {})).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'raises an error if no body is provided' do expect do client.security.saml_logout end.to raise_exception(ArgumentError) end end saml_prepare_authentication_spec.rb000066400000000000000000000024361462737751600363230ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.security#saml_prepare_authentication' do let(:expected_args) do [ 'POST', '_security/saml/logout', {}, {}, {} ] end it 'performs the request' do expect(client_double.security.saml_logout(body: {})).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'raises an error if no body is provided' do expect do client.security.saml_logout end.to raise_exception(ArgumentError) end end saml_service_provider_metadata_spec.rb000066400000000000000000000026111462737751600367730ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.security#saml_service_provider_metadata' do let(:expected_args) do [ 'GET', "_security/saml/metadata/#{realm_name}", {}, nil, {} ] end let(:realm_name) { 'foo' } it 'performs the request' do expect(client_double.security.saml_service_provider_metadata(realm_name: realm_name)).to eq({}) end let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'raises an error if no realm name is provided' do expect do client.security.saml_service_provider_metadata end.to raise_exception(ArgumentError) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/sql/000077500000000000000000000000001462737751600262155ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/sql/delete_async_spec.rb000066400000000000000000000025511462737751600322160ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.sql#delete_async' do let(:expected_args) do [ 'DELETE', '_sql/async/delete/foo', {}, nil, {} ] end context 'when there is no id specified' do let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'raises an exception' do expect { client.sql.delete_async }.to raise_exception(ArgumentError) end end context 'when an index is specified' do it 'performs the request' do expect(client_double.sql.delete_async(id: 'foo')).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/sql/get_async_spec.rb000066400000000000000000000025261462737751600315350ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.sql#get_async' do let(:expected_args) do [ 'GET', '_sql/async/foo', {}, nil, {} ] end context 'when there is no id specified' do let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'raises an exception' do expect { client.sql.get_async }.to raise_exception(ArgumentError) end end context 'when an index is specified' do it 'performs the request' do expect(client_double.sql.get_async(id: 'foo')).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/sql/get_async_status_spec.rb000066400000000000000000000025621462737751600331400ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.sql#get_async_status' do let(:expected_args) do [ 'GET', '_sql/async/status/foo', {}, nil, {} ] end context 'when there is no id specified' do let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'raises an exception' do expect { client.sql.get_async_status }.to raise_exception(ArgumentError) end end context 'when an index is specified' do it 'performs the request' do expect(client_double.sql.get_async_status(id: 'foo')).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/terms_enum_spec.rb000066400000000000000000000026631462737751600311420ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client#terms_enum' do let(:expected_args) do [ method, 'foo/_terms_enum', {}, body, {} ] end context 'without a body' do let(:method) { 'GET' } let(:body) { nil } it 'performs a GET request' do expect(client_double.terms_enum(index: 'foo')).to eq({}) end end context 'with a body' do let(:method) { 'POST' } let(:body) { {} } it 'performs a POST request' do expect(client_double.terms_enum(index: 'foo', body: body)).to eq({}) end end it 'requires the :index argument' do expect { client.terms_enum }.to raise_exception(ArgumentError) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/transform/000077500000000000000000000000001462737751600274315ustar00rootroot00000000000000upgrade_transforms_spec.rb000066400000000000000000000020601462737751600346140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/transform# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.transform#upgrade_transforms' do let(:expected_args) do [ 'POST', '_transform/_upgrade', {}, nil, {} ] end it 'performs the request' do expect(client_double.transform.upgrade_transforms).to eq({}) end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/spec/xpack/unfreeze_spec.rb000066400000000000000000000036371462737751600306110ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' describe 'client.indices#unfreeze' do let(:expected_args) do [ 'POST', url, params, nil, {} ] end let(:params) do {} end context 'when there is no index specified' do let(:client) do Class.new { include Elasticsearch::XPack::API }.new end it 'raises an exception' do expect { client.indices.unfreeze }.to raise_exception(ArgumentError) end end context 'when an index is specified' do let(:url) do 'foo/_unfreeze' end it 'performs the request' do expect(client_double.indices.unfreeze(index: 'foo')).to eq({}) end end context 'when params are specified' do let(:params) do { timeout: '1s' } end let(:url) do 'foo/_unfreeze' end it 'performs the request' do expect(client_double.indices.unfreeze(index: 'foo', timeout: '1s')).to eq({}) end end context 'when the path must be URL-escaped' do let(:url) do 'foo%5Ebar/_unfreeze' end it 'performs the request' do expect(client_double.indices.unfreeze(index: 'foo^bar')).to eq({}) end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/000077500000000000000000000000001462737751600243355ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/integration/000077500000000000000000000000001462737751600266605ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/integration/yaml_test_runner.rb000066400000000000000000000535571462737751600326160ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. JRUBY = defined?(JRUBY_VERSION) require 'pathname' require 'logger' require 'yaml' require 'active_support/inflector' require 'ansi' require 'elasticsearch' require 'elasticsearch/extensions/test/cluster' require 'elasticsearch/extensions/test/startup_shutdown' require 'elasticsearch/extensions/test/profiling' unless JRUBY require 'test_helper' # Skip features skip_features = 'stash_in_path,requires_replica,warnings' SKIP_FEATURES = ENV.fetch('TEST_SKIP_FEATURES', skip_features) # Skip files where a pattern matches default_skip_patterns = [ '/xpack/10_basic.yml', # Test fails, doesn't counts with more plugins installed, like `ingest-geoip` '/xpack/15_basic', # Test inserts invalid license, making all subsequent tests fail '/license/20_put_license', # Test inserts invalid license, making all subsequent tests fail '/token/', # Tokens require full SSL setup (TODO) '/ssl/10_basic', # (?) Test relies on some external setup '/ml/jobs_crud.yml', # (?) Test expects settings? '/ml/ml_info.yml', # Test doesn't reset itself in teardown '/transform/' # Skipping until transform is supported ].join('|') SKIP_PATTERNS = Regexp.new( [default_skip_patterns, ENV['TEST_SKIP_PATTERNS'] ].compact.join('|') ) class String # Reset the `ansi` method on CI def ansi(*args) self end end if ENV['CI'] module CapturedLogger def self.included base base.class_eval do %w[ info error warn fatal debug ].each do |m| alias_method "#{m}_without_capture", m define_method m do |*args| @logdev.__send__ :puts, *(args.join("\n") + "\n") self.__send__ "#{m}_without_capture", *args end end end end end Logger.__send__ :include, CapturedLogger if ENV['CI'] $logger = Logger.new($stderr) $logger.progname = 'elasticsearch' $logger.formatter = proc do |severity, datetime, progname, msg| color = case severity when /INFO/ then :green when /ERROR|WARN|FATAL/ then :red when /DEBUG/ then :cyan else :white end "#{severity[0]} ".ansi(color, :faint) + msg.ansi(:white, :faint) + "\n" end $tracer = Logger.new($stdout) $tracer.progname = 'elasticsearch.tracer' $tracer.formatter = proc { |severity, datetime, progname, msg| "#{msg}\n" } if ENV['ELASTIC_PASSWORD'] password = ENV['ELASTIC_PASSWORD'] else password = begin puts "The ELASTIC_PASSWORD environment variable is not set, getting password by running `bin/elasticsearch-setup-passwords`...".ansi(:faint) out = `docker exec -it elasticsearch-xpack bin/elasticsearch-setup-passwords auto --batch` matches = out.match(/PASSWORD elastic = (\S+)/) if matches && matches.captures.first matches.captures.first else puts "\nCannot get password from Docker:".ansi(:bold, :red) puts out.to_s.ansi(:faint) exit(1) end end puts "Password succesfully generated, export it in your shell for subsequent runs:".ansi(:faint), "export ELASTIC_PASSWORD=#{password}" end $url = ENV.fetch('TEST_CLUSTER_URL', "http://elastic:#{password}@localhost:#{ENV['TEST_CLUSTER_PORT'] || 9260}") puts '-'*80, "Connecting to <#{$url}>".ansi(:bold, :faint) $client ||= Elasticsearch::Client.new url: $url $helper_client ||= Elasticsearch::Client.new url: $url es_version_info = $helper_client.info['version'] xpack_info = $helper_client.xpack.info plugins = $helper_client.cat.plugins(format: 'json') $es_version = es_version_info['number'] puts '-'*80, "Elasticsearch #{$es_version.ansi(:bold)} [#{es_version_info['build_hash'].to_s[0...7]}]", "Plugins: " + plugins.map { |d| "#{d['component'].ansi(:bold)}:#{d['version']}"}.join(', '), "X-Pack #{xpack_info['license']['type']} license is #{xpack_info['license']['status'].ansi(:bold)} and expires at #{Time.at(xpack_info['license']['expiry_date_in_millis']/1000)}", '-'*80 $client.transport.logger = $logger unless ENV['QUIET'] || ENV['CI'] $original_client = $client.clone module Minitest module Reporters class SpecReporter def record_print_status(test) test_name = test.name.gsub(/^test_: (.+) should (.+)/, '[\1] \2') print pad_test(test_name) print_colored_status(test) print(" (%.2fs)" % test.time) unless test.time.nil? puts end end end end module Elasticsearch module YamlTestSuite $last_response = '' $results = {} $stash = {} module Utils def titleize(word) word.to_s.gsub(/[^\w]+/, ' ').gsub(/\b('?[a-z])/) { $1.capitalize }.tr('_', ' ') end def symbolize_keys(object) if object.is_a? Hash object.reduce({}) { |memo,(k,v)| memo[k.to_sym] = symbolize_keys(v); memo } else object end end extend self end module Runner def perform_api_call(test, api, arguments=nil) namespace = api.split('.') replacer = lambda do |value| case value when Array value.map { |v| replacer.call(v) } when Hash Hash[ value.map { |v| replacer.call(v) } ] else fetch_or_return value end end timefixer = lambda do |value| if value.is_a?(Time) value.iso8601 else value end end arguments = Hash[ arguments.map do |key, value| replacement = replacer.call(value) replacement = timefixer.call(replacement) [key, replacement] end ] $stderr.puts "[#{api}] ARGUMENTS: #{arguments.inspect}" if ENV['DEBUG'] $last_response = namespace.reduce($client) do |memo, current| unless current == namespace.last memo = memo.send(current) else arguments ? memo = memo.send(current, arguments) : memo = memo.send(current) end memo end $results[test.hash] = $last_response end def evaluate(test, property, response=nil) response ||= $results[test.hash] property.gsub(/\\\./, '_____').split('.').reduce(response) do |memo, attr| if memo if attr attr = attr.gsub(/_____/, '.') attr = $stash[attr] if attr.start_with? '$' end case when memo.is_a?(Hash) && attr memo = memo[attr] when memo.is_a?(Array) && attr && attr =~ /^\d+$/ memo = memo[attr.to_i] else memo = memo end end memo end end def in_context(name, &block) klass = Class.new(YamlTestCase) Object::const_set "%sTest" % name.split(/\s/).reject { |d| d.match(/^\d+/) }.map { |d| d.capitalize }.join('').gsub(/[^\w]+/, ''), klass klass.context name, &block end def fetch_or_return(var) if var.is_a?(String) && var =~ /^\$(.+)/ $stash[var] else var end end def set(var, val) $stash["$#{var}"] = val end def skip?(actions) skip = actions.select { |a| a['skip'] }.first # Skip version if skip && skip['skip']['version'] $stderr.puts "SKIP: #{skip.inspect}" if ENV['DEBUG'] return skip['skip']['reason'] ? skip['skip']['reason'] : true if skip['skip']['version'] == 'all' min, max = skip['skip']['version'].split('-').map(&:strip) min_normalized = sprintf "%03d-%03d-%03d", *min.split('.') .map(&:to_i) .fill(0, min.split('.').length, 3-min.split('.').length) max_normalized = sprintf "%03d-%03d-%03d", *max.split('.') .map(&:to_i) .map(&:to_i) .fill(0, max.split('.').length, 3-max.split('.').length) es_normalized = sprintf "%03d-%03d-%03d", *$es_version.split('.').map(&:to_i) if ( min.empty? || min_normalized <= es_normalized ) && ( max.empty? || max_normalized >= es_normalized ) return skip['skip']['reason'] ? skip['skip']['reason'] : true end # Skip features elsif skip && skip['skip']['features'] skip_features = skip['skip']['features'].respond_to?(:split) ? skip['skip']['features'].split(',') : skip['skip']['features'] if ( skip_features & SKIP_FEATURES.split(',') ).size > 0 return skip['skip']['features'] end end return false end extend self end class YamlTestCase < Minitest::Test; end end end include Elasticsearch::YamlTestSuite rest_api_test_source = '../../../../tmp/elasticsearch/x-pack/plugin/src/test/resources/rest-api-spec/test' PATH = Pathname(ENV.fetch('TEST_REST_API_SPEC', File.expand_path(rest_api_test_source, __FILE__))) raise Errno::ENOENT, "#{PATH}" unless PATH.exist? suites = Dir.glob(PATH.join('*')).map { |d| Pathname(d) } suites = suites.select { |s| s.to_s =~ Regexp.new(ENV['FILTER']) } if ENV['FILTER'] $stderr.puts "TEST SUITES: " + suites.map { |d| d.basename }.join(', ') if ENV['DEBUG'] suites.each do |suite| name = Elasticsearch::YamlTestSuite::Utils.titleize(suite.basename) Elasticsearch::YamlTestSuite::Runner.in_context name do # --- Register context setup ------------------------------------------- # setup do # Prevent deleting the `.security*` index indices = $helper_client.indices.get(index: '_all').keys.reject { |i| i.start_with?('.security') } $helper_client.indices.delete index: indices, ignore: 404 unless indices.empty? $results = {} $stash = {} # Cleanup for roles $helper_client.xpack.security.get_role.each do |role, _| begin $helper_client.xpack.security.delete_role name: role rescue end end # Cleanup for privileges $helper_client.xpack.security.get_privileges.each do |privilege, _| begin $helper_client.xpack.security.delete_privileges name: privilege rescue end end # Cleanup for users $helper_client.xpack.security.get_user.each do |user, _| begin $helper_client.xpack.security.delete_user username: user rescue end end # Setup machine learning user $helper_client.xpack.security.put_user username: 'x_pack_rest_user', body: { password: 'x-pack-test-password', roles: ['superuser'] } # Cleanup for machine learning $helper_client.xpack.ml.stop_datafeed datafeed_id: '_all', force: true $helper_client.xpack.ml.get_datafeeds['datafeeds'].each do |d| $helper_client.xpack.ml.delete_datafeed datafeed_id: d['datafeed_id'] end $helper_client.xpack.ml.close_job job_id: '_all', force: true $helper_client.xpack.ml.get_jobs['jobs'].each do |d| $helper_client.xpack.ml.delete_job job_id: d['job_id'] end # $helper_client.cat.tasks(format: 'json') tasks = $helper_client.tasks.get['nodes'].values.first['tasks'].values.select { |d| d['cancellable'] }.map { |d| "#{d['node']}:#{d['id']}" } tasks.each { |t| $helper_client.tasks.cancel task_id: t } $helper_client.indices.delete index: '.ml-*', ignore: 404 end # --- Register context teardown ---------------------------------------- # teardown do $helper_client.xpack.ml.stop_datafeed datafeed_id: '_all', force: true $helper_client.xpack.ml.get_datafeeds['datafeeds'].each do |d| $helper_client.xpack.ml.delete_datafeed datafeed_id: d['datafeed_id'] end $helper_client.xpack.ml.close_job job_id: '_all', force: true $helper_client.xpack.ml.get_jobs['jobs'].each do |d| $helper_client.xpack.ml.delete_job job_id: d['job_id'] end $helper_client.indices.delete index: '_all', ignore: 404 if ENV['CLEANUP'] end # --- Parse tests ------------------------------------------------------ # Dir[suite.join('*.{yml,yaml}')].each do |file| if file =~ SKIP_PATTERNS $stderr.puts "#{'SKIP FILE'.ansi(:yellow)} #{file.gsub(PATH.to_s, '')}" next end tests = YAML.load_stream File.new(file) # Extract setup and teardown actions setup_actions = tests.select { |t| t['setup'] }.first['setup'] rescue [] teardown_actions = tests.select { |t| t['teardown'] }.first['teardown'] rescue [] # Skip all the tests when `skip` is part of the `setup` part if features = Runner.skip?(setup_actions) $stdout.puts "#{'SKIP TEST'.ansi(:yellow)} [#{name}] #{file.gsub(PATH.to_s, '').ansi(:bold)} (Feature not implemented: #{features})" next end # Remove setup/teardown actions from tests tests = tests.reject { |t| t['setup'] || t['teardown'] } # Add setup/teardown actions to each individual test tests.each { |t| t[t.keys.first] << { 'setup' => setup_actions } } tests.each { |t| t[t.keys.first] << { 'teardown' => teardown_actions } } tests.each do |test| context '' do test_name = test.keys.first.to_s.gsub(/test/i, '').strip.capitalize.ansi(:bold) + " | #{file.gsub(PATH.to_s, '')}" actions = test.values.first if reason = Runner.skip?(actions) $stdout.puts "#{'SKIP TEST'.ansi(:yellow)} [#{name}] #{test_name} (Reason: #{reason})" next end # --- Register test setup ------------------------------------------- setup do actions.find { |a| a['setup'] }['setup'].each do |action| if action['do'] if headers = action['do'] && action['do'].delete('headers') puts "HEADERS: " + headers.inspect if ENV['DEBUG'] $client = Elasticsearch::Client.new url: $url, transport_options: { headers: headers } $client.transport.logger = $logger unless ENV['QUIET'] || ENV['CI'] else $client = $original_client end api, arguments = action['do'].to_a.first arguments = Utils.symbolize_keys(arguments) Runner.perform_api_call((test.to_s + '___setup'), api, arguments) end if action['set'] stash = action['set'] property, variable = stash.to_a.first result = Runner.evaluate(test, property, $last_response) $stderr.puts "STASH: '$#{variable}' => #{result.inspect}" if ENV['DEBUG'] Runner.set variable, result end end end # --- Register test teardown ------------------------------------------- teardown do $client = $helper_client actions.select { |a| a['teardown'] }.first['teardown'].each do |action| if action['do'] api, arguments = action['do'].to_a.first arguments = Utils.symbolize_keys(arguments) Runner.perform_api_call((test.to_s + '___teardown'), api, arguments) end if action['set'] stash = action['set'] property, variable = stash.to_a.first result = Runner.evaluate(test, property, $last_response) $stderr.puts "STASH: '$#{variable}' => #{result.inspect}" if ENV['DEBUG'] Runner.set variable, result end end unless teardown_actions.empty? end # --- Register test method ------------------------------------------ should test_name do actions.each do |action| $stderr.puts "ACTION: #{action.inspect}" if ENV['DEBUG'] if headers = action['do'] && action['do'].delete('headers') puts "HEADERS: " + headers.inspect if ENV['DEBUG'] $client = Elasticsearch::Client.new url: $url, transport_options: { headers: headers } $client.transport.logger = $logger unless ENV['QUIET'] || ENV['CI'] else $client = $original_client end case # --- Perform action ------------------------------------------ # when action['do'] catch_exception = action['do'].delete('catch') if action['do'] api, arguments = action['do'].to_a.first arguments = Utils.symbolize_keys(arguments) begin $results[test.hash] = Runner.perform_api_call(test, api, arguments) rescue Exception => e begin $results[test.hash] = MultiJson.load(e.message.match(/{.+}/, 1).to_s) rescue MultiJson::ParseError $stderr.puts "RESPONSE: Cannot parse JSON from error message: '#{e.message}'" if ENV['DEBUG'] end if catch_exception $stderr.puts "CATCH: '#{catch_exception}': #{e.inspect}" if ENV['DEBUG'] case e when 'missing' assert_match /\[404\]/, e.message when 'conflict' assert_match /\[409\]/, e.message when 'request' assert_match /\[500\]/, e.message when 'param' raise ArgumentError, "NOT IMPLEMENTED" when /\/.+\// assert_match Regexp.new(catch_exception.tr('/', '')), e.message end else raise e end end # --- Evaluate predicates ------------------------------------- # when property = action['is_true'] result = Runner.evaluate(test, property) $stderr.puts "CHECK: Expected '#{property}' to be true, is: #{result.inspect}" if ENV['DEBUG'] assert(result, "Property '#{property}' should be true, is: #{result.inspect}") when property = action['is_false'] result = Runner.evaluate(test, property) $stderr.puts "CHECK: Expected '#{property}' to be nil, false, 0 or empty string, is: #{result.inspect}" if ENV['DEBUG'] assert "Property '#{property}' should be nil, false, 0 or empty string, but is: #{result.inspect}" do result.nil? || result == false || result == 0 || result == '' end when a = action['match'] property, value = a.to_a.first if value.is_a?(String) && value =~ %r{\s*^/\s*.*\s*/$\s*}mx # Begins and ends with / pattern = Regexp.new(value.strip[1..-2], Regexp::EXTENDED|Regexp::MULTILINE) else value = Runner.fetch_or_return(value) end if property == '$body' result = $results[test.hash] else result = Runner.evaluate(test, property) end if pattern $stderr.puts "CHECK: Expected '#{property}' to match #{pattern}, is: #{result.inspect}" if ENV['DEBUG'] assert_match(pattern, result) else value = value.reduce({}) { |memo, (k,v)| memo[k] = Runner.fetch_or_return(v); memo } if value.is_a? Hash $stderr.puts "CHECK: Expected '#{property}' to be '#{value}', is: #{result.inspect}" if ENV['DEBUG'] assert_equal(value, result) end when a = action['length'] property, value = a.to_a.first result = Runner.evaluate(test, property) length = result.size $stderr.puts "CHECK: Expected '#{property}' to be #{value}, is: #{length.inspect}" if ENV['DEBUG'] assert_equal(value, length) when a = action['lt'] || action['gt'] || action['lte'] || action['gte'] property, value = a.to_a.first operator = case when action['lt'] '<' when action['gt'] '>' when action['lte'] '<=' when action['gte'] '>=' end result = Runner.evaluate(test, property) message = "Expected '#{property}' to be #{operator} #{value}, is: #{result.inspect}" $stderr.puts "CHECK: #{message}" if ENV['DEBUG'] assert_operator result, operator.to_sym, value.to_i when stash = action['set'] property, variable = stash.to_a.first result = Runner.evaluate(test, property) $stderr.puts "STASH: '$#{variable}' => #{result.inspect}" if ENV['DEBUG'] Runner.set variable, result end end end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/test_helper.rb000066400000000000000000000037211462737751600272030ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'pathname' require 'minitest/autorun' require 'minitest/reporters' require 'shoulda/context' require 'mocha/minitest' require 'ansi' require 'elasticsearch/transport' require 'elasticsearch/xpack' Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new module Minitest class Test def assert_nothing_raised(*args) begin line = __LINE__ yield rescue Exception => e raise MiniTest::Assertion, "Exception raised:\n<#{e.class}>", e.backtrace end true end end end module Elasticsearch module Test class FakeClient def xpack @xpack ||= Elasticsearch::XPack::API::Client.new(self) end def perform_request(method, path, params, body) puts "PERFORMING REQUEST:", "--> #{method.to_s.upcase} #{path} #{params} #{body}" FakeResponse.new(200, 'FAKE', {}) end end FakeResponse = Struct.new(:status, :body, :headers) do def status values[0] || 200 end def body values[1] || '{}' end def headers values[2] || {} end end class NotFound < StandardError; end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/000077500000000000000000000000001462737751600253145ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/async_search/000077500000000000000000000000001462737751600277565ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/async_search/delete_test.rb000066400000000000000000000025501462737751600326060ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackAsyncSearchDelete < Minitest::Test subject { FakeClient.new } context 'XPack: Async Search Delete' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('DELETE', method) assert_equal('_async_search/foo', url) assert_equal({}, params) assert_nil(body) end.returns(FakeResponse.new) subject.xpack.async_search.delete(id: 'foo') end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/async_search/get_test.rb000066400000000000000000000025341462737751600321250ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackAsyncSearchGet < Minitest::Test subject { FakeClient.new } context 'XPack: Async Search Get' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('GET', method) assert_equal('_async_search/foo', url) assert_equal({}, params) assert_nil(body) end.returns(FakeResponse.new) subject.xpack.async_search.get(id: 'foo') end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/async_search/status_test.rb000066400000000000000000000025541462737751600326730ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackAsyncSearchStatus < Minitest::Test subject { FakeClient.new } context 'XPack: Async Search Status' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('GET', method) assert_equal('_async_search/status/foo', url) assert_equal({}, params) assert_nil(body) end.returns(FakeResponse.new) subject.xpack.async_search.status(id: 'foo') end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/async_search/submit_test.rb000066400000000000000000000033541462737751600326520ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackAsyncSearchSubmit < Minitest::Test subject { FakeClient.new } context 'XPack: Async Search Submit' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('POST', method) assert_equal('_async_search', url) assert_equal({}, params) assert_nil(body) end.returns(FakeResponse.new) subject.xpack.async_search.submit end should 'perform correct request with index' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('POST', method) assert_equal('foo/_async_search', url) assert_equal({}, params) assert_nil(body) end.returns(FakeResponse.new) subject.xpack.async_search.submit(index: 'foo') end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/autoscaling/000077500000000000000000000000001462737751600276255ustar00rootroot00000000000000delete_autoscaling_policy_test.rb000066400000000000000000000031571462737751600363520ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/autoscaling# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackAutoscalingDeleteAutoscalingPolicyTest < Minitest::Test subject { FakeClient.new } context 'XPack: Get Autoscaling Policy' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('DELETE', method) assert_equal('_autoscaling/policy/a_policy', url) assert_equal({}, params) assert_nil(body) true end.returns(FakeResponse.new) subject.xpack.autoscaling.delete_autoscaling_policy(name: 'a_policy') end should 'raise argument error without name' do assert_raises ArgumentError do subject.xpack.autoscaling.delete_autoscaling_policy end end end end end end get_autoscaling_capacity_test.rb000066400000000000000000000026311462737751600361610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/autoscaling# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackAutoscalingGetAutoscalingCapacityTest < Minitest::Test subject { FakeClient.new } context 'XPack: Get Autoscaling Capacity' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('GET', method) assert_equal('_autoscaling/capacity', url) assert_equal({}, params) assert_nil(body) true end.returns(FakeResponse.new) subject.xpack.autoscaling.get_autoscaling_capacity end end end end end get_autoscaling_decision_test.rb000066400000000000000000000026311462737751600361610ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/autoscaling# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackAutoscalingGetAutoscalingDecisionTest < Minitest::Test subject { FakeClient.new } context 'XPack: Get Autoscaling Decision' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('GET', method) assert_equal('_autoscaling/decision', url) assert_equal({}, params) assert_nil(body) true end.returns(FakeResponse.new) subject.xpack.autoscaling.get_autoscaling_decision end end end end end get_autoscaling_policy_test.rb000066400000000000000000000031431462737751600356620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/autoscaling# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackAutoscalingGetAutoscalingPolicyTest < Minitest::Test subject { FakeClient.new } context 'XPack: Get Autoscaling Policy' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('GET', method) assert_equal('_autoscaling/policy/a_policy', url) assert_equal({}, params) assert_nil(body) true end.returns(FakeResponse.new) subject.xpack.autoscaling.get_autoscaling_policy(name: 'a_policy') end should 'raise argument error without name' do assert_raises ArgumentError do subject.xpack.autoscaling.get_autoscaling_policy end end end end end end put_autoscaling_policy_test.rb000066400000000000000000000035061462737751600357160ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/autoscaling# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackAutoscalingPutAutoscalingPolicyTest < Minitest::Test subject { FakeClient.new } context 'XPack: Put Autoscaling Policy' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('PUT', method) assert_equal('_autoscaling/policy/a_policy', url) assert_equal({}, params) assert_equal(body, {}) true end.returns(FakeResponse.new) subject.xpack.autoscaling.put_autoscaling_policy(name: 'a_policy', body: {}) end should 'raise argument error without name' do assert_raises ArgumentError do subject.xpack.autoscaling.put_autoscaling_policy(body: {}) end end should 'raise argument error without body' do assert_raises ArgumentError do subject.xpack.autoscaling.put_autoscaling_policy(name: 'a_policy') end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/eql/000077500000000000000000000000001462737751600260755ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/eql/delete_test.rb000066400000000000000000000027711462737751600307320ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackEqlDeleteTest < Minitest::Test context 'Eql: Delete' do subject { FakeClient.new } should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal '_eql/search/test', url assert_equal({}, params) assert_nil body true end.returns(FakeResponse.new) subject.xpack.eql.delete(id: 'test') end should 'raise argument error without id' do assert_raises ArgumentError do subject.xpack.eql.delete end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/eql/get_status_test.rb000066400000000000000000000030121462737751600316370ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackEqlGetStatusTest < Minitest::Test context 'Eql: Get Status' do subject { FakeClient.new } should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_eql/search/status/foo', url assert_equal({}, params) assert_nil body true end.returns(FakeResponse.new) subject.xpack.eql.get_status(id: 'foo') end should 'raise argument error without id' do assert_raises ArgumentError do subject.xpack.eql.get_status end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/eql/get_test.rb000066400000000000000000000027521462737751600302460ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackEqlGetTest < Minitest::Test context 'Eql: Get' do subject { FakeClient.new } should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_eql/search/test', url assert_equal({}, params) assert_nil body true end.returns(FakeResponse.new) subject.xpack.eql.get(id: 'test') end should 'raise argument error without id' do assert_raises ArgumentError do subject.xpack.eql.get end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/eql/search_test.rb000066400000000000000000000033161462737751600307310ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackEqlSearchTest < Minitest::Test context 'Eql: Search' do subject { FakeClient.new } should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal 'foo/_eql/search', url assert_equal({}, params) assert_equal body, 'test' true end.returns(FakeResponse.new) subject.xpack.eql.search(index: 'foo', body: 'test') end should 'raise argument error without body' do assert_raises ArgumentError do subject.xpack.eql.search(index: 'foo') end end should 'raise argument error without index' do assert_raises ArgumentError do subject.xpack.eql.search(body: 'test') end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/graph/000077500000000000000000000000001462737751600264155ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/graph/explore_test.rb000066400000000000000000000025631462737751600314650ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class GraphExploreTest < Minitest::Test context "Graph: Explore" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal 'my_index/_graph/explore', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.graph.explore(index: 'my_index') end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/index_lifecycle_management/000077500000000000000000000000001462737751600326365ustar00rootroot00000000000000delete_policy_test.rb000066400000000000000000000026631462737751600367730ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndexLifecycleManagementDeletePolicyTest < Minitest::Test context "XPack Index Lifecycle Management: Delete policy" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal '_ilm/policy/foo', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ilm.delete_policy :policy_id => 'foo' end end end end end explain_test.rb000066400000000000000000000026341462737751600356100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndexLifecycleManagementExplainTest < Minitest::Test context "XPack Index Lifecycle Management: explain" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal 'foo/_ilm/explain', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ilm.explain :index => 'foo' end end end end end get_policy_test.rb000066400000000000000000000026471462737751600363120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndexLifecycleManagementGetPolicyTest < Minitest::Test context "XPack Index Lifecycle Management: Get policy" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_ilm/policy/foo', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ilm.get_policy :policy_id => 'foo' end end end end end get_status_test.rb000066400000000000000000000026151462737751600363310ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndexLifecycleManagementGetStatusTest < Minitest::Test context "XPack Index Lifecycle Management: Get status" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_ilm/status', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ilm.get_status end end end end end move_to_step.rb000066400000000000000000000026741462737751600356200ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndexLifecycleManagementMoveStepTest < Minitest::Test context "XPack Index Lifecycle Management: Move to step" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal '_ilm/move/foo', url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.ilm.move_to_step :index => 'foo', :body => {} end end end end end put_policy_test.rb000066400000000000000000000026761462737751600363450ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndexLifecycleManagementPutPolicyTest < Minitest::Test context "XPack Index Lifecycle Management: Put policy" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_ilm/policy/foo', url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.ilm.put_policy :policy_id => 'foo', :body => {} end end end end end remove_policy_test.rb000066400000000000000000000026551462737751600370270ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndexLifecycleManagementRemovePolicyTest < Minitest::Test context "XPack Index Lifecycle Management: Remove policy" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal 'foo/_ilm/remove', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ilm.remove_policy :index => 'foo' end end end end end retry_policy_test.rb000066400000000000000000000026321462737751600366720ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndexLifecycleManagementRetryTest < Minitest::Test context "XPack Index Lifecycle Management: retry" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal 'foo/_ilm/retry', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ilm.retry_policy :index => 'foo' end end end end end start_test.rb000066400000000000000000000026011462737751600352770ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndexLifecycleManagementStartTest < Minitest::Test context "XPack Index Lifecycle Management: start" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal '_ilm/start', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ilm.start end end end end end stop_test.rb000066400000000000000000000025751462737751600351410ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/index_lifecycle_management# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndexLifecycleManagementStopTest < Minitest::Test context "XPack Index Lifecycle Management: stop" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal '_ilm/stop', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ilm.stop end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/indices/000077500000000000000000000000001462737751600267325ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/indices/create_data_stream_test.rb000066400000000000000000000030661462737751600341320ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndicesCreateDataStreamTest < Minitest::Test subject { FakeClient.new } context 'XPack: Create Data Stream' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('PUT', method) assert_equal('_data_stream/foo', url) assert_equal({}, params) assert_nil(body) true end.returns(FakeResponse.new) subject.xpack.indices.create_data_stream(name: 'foo') end should 'raise argument error without name' do assert_raises ArgumentError do subject.xpack.indices.create_data_stream end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/indices/data_stream_stats_test.rb000066400000000000000000000035251462737751600340250ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndicesDataStreamStatsTest < Minitest::Test subject { FakeClient.new } context 'XPack: Data Stream Stats' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('GET', method) assert_equal('_data_stream/_stats', url) assert_equal({}, params) assert_nil(body) true end.returns(FakeResponse.new) subject.xpack.indices.data_streams_stats end end context 'when name is specified' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('GET', method) assert_equal('_data_stream/foo/_stats', url) assert_equal({}, params) assert_nil(body) true end.returns(FakeResponse.new) subject.xpack.indices.data_streams_stats(name: 'foo') end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/indices/delete_data_stream_test.rb000066400000000000000000000030371462737751600341270ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndicesDeleteDataStreamTest < Minitest::Test subject { FakeClient.new } context 'XPack: Delete Data Stream' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('DELETE', method) assert_equal('_data_stream/foo', url) assert_equal({}, params) assert_nil(body) end.returns(FakeResponse.new) subject.xpack.indices.delete_data_stream(name: 'foo') end end should 'raise argument error without name' do assert_raises ArgumentError do subject.xpack.indices.create_data_stream end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/indices/get_data_stream_test.rb000066400000000000000000000033341462737751600334440ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndicesGetDataStreamTest < Minitest::Test subject { FakeClient.new } context 'XPack: Get Data Stream' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('GET', method) assert_equal('_data_stream', url) assert_equal({}, params) assert_nil(body) end.returns(FakeResponse.new) subject.xpack.indices.get_data_stream end end context 'Get Data Stream with name' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('GET', method) assert_equal('_data_stream/foo', url) end.returns(FakeResponse.new) subject.xpack.indices.get_data_stream(name: 'foo') end end end end end migrate_to_data_stream_test.rb000066400000000000000000000031171462737751600347370ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/indices# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndicesMigrateToDataStreamTest < Minitest::Test subject { FakeClient.new } context 'XPack: Migrate to Data Stream' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('POST', method) assert_equal('_data_stream/_migrate/foo', url) assert_equal({}, params) assert_nil(body) true end.returns(FakeResponse.new) subject.xpack.indices.migrate_to_data_stream(name: 'foo') end should 'raise argument error without name' do assert_raises ArgumentError do subject.xpack.indices.migrate_to_data_stream end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/indices/modify_data_stream_test.rb000066400000000000000000000026171462737751600341570ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndicesModifyDataStreamTest < Minitest::Test subject { FakeClient.new } context 'XPack: Modify Data Stream' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('POST', method) assert_equal('_data_stream/_modify', url) assert_equal({}, params) assert_equal(body, {}) true end.returns(FakeResponse.new) subject.xpack.indices.modify_data_stream(body: {}) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/indices/promote_data_stream_test.rb000066400000000000000000000031041462737751600343450ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackIndicesPromoteDataStreamTest < Minitest::Test subject { FakeClient.new } context 'XPack: Promote Data Stream' do should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('POST', method) assert_equal('_data_stream/_promote/foo', url) assert_equal({}, params) assert_nil(body) true end.returns(FakeResponse.new) subject.xpack.indices.promote_data_stream(name: 'foo') end should 'raise argument error without name' do assert_raises ArgumentError do subject.xpack.indices.promote_data_stream end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/info_test.rb000066400000000000000000000024771462737751600276450ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackInfoTest < Minitest::Test context "XPack: Info" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_xpack', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.info end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/license/000077500000000000000000000000001462737751600267365ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/license/delete_test.rb000066400000000000000000000025361462737751600315720ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackLicenseDeleteTest < Minitest::Test context "License: Delete" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal '_license', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.license.delete end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/license/get_test.rb000066400000000000000000000025221462737751600311020ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackLicenseGetTest < Minitest::Test context "License: Get" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_license', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.license.get end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/license/post_test.rb000066400000000000000000000025421462737751600313120ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackLicensePostTest < Minitest::Test context "License: Post" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_license', url assert_equal Hash.new, params assert_equal [], body true end.returns(FakeResponse.new) subject.xpack.license.post body: [] end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/logstash/000077500000000000000000000000001462737751600271405ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/logstash/delete_pipeline_test.rb000066400000000000000000000030651462737751600336570ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackLogstashDeletePipelineTest < Minitest::Test context 'Logstash: Delete Pipeline' do subject { FakeClient.new } should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal '_logstash/pipeline/foo', url assert_equal({}, params) assert_nil body true end.returns(FakeResponse.new) subject.xpack.logstash.delete_pipeline(id: 'foo') end should 'raise argument error without id' do assert_raises ArgumentError do subject.xpack.logstash.delete_pipeline end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/logstash/get_pipeline_test.rb000066400000000000000000000030461462737751600331730ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackLogstashGetPipelineTest < Minitest::Test context 'Logstash: Get Pipeline' do subject { FakeClient.new } should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_logstash/pipeline/foo', url assert_equal({}, params) assert_nil body true end.returns(FakeResponse.new) subject.xpack.logstash.get_pipeline(id: 'foo') end should 'raise argument error without id' do assert_raises ArgumentError do subject.xpack.logstash.get_pipeline end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/logstash/put_pipeline_test.rb000066400000000000000000000031041462737751600332170ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackLogstashPutPipelineTest < Minitest::Test context 'Logstash: Put Pipeline' do subject { FakeClient.new } should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_logstash/pipeline/foo', url assert_equal({}, params) assert_equal({}, body) true end.returns(FakeResponse.new) subject.xpack.logstash.put_pipeline(id: 'foo', body: {}) end should 'raise argument error without body' do assert_raises ArgumentError do subject.xpack.logstash.put_pipeline(id: 'foo') end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning/000077500000000000000000000000001462737751600305775ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning/close_job_test.rb000066400000000000000000000026211462737751600341230ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlCloseJobTest < Minitest::Test context "XPack MachineLearning: Close job" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/anomaly_detectors/foo/_close", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.close_job :job_id => 'foo' end end end end end delete_datafeed_test.rb000066400000000000000000000026331462737751600351670ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlDeleteDatafeedTest < Minitest::Test context "XPack MachineLearning: Delete datafeed" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal "_ml/datafeeds/foo", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.delete_datafeed :datafeed_id => 'foo' end end end end end delete_expired_data_test.rb000066400000000000000000000026271462737751600360660ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlDeleteExpiredDataTest < Minitest::Test context "XPack MachineLearning: Delete expired data" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal "_ml/_delete_expired_data", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.delete_expired_data end end end end end delete_filter_test.rb000066400000000000000000000026211462737751600347140ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlDeleteFilterTest < Minitest::Test context "XPack MachineLearning: Delete filter" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal "_ml/filters/foo", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.delete_filter :filter_id => 'foo' end end end end end delete_forecast_test.rb000066400000000000000000000026501462737751600352370ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlDeleteForecastTest < Minitest::Test context "XPack MachineLearning: Delete forecast" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal "_ml/anomaly_detectors/foo/_forecast", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.delete_forecast :job_id => 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning/delete_job_test.rb000066400000000000000000000026171462737751600342650ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlDeleteJobTest < Minitest::Test context "XPack MachineLearning: Delete job" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal "_ml/anomaly_detectors/foo", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.delete_job :job_id => 'foo' end end end end end delete_model_alias_test.rb000066400000000000000000000027421462737751600357040ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlDeleteTrainedModelAliasTest < Minitest::Test context "XPack MachineLearning: Delete trained model alias" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('DELETE', method) assert_equal("_ml/trained_models/foo/model_aliases/alias", url) assert_equal(Hash.new, params) assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.delete_trained_model_alias(model_id: 'foo', model_alias: 'alias') end end end end end delete_model_snapshot_test.rb000066400000000000000000000027321462737751600364510ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlDeleteModelSnapshotTest < Minitest::Test context "XPack MachineLearning: Delete model snapshot" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal "_ml/anomaly_detectors/foo/model_snapshots/bar", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.delete_model_snapshot :job_id => 'foo', :snapshot_id => 'bar' end end end end end find_file_structure_test.rb000066400000000000000000000026321462737751600361460ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class FindFileStructuretest < Minitest::Test context "XPack MachineLearning: Find file structure" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/find_file_structure", url assert_equal Hash.new, params assert_equal "", body true end.returns(FakeResponse.new) subject.xpack.ml.find_file_structure body: [] end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning/flush_job_test.rb000066400000000000000000000026171462737751600341440ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlFlushJobTest < Minitest::Test context "XPack MachineLearning: Flush job" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/anomaly_detectors/foo/_flush", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.flush_job :job_id => 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning/forecast_test.rb000066400000000000000000000026221462737751600337730ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlForecastTest < Minitest::Test context "XPack MachineLearning: Forecast" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal '_ml/anomaly_detectors/foo/_forecast', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.forecast :job_id => 'foo' end end end end end get_buckets_test.rb000066400000000000000000000026351462737751600344110ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlGetBucketsTest < Minitest::Test context "XPack MachineLearning: Get buckets" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal "_ml/anomaly_detectors/foo/results/buckets", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.get_buckets :job_id => 'foo' end end end end end get_categories_test.rb000066400000000000000000000026511462737751600350740ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlGetCategoriesTest < Minitest::Test context "XPack MachineLearning: Get categories" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal "_ml/anomaly_detectors/foo/results/categories", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.get_categories :job_id => 'foo' end end end end end get_datafeed_stats_test.rb000066400000000000000000000026151462737751600357220ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlGetDatafeedStatsTest < Minitest::Test context "XPack MachineLearning: Get datafeed stats" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal "_ml/datafeeds/_stats", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.get_datafeed_stats end end end end end get_datafeeds_test.rb000066400000000000000000000026221462737751600346650ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlGetDatafeedsTest < Minitest::Test context "XPack MachineLearning: Get datafeeds" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal "_ml/datafeeds/foo", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.get_datafeeds :datafeed_id => 'foo' end end end end end get_filters_test.rb000066400000000000000000000026101462737751600344120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlGetFiltersTest < Minitest::Test context "XPack MachineLearning: Get filters" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal "_ml/filters/foo", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.get_filters :filter_id => 'foo' end end end end end get_influencers_test.rb000066400000000000000000000026551462737751600352700ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlGetInfluencersTest < Minitest::Test context "XPack MachineLearning: Get influencers" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal "_ml/anomaly_detectors/foo/results/influencers", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.get_influencers :job_id => 'foo' end end end end end get_job_stats_test.rb000066400000000000000000000026331462737751600347370ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlGetJobStatsTest < Minitest::Test context "XPack MachineLearning: Get job stats" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal "_ml/anomaly_detectors/foo/_stats", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.get_job_stats :job_id => 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning/get_jobs_test.rb000066400000000000000000000026061462737751600337630ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlGetJobsTest < Minitest::Test context "XPack MachineLearning: Get jobs" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal "_ml/anomaly_detectors/foo", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.get_jobs :job_id => 'foo' end end end end end get_model_snapshots_test.rb000066400000000000000000000027171462737751600361540ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlGetModelSnapshotsTest < Minitest::Test context "XPack MachineLearning: Get model snapshots" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal "_ml/anomaly_detectors/foo/model_snapshots/bar", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.get_model_snapshots :job_id => 'foo', :snapshot_id => 'bar' end end end end end get_overall_buckets_test.rb000066400000000000000000000026741462737751600361400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlGetOverallBucketsTest < Minitest::Test context "XPack MachineLearning: Get overall buckets" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_ml/anomaly_detectors/foo/results/overall_buckets', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.get_overall_buckets :job_id => 'foo' end end end end end get_records_test.rb000066400000000000000000000026351462737751600344120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlGetRecordsTest < Minitest::Test context "XPack MachineLearning: Get records" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal "_ml/anomaly_detectors/foo/results/records", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.get_records :job_id => 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning/open_job_test.rb000066400000000000000000000026151462737751600337620ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlOpenJobTest < Minitest::Test context "XPack MachineLearning: Open job" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/anomaly_detectors/foo/_open", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.open_job :job_id => 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning/post_data_test.rb000066400000000000000000000026471462737751600341520ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlPostDataTest < Minitest::Test context "XPack MachineLearning: Post data" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/anomaly_detectors/foo/_data", url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.ml.post_data :job_id => 'foo', :body => {} end end end end end preview_data_frame_analytics_test.rb000066400000000000000000000044761462737751600400120ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlPreviewDataFrameAnalyticsTest < Minitest::Test context 'XPack MachineLearning: Preview data frame analytics' do subject { FakeClient.new } should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('GET', method) assert_equal('_ml/data_frame/analytics/_preview', url) assert_equal(Hash.new, params) assert_nil(body) true end.returns(FakeResponse.new) subject.xpack.ml.preview_data_frame_analytics end should 'perform correct request with body' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('POST', method) assert_equal('_ml/data_frame/analytics/_preview', url) assert_equal(Hash.new, params) assert_equal(body, {}) true end.returns(FakeResponse.new) subject.xpack.ml.preview_data_frame_analytics(body: {}) end should 'perform correct request with id' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('GET', method) assert_equal('_ml/data_frame/analytics/3/_preview', url) assert_equal(Hash.new, params) assert_nil(body) true end.returns(FakeResponse.new) subject.xpack.ml.preview_data_frame_analytics(id: 3) end end end end end preview_datafeed_test.rb000066400000000000000000000026441462737751600354100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlPreviewDatafeedTest < Minitest::Test context "XPack MachineLearning: Preview datafeed" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal "_ml/datafeeds/foo/_preview", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.preview_datafeed :datafeed_id => 'foo' end end end end end put_datafeed_test.rb000066400000000000000000000026431462737751600345360ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlPutDatafeedTest < Minitest::Test context "XPack MachineLearning: Put datafeed" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal "_ml/datafeeds/foo", url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.ml.put_datafeed :datafeed_id => 'foo', body: {} end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning/put_filter_test.rb000066400000000000000000000026341462737751600343450ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlPutFilterTest < Minitest::Test context "XPack MachineLearning: Put filter" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal "_ml/filters/foo", url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.ml.put_filter :filter_id => 'foo', :body => {} end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning/put_job_test.rb000066400000000000000000000026321462737751600336300ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlPutJobTest < Minitest::Test context "XPack MachineLearning: Put job" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal "_ml/anomaly_detectors/foo", url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.ml.put_job :job_id => 'foo', :body => {} end end end end end put_trained_model_alias_test.rb000066400000000000000000000027261462737751600367620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlPutTrainedModelAliasTest < Minitest::Test context "XPack MachineLearning: Put trained model alias" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('PUT', method) assert_equal("_ml/trained_models/foo/model_aliases/alias", url) assert_equal(Hash.new, params) assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.put_trained_model_alias(model_id: 'foo', model_alias: 'alias') end end end end end revert_model_snapshot_test.rb000066400000000000000000000027361462737751600365220ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlRevertModelSnapshotTest < Minitest::Test context "XPack MachineLearning: Revert model snapshot" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/anomaly_detectors/foo/model_snapshots/bar/_revert", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.revert_model_snapshot :job_id => 'foo', :snapshot_id => 'bar' end end end end end start_datafeed_test.rb000066400000000000000000000026331462737751600350620ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlStartDatafeedTest < Minitest::Test context "XPack MachineLearning: Start datafeed" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/datafeeds/foo/_start", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.start_datafeed :datafeed_id => 'foo' end end end end end stop_datafeed_test.rb000066400000000000000000000026311462737751600347100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlStopDatafeedTest < Minitest::Test context "XPack MachineLearning: Stop datafeed" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/datafeeds/foo/_stop", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.stop_datafeed :datafeed_id => 'foo' end end end end end update_datafeed_test.rb000066400000000000000000000026701462737751600352100ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlUpdateDatafeedTest < Minitest::Test context "XPack MachineLearning: Update datafeed" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/datafeeds/foo/_update", url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.ml.update_datafeed :datafeed_id => 'foo', :body => {} end end end end end update_filter_test.rb000066400000000000000000000026561462737751600347440ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlUpdateFilterTest < Minitest::Test context "XPack MachineLearning: Update filter" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/filters/foo/_update", url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.ml.update_filter :filter_id => 'foo', :body => {} end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning/update_job_test.rb000066400000000000000000000026541462737751600343060ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlUpdateJobTest < Minitest::Test context "XPack MachineLearning: Update job" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/anomaly_detectors/foo/_update", url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.ml.update_job :job_id => 'foo', :body => {} end end end end end update_model_snapshot_test.rb000066400000000000000000000027671462737751600365010ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlUpdateModelSnapshotTest < Minitest::Test context "XPack MachineLearning: Update model snapshot" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/anomaly_detectors/foo/model_snapshots/bar/_update", url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.ml.update_model_snapshot :job_id => 'foo', :snapshot_id => 'bar', :body => {} end end end end end upgrade_job_snapshot_test.rb000066400000000000000000000027261462737751600363130ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlUpdateJobSnapshotTest < Minitest::Test context "XPack MachineLearning: Upgrade job snapshot" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/anomaly_detectors/foo/model_snapshots/bar/_upgrade", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ml.upgrade_job_snapshot(job_id: 'foo', snapshot_id: 'bar') end end end end end validate_detector_test.rb000066400000000000000000000026661462737751600356000ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlValidateDetectorTest < Minitest::Test context "XPack MachineLearning: Validate detector" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/anomaly_detectors/_validate/detector", url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.ml.validate_detector :body => {} end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/machine_learning/validate_test.rb000066400000000000000000000026231462737751600337570ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlValidateTest < Minitest::Test context "XPack MachineLearning: Validate" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_ml/anomaly_detectors/_validate", url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.ml.validate :body => {} end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/migration/000077500000000000000000000000001462737751600273055ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/migration/deprecations_test.rb000066400000000000000000000026071462737751600333560ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMigrationDeprecationsTest < Minitest::Test context "XPack Migration: Deprecations" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_migration/deprecations', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.migration.deprecations end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/monitoring/000077500000000000000000000000001462737751600275015ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/monitoring/bulk_test.rb000066400000000000000000000025721462737751600320300ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMonitoringBulkTest < Minitest::Test context "XPack Monitoring: Bulk" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal '_monitoring/bulk', url assert_equal Hash.new, params assert_equal "", body true end.returns(FakeResponse.new) subject.xpack.monitoring.bulk body: [] end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/rollup/000077500000000000000000000000001462737751600266315ustar00rootroot00000000000000get_rollup_index_caps_test.rb000066400000000000000000000026111462737751600345070ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/rollup# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackMlGetRollupIndexCapsTest < Minitest::Test context 'XPack Rollup: Get index caps' do subject { FakeClient.new } should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal 'foo/_rollup/data', url assert_equal({}, params) assert_nil body true end.returns(FakeResponse.new) subject.xpack.rollup.get_rollup_index_caps(index: 'foo') end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/rollup/rollup_test.rb000066400000000000000000000037311462737751600315360ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackRollupRollupTest < Minitest::Test context 'XPack Rollup: Rollup' do subject { FakeClient.new } should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal 'foo/_rollup/bar', url assert_equal({}, params) assert_equal({}, body) true end.returns(FakeResponse.new) subject.xpack.rollup.rollup(body: {}, index: 'foo', rollup_index: 'bar') end should 'raise argument error without body' do assert_raises ArgumentError do subject.xpack.rollup.rollup(index: 'foo', rollup_index: 'bar') end end should 'raise argument error without index' do assert_raises ArgumentError do subject.xpack.rollup.rollup(body: {}, rollup_index: 'bar') end end should 'raise argument error without rollup_index' do assert_raises ArgumentError do subject.xpack.rollup.rollup(index: 'foo', body: {}) end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/000077500000000000000000000000001462737751600271635ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/authenticate_test.rb000066400000000000000000000026051462737751600332300ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityAuthenticateTest < Minitest::Test context "XPack Security: Authenticate" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_security/_authenticate', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.authenticate end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/change_password_test.rb000066400000000000000000000036741462737751600337300ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityChangePasswordTest < Minitest::Test context "XPack Security: Change password" do subject { FakeClient.new } should "perform correct request for a specific user" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_security/user/foo/_password', url assert_equal Hash.new, params assert_equal 'bar', body[:password] true end.returns(FakeResponse.new) subject.xpack.security.change_password username: 'foo', body: { password: 'bar' } end should "perform correct request for current user" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_security/user/_password', url assert_equal Hash.new, params assert_equal 'bar', body[:password] true end.returns(FakeResponse.new) subject.xpack.security.change_password body: { password: 'bar' } end end end end end clear_api_key_cache_test.rb000066400000000000000000000026501462737751600344050ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityClearCachedRolesTest < Minitest::Test context 'XPack Security: Clear api key cache' do subject { FakeClient.new } should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal '_security/api_key/3/_clear_cache', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.clear_api_key_cache(ids: '3') end end end end end clear_cached_privileges_test.rb000066400000000000000000000027041462737751600353010ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityClearCachedPrivilegesTest < Minitest::Test context "XPack Security: Clear cached privileges" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_security/privilege/test/_clear_cache", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.clear_cached_privileges application: 'test' end end end end end clear_cached_realms_test.rb000066400000000000000000000027001462737751600344070ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityClearCachedRealmsTest < Minitest::Test context "XPack Security: Clear cached realms" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_security/realm/foo,bar/_clear_cache", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.clear_cached_realms :realms => ['foo', 'bar'] end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/clear_cached_roles_test.rb000066400000000000000000000026551462737751600343400ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityClearCachedRolesTest < Minitest::Test context "XPack Security: Clear cached roles" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal '_security/role/foo/_clear_cache', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.clear_cached_roles :name => 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/delete_privileges_test.rb000066400000000000000000000026751462737751600342540ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityDeletePrivilegesTest < Minitest::Test context "XPack Security: Delete privileges" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal '_security/privilege/foo/bar', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.delete_privileges :application => 'foo', name: 'bar' end end end end end delete_role_mapping_test.rb000066400000000000000000000026551462737751600344760ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityDeleteRoleMappingTest < Minitest::Test context "XPack Security: Delete role mapping" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal '_security/role_mapping/foo', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.delete_role_mapping :name => 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/delete_role_test.rb000066400000000000000000000026161462737751600330370ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityDeleteRoleTest < Minitest::Test context "XPack Security: Delete role" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal '_security/role/foo', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.delete_role :name => 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/delete_user_test.rb000066400000000000000000000026221462737751600330510ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityDeleteUserTest < Minitest::Test context "XPack Security: Delete user" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal '_security/user/foo', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.delete_user :username => 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/disable_user_test.rb000066400000000000000000000026331462737751600332140ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityDisableUserTest < Minitest::Test context "XPack Security: Disable user" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal "_security/user/foo/_disable", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.disable_user :username => 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/enable_user_test.rb000066400000000000000000000026271462737751600330420ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityEnableUserTest < Minitest::Test context "XPack Security: Enable user" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal "_security/user/foo/_enable", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.enable_user :username => 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/get_privileges_test.rb000066400000000000000000000054451462737751600335670ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityGetPrivilegesTest < Minitest::Test context "XPack Security: Get privileges" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_security/privilege', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.get_privileges end should "perform correct request for an application but no name" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_security/privilege/foo', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.get_privileges application: 'foo' end should "perform correct request for an application and a single name" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_security/privilege/foo/bar', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.get_privileges application: 'foo', name: 'bar' end should "perform correct request for an application and multiple names" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_security/privilege/foo/bar,baz', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.get_privileges application: 'foo', name: ['bar', 'baz'] end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/get_role_mapping_test.rb000066400000000000000000000035321462737751600340650ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityGetRoleMappingTest < Minitest::Test context "XPack Security: Get role mapping" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal "_security/role_mapping/foo", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.get_role_mapping :name => 'foo' end should "handle a list of roles" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal "_security/role_mapping/foo,bar", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.get_role_mapping :name => ['foo', 'bar'] end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/get_role_test.rb000066400000000000000000000040631462737751600323520ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityGetRoleTest < Minitest::Test context "XPack Security: Get role" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_security/role', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.get_role end should "perform correct request for multiple roles" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_security/role/foo,bar', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.get_role name: ['foo', 'bar'] end should "catch a NotFound exception with the ignore parameter" do subject.expects(:perform_request).raises(NotFound) assert_nothing_raised do subject.xpack.security.get_role name: 'foo', ignore: 404 end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/get_token_test.rb000066400000000000000000000026211462737751600325270ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityGetTokenTest < Minitest::Test context "XPack Security: Get token" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal "_security/oauth2/token", url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.security.get_token :body => {} end end end end end get_user_privileges_test.rb000066400000000000000000000026311462737751600345400ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityGetUserPrivilegesTest < Minitest::Test context "XPack Security: Get user privileges" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal "_security/user/_privileges", url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.get_user_privileges end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/get_user_test.rb000066400000000000000000000040721462737751600323670ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityGetUserTest < Minitest::Test context "XPack Security: Get user" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_security/user', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.get_user end should "perform correct request for multiple roles" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_security/user/foo,bar', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.security.get_user username: ['foo', 'bar'] end should "catch a NotFound exception with the ignore parameter" do subject.expects(:perform_request).raises(NotFound) assert_nothing_raised do subject.xpack.security.get_user username: 'foo', ignore: 404 end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/grant_api_key_test.rb000066400000000000000000000031011462737751600333560ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityGrantApiKey < Minitest::Test context "XPack Security: Grant API Key" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal('POST', method) assert_equal('_security/api_key/grant', url) assert_equal(Hash.new, params) assert_equal(body, {access_token: 'access_token', api_key: 'api_key', grant_type: 'access_token'}) true end.returns(FakeResponse.new) subject.xpack.security.grant_api_key( body: {access_token: 'access_token', api_key: 'api_key', grant_type: 'access_token'} ) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/has_privileges_test.rb000066400000000000000000000040241462737751600335530ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityHasPrivilegesTest < Minitest::Test context "XPack Security: Has Privileges" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal '_security/user/_has_privileges', url assert_equal Hash.new, params assert_equal({ cluster: [], index: [], application: [] }, body) true end.returns(FakeResponse.new) subject.xpack.security.has_privileges(body: { cluster: [], index: [], application: [] }) end should "check privileges for a specific user" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal '_security/user/foo/_has_privileges', url assert_equal Hash.new, params assert_equal({ cluster: [], index: [], application: [] }, body) true end.returns(FakeResponse.new) subject.xpack.security.has_privileges(user: 'foo', body: { cluster: [], index: [], application: [] }) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/invalidate_token_test.rb000066400000000000000000000026501462737751600340720ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityInvalidateTokenTest < Minitest::Test context "XPack Security: Invalidate token" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal "_security/oauth2/token", url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.security.invalidate_token :body => {} end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/put_privileges_test.rb000066400000000000000000000027751462737751600336230ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityPutPrivilegesTest < Minitest::Test context "XPack Security: Put role" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_security/privilege', url assert_equal Hash.new, params assert_equal({ "app-allow": { read: { actions: [ "data:read/*" ] } } }, body) true end.returns(FakeResponse.new) subject.xpack.security.put_privileges(body: { "app-allow": { read: { actions: [ "data:read/*" ] } } }) end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/put_role_mapping_test.rb000066400000000000000000000026701462737751600341200ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityPutRoleMappingTest < Minitest::Test context "XPack Security: Put role mapping" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal "_security/role_mapping/foo", url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.security.put_role_mapping :name => 'foo', :body => {} end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/put_role_test.rb000066400000000000000000000026261462737751600324060ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityPutRoleTest < Minitest::Test context "XPack Security: Put role" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_security/role/foo', url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.security.put_role :name => 'foo', body: {} end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/security/put_user_test.rb000066400000000000000000000026271462737751600324240ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSecurityPutUserTest < Minitest::Test context "XPack Security: Put user" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_security/user/foo', url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.security.put_user username: 'foo', body: {} end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/ssl/000077500000000000000000000000001462737751600261155ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/ssl/certificates_test.rb000066400000000000000000000025601462737751600321510ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackSslCertificatesTest < Minitest::Test context "XPack Ssl: Certificates" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_ssl/certificates', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.ssl.certificates end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/text_structure/000077500000000000000000000000001462737751600304205ustar00rootroot00000000000000find_structure_test.rb000066400000000000000000000031331462737751600347650ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/text_structure# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackTextStructureFindStructureTest < Minitest::Test context 'Text Structure: Find Text Structure' do subject { FakeClient.new } should 'perform correct request' do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal '_text_structure/find_structure', url assert_equal({}, params) assert_equal({}, body) true end.returns(FakeResponse.new) subject.xpack.text_structure.find_structure(body: {}) end should 'raise argument error without body' do assert_raises ArgumentError do subject.xpack.text_structure.find_structure end end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/usage_test.rb000066400000000000000000000025131462737751600300050ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackUsageTest < Minitest::Test context "XPack: Usage" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_xpack/usage', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.usage end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/watcher/000077500000000000000000000000001462737751600267515ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/watcher/ack_watch_test.rb000066400000000000000000000035351462737751600322670ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackWatcherAckWatchTest < Minitest::Test context "XPack Watcher: Ack watch" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_watcher/watch/foo/_ack', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.watcher.ack_watch watch_id: 'foo' end should "perform correct request when action id is provided" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_watcher/watch/foo/_ack/bar', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.watcher.ack_watch watch_id: 'foo', action_id: 'bar' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/watcher/activate_watch_test.rb000066400000000000000000000026341462737751600333300ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackWatcherActivateWatchTest < Minitest::Test context "XPack Watcher: Activate watch" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_watcher/watch/foo/_activate', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.watcher.activate_watch watch_id: 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/watcher/deactivate_watch_test.rb000066400000000000000000000026441462737751600336420ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackWatcherDeactivateWatchTest < Minitest::Test context "XPack Watcher: Deactivate watch" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_watcher/watch/foo/_deactivate', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.watcher.deactivate_watch watch_id: 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/watcher/delete_watch_test.rb000066400000000000000000000026111462737751600327650ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackWatcherDeleteWatchTest < Minitest::Test context "XPack Watcher: Delete watch" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'DELETE', method assert_equal '_watcher/watch/foo', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.watcher.delete_watch id: 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/watcher/execute_watch_test.rb000066400000000000000000000034731462737751600331740ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackWatcherExecuteWatchTest < Minitest::Test context "XPack Watcher: Execute watch" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_watcher/watch/foo/_execute', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.watcher.execute_watch id: 'foo' end should "perform correct request with no id specified" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_watcher/watch/_execute', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.watcher.execute_watch end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/watcher/get_watch_test.rb000066400000000000000000000025751462737751600323130ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackWatcherGetWatchTest < Minitest::Test context "XPack Watcher: Get watch" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_watcher/watch/foo', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.watcher.get_watch id: 'foo' end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/watcher/put_watch_test.rb000066400000000000000000000026211462737751600323340ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackWatcherPutWatchTest < Minitest::Test context "XPack Watcher: Put watch" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'PUT', method assert_equal '_watcher/watch/foo', url assert_equal Hash.new, params assert_equal Hash.new, body true end.returns(FakeResponse.new) subject.xpack.watcher.put_watch id: 'foo', body: {} end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/watcher/query_watches_test.rb000066400000000000000000000034641462737751600332270ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackWatcherQueryWatchesTest < Minitest::Test context "XPack Watcher: Query Watches" do subject { FakeClient.new } should "perform correct request with body" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal '_watcher/_query/watches', url assert_equal({}, params) assert_equal({}, body) true end.returns(FakeResponse.new) subject.xpack.watcher.query_watches(body: {}) end should "perform correct request without body" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_watcher/_query/watches', url assert_equal({}, params) assert_nil body true end.returns(FakeResponse.new) subject.xpack.watcher.query_watches end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/watcher/start_test.rb000066400000000000000000000025461462737751600315010ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackWatcherStartTest < Minitest::Test context "XPack Watcher: Start" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal '_watcher/_start', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.watcher.start end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/watcher/stats_test.rb000066400000000000000000000025441462737751600315000ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackWatcherStatsTest < Minitest::Test context "XPack Watcher: Stats" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'GET', method assert_equal '_watcher/stats', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.watcher.stats end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch-xpack/test/unit/watcher/stop_test.rb000066400000000000000000000025421462737751600313250ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'test_helper' module Elasticsearch module Test class XPackWatcherStopTest < Minitest::Test context "XPack Watcher: Stop" do subject { FakeClient.new } should "perform correct request" do subject.expects(:perform_request).with do |method, url, params, body| assert_equal 'POST', method assert_equal '_watcher/_stop', url assert_equal Hash.new, params assert_nil body true end.returns(FakeResponse.new) subject.xpack.watcher.stop end end end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch/000077500000000000000000000000001462737751600222525ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch/.gitignore000066400000000000000000000005451462737751600242460ustar00rootroot00000000000000# Licensed to Elasticsearch B.V under one or more agreements. # Elasticsearch B.V licenses this file to you under the Apache 2.0 License. # See the LICENSE file in the project root for more information *.gem *.rbc .bundle .config .yardoc Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp elastic-elasticsearch-ruby-c38be0c/elasticsearch/Gemfile000066400000000000000000000027571462737751600235600ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. source 'https://rubygems.org' # Specify your gem's dependencies in elasticsearch.gemspec gemspec if File.exist? File.expand_path("../../elasticsearch-api/elasticsearch-api.gemspec", __FILE__) gem 'elasticsearch-api', :path => File.expand_path("../../elasticsearch-api", __FILE__), :require => false end if File.exist? File.expand_path("../../elasticsearch-transport/elasticsearch-transport.gemspec", __FILE__) gem 'elasticsearch-transport', :path => File.expand_path("../../elasticsearch-transport", __FILE__), :require => false end if File.exist? File.expand_path("../../elasticsearch-extensions", __FILE__) gem 'elasticsearch-extensions', :path => File.expand_path("../../elasticsearch-extensions", __FILE__), :require => true end elastic-elasticsearch-ruby-c38be0c/elasticsearch/LICENSE000066400000000000000000000261361462737751600232670ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. elastic-elasticsearch-ruby-c38be0c/elasticsearch/README.md000066400000000000000000000063331462737751600235360ustar00rootroot00000000000000# Elasticsearch The `elasticsearch` library provides a Ruby client and API for [Elasticsearch](http://elasticsearch.com). Features overview: * Pluggable logging and tracing * Pluggable connection selection strategies (round-robin, random, custom) * Pluggable transport implementation, customizable and extendable * Pluggable serializer implementation * Request retries and dead connections handling * Node reloading (based on cluster state) on errors or on demand * Consistent API support for the whole Elasticsearch API * Extensive documentation and examples * Emphasis on modularity and extendability of both the client and API libraries (For integration with Ruby models and Rails applications, see the project.) ## Compatibility The Elasticsearch client for Ruby is compatible with Ruby 1.9 and higher. The client's API is compatible with Elasticsearch's API versions from 0.90 till current, just use a release matching major version of Elasticsearch. | Ruby | | Elasticsearch | |:-------------:|:-:| :-----------: | | 0.90 | → | 0.90 | | 1.x | → | 1.x | | 2.x | → | 2.x | | 5.x | → | 5.x | | 6.x | → | 6.x | | 7.x | → | 7.x | | master | → | master | ## Installation Install the package from [Rubygems](https://rubygems.org): gem install elasticsearch To use an unreleased version, either add it to your `Gemfile` for [Bundler](http://gembundler.com): gem 'elasticsearch', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git' or install it from a source code checkout: git clone https://github.com/elasticsearch/elasticsearch-ruby.git cd elasticsearch-ruby/elasticsearch bundle install rake install ## Usage This library is a wrapper for two separate libraries: * [`elasticsearch-transport`](https://github.com/elasticsearch/elasticsearch-ruby/tree/master/elasticsearch-transport), which provides a low-level Ruby client for connecting to an [Elasticsearch](http://elasticsearch.com) cluster * [`elasticsearch-api`](https://github.com/elasticsearch/elasticsearch-ruby/tree/master/elasticsearch-api), which provides a Ruby API for the Elasticsearch RESTful API Install the `elasticsearch` package and use the API directly: ```ruby require 'elasticsearch' client = Elasticsearch::Client.new log: true client.cluster.health client.transport.reload_connections! client.search q: 'test' # etc. ``` Please refer to the specific library documentation for details: * **Transport**: [[README]](https://github.com/elasticsearch/elasticsearch-ruby/blob/master/elasticsearch-transport/README.md) [[Documentation]](http://rubydoc.info/gems/elasticsearch-transport/file/README.markdown) * **API**: [[README]](https://github.com/elasticsearch/elasticsearch-ruby/blob/master/elasticsearch-api/README.md) [[Documentation]](http://rubydoc.info/gems/elasticsearch-api/file/README.markdown) ## Development You can run `rake -T` to check the test tasks. Use `COVERAGE=true` before running a test task to check the coverage with Simplecov. ## License This software is licensed under the [Apache 2 license](./LICENSE).elastic-elasticsearch-ruby-c38be0c/elasticsearch/Rakefile000066400000000000000000000032361462737751600237230ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'bundler/gem_tasks' task(:default) { system 'rake --tasks' } desc 'Run unit tests' task test: 'test:spec' # ----- Test tasks ------------------------------------------------------------ require 'rspec/core/rake_task' namespace :test do desc 'Wait for Elasticsearch to be in a green state' task :wait_for_green do sh '../scripts/wait-cluster.sh' end RSpec::Core::RakeTask.new(:integration) do |t| t.pattern = 'spec/integration/**{,/*/**}/*_spec.rb' end RSpec::Core::RakeTask.new(:unit) do |t| t.pattern = 'spec/unit/**{,/*/**}/*_spec.rb' end desc 'Run unit and integration tests' task :all do Rake::Task['test:unit'].invoke Rake::Task['test:integration'].invoke end end # ----- Documentation tasks --------------------------------------------------- require 'yard' YARD::Rake::YardocTask.new(:doc) do |t| t.options = %w| --embed-mixins --markup=markdown | end elastic-elasticsearch-ruby-c38be0c/elasticsearch/bin/000077500000000000000000000000001462737751600230225ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch/bin/elastic_ruby_console000077500000000000000000000023601462737751600271600ustar00rootroot00000000000000#!/usr/bin/env ruby $LOAD_PATH.unshift(File.expand_path('../../elasticsearch/lib', __dir__)) $LOAD_PATH.unshift(File.expand_path('../../elasticsearch-transport/lib', __dir__)) $LOAD_PATH.unshift(File.expand_path('../../elasticsearch-dsl/lib', __dir__)) $LOAD_PATH.unshift(File.expand_path('../../elasticsearch-api/lib', __dir__)) $LOAD_PATH.unshift(File.expand_path('../../elasticsearch-xpack/lib', __dir__)) $LOAD_PATH.unshift(File.expand_path('../../elasticsearch-extensions/lib', __dir__)) require 'elasticsearch' require 'elasticsearch-transport' require 'elasticsearch-api' gems_not_loaded = ['elasticsearch-dsl', 'elasticsearch/xpack', 'elasticsearch-extensions'].reject do |gem| begin (require gem) || true rescue LoadError false end end unless gems_not_loaded.empty? warn "The following gems were not loaded: [#{gems_not_loaded.join(', ')}]. Please install and require them explicitly." end include Elasticsearch include Elasticsearch::DSL if defined?(Elasticsearch::DSL) begin require 'pry' rescue LoadError end begin require 'irb' rescue LoadError end if defined?(Pry) Pry.config.prompt_name = 'elastic_ruby' Pry.start elsif defined?(IRB) IRB.start else abort 'LoadError: elastic_ruby_console requires Pry or IRB' end elastic-elasticsearch-ruby-c38be0c/elasticsearch/elasticsearch.gemspec000066400000000000000000000055131462737751600264350ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'elasticsearch/version' Gem::Specification.new do |s| s.name = 'elasticsearch' s.version = Elasticsearch::VERSION s.authors = ['Karel Minarik'] s.email = ['karel.minarik@elasticsearch.org'] s.summary = 'Ruby integrations for Elasticsearch' s.homepage = 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.16/index.html' s.license = 'Apache-2.0' s.metadata = { 'homepage_uri' => 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.16/index.html', 'changelog_uri' => 'https://github.com/elastic/elasticsearch-ruby/blob/7.16/CHANGELOG.md', 'source_code_uri' => 'https://github.com/elastic/elasticsearch-ruby/tree/7.16', 'bug_tracker_uri' => 'https://github.com/elastic/elasticsearch-ruby/issues' } s.files = `git ls-files`.split($/) s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } s.executables << 'elastic_ruby_console' s.test_files = s.files.grep(%r{^(test|spec|features)/}) s.require_paths = ['lib'] s.bindir = 'bin' s.extra_rdoc_files = [ 'README.md', 'LICENSE' ] s.rdoc_options = [ '--charset=UTF-8' ] s.required_ruby_version = '>= 2.4' s.add_dependency 'elasticsearch-transport', '7.17.11' s.add_dependency 'elasticsearch-api', '7.17.11' s.add_development_dependency 'bundler' s.add_development_dependency 'byebug' unless defined?(JRUBY_VERSION) || defined?(Rubinius) s.add_development_dependency 'pry' s.add_development_dependency 'rake', '~> 13' s.add_development_dependency 'require-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius) s.add_development_dependency 'rspec' s.add_development_dependency 'ruby-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius) s.add_development_dependency 'simplecov' s.add_development_dependency 'webmock' s.add_development_dependency 'yard' s.description = <<-DESC.gsub(/^ /, '') Ruby integrations for Elasticsearch (client, API, etc.) DESC end elastic-elasticsearch-ruby-c38be0c/elasticsearch/lib/000077500000000000000000000000001462737751600230205ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch/lib/elasticsearch-ruby.rb000066400000000000000000000014401462737751600271350ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'elasticsearch' elastic-elasticsearch-ruby-c38be0c/elasticsearch/lib/elasticsearch.rb000066400000000000000000000106501462737751600261610ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'elasticsearch/version' require 'elasticsearch/transport' require 'elasticsearch/api' module Elasticsearch SECURITY_PRIVILEGES_VALIDATION_WARNING = 'The client is unable to verify that the server is Elasticsearch due to security privileges on the server side. Some functionality may not be compatible if the server is running an unsupported product.'.freeze NOT_ELASTICSEARCH_WARNING = 'The client noticed that the server is not Elasticsearch and we do not support this unknown product.'.freeze NOT_SUPPORTED_ELASTICSEARCH_WARNING = 'The client noticed that the server is not a supported distribution of Elasticsearch.'.freeze YOU_KNOW_FOR_SEARCH = 'You Know, for Search'.freeze class Client include Elasticsearch::API attr_accessor :transport # See Elasticsearch::Transport::Client for initializer parameters def initialize(arguments = {}, &block) @verified = false @transport = Elasticsearch::Transport::Client.new(arguments, &block) end def method_missing(name, *args, &block) if name == :perform_request verify_elasticsearch unless @verified @transport.perform_request(*args, &block) else super end end private def verify_elasticsearch begin response = elasticsearch_validation_request rescue Elasticsearch::Transport::Transport::Errors::Unauthorized, Elasticsearch::Transport::Transport::Errors::Forbidden, Elasticsearch::Transport::Transport::Errors::RequestEntityTooLarge @verified = true warn(SECURITY_PRIVILEGES_VALIDATION_WARNING) return end body = if response.headers['content-type'] == 'application/yaml' require 'yaml' YAML.safe_load(response.body) else response.body end version = body.dig('version', 'number') verify_with_version_or_header(body, version, response.headers) end def verify_with_version_or_header(body, version, headers) raise Elasticsearch::UnsupportedProductError if version.nil? || version < '6.0.0' if version == '7.x-SNAPSHOT' || Gem::Version.new(version) >= Gem::Version.new('7.14-SNAPSHOT') raise Elasticsearch::UnsupportedProductError unless headers['x-elastic-product'] == 'Elasticsearch' @verified = true elsif Gem::Version.new(version) > Gem::Version.new('6.0.0') && Gem::Version.new(version) < Gem::Version.new('7.0.0') raise Elasticsearch::UnsupportedProductError unless body['tagline'] == YOU_KNOW_FOR_SEARCH @verified = true elsif Gem::Version.new(version) >= Gem::Version.new('7.0.0') && Gem::Version.new(version) < Gem::Version.new('7.14-SNAPSHOT') raise Elasticsearch::UnsupportedProductError unless body['tagline'] == YOU_KNOW_FOR_SEARCH raise Elasticsearch::UnsupportedProductError.new(NOT_SUPPORTED_ELASTICSEARCH_WARNING) unless body.dig('version', 'build_flavor') == 'default' @verified = true end end def elasticsearch_validation_request @transport.perform_request('GET', '/') end end class UnsupportedProductError < StandardError def initialize(message = NOT_ELASTICSEARCH_WARNING) super(message) end end end module Elastic # If the version is X.X.X.pre/alpha/beta, use X.X.Xp for the meta-header: def self.client_meta_version regexp = /^([0-9]+\.[0-9]+\.[0-9]+)\.?([a-z0-9.-]+)?$/ match = Elasticsearch::VERSION.match(regexp) return "#{match[1]}p" if match[2] Elasticsearch::VERSION end # Constant for elasticsearch-transport meta-header ELASTICSEARCH_SERVICE_VERSION = [:es, client_meta_version].freeze end elastic-elasticsearch-ruby-c38be0c/elasticsearch/lib/elasticsearch/000077500000000000000000000000001462737751600256325ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch/lib/elasticsearch/version.rb000066400000000000000000000014761462737751600276540ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch VERSION = '7.17.11'.freeze end elastic-elasticsearch-ruby-c38be0c/elasticsearch/spec/000077500000000000000000000000001462737751600232045ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch/spec/integration/000077500000000000000000000000001462737751600255275ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch/spec/integration/characters_escaping_spec.rb000066400000000000000000000066061462737751600330660ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'uri' ELASTICSEARCH_URL = ENV['TEST_ES_SERVER'] || "http://localhost:#{(ENV['PORT'] || 9200)}" raise URI::InvalidURIError unless ELASTICSEARCH_URL =~ /\A#{URI::DEFAULT_PARSER.make_regexp}\z/ require 'spec_helper' context 'Elasticsearch client' do let(:client) do Elasticsearch::Client.new(host: ELASTICSEARCH_URL, user: 'elastic', password: 'changeme') end let(:index) { 'tvs' } after do client.indices.delete(index: index) end context 'escaping spaces in ids' do it 'escapes spaces for id when using index' do response = client.index(index: index, id: 'a test 1', body: { name: 'A test 1' }, refresh: true) expect(response['_id']).to eq 'a test 1' response = client.search(index: index) expect(response['hits']['hits'].first['_id']).to eq 'a test 1' # Raises exception, _id is unrecognized expect do client.index(index: index, _id: 'a test 2', body: { name: 'A test 2' }) end.to raise_exception ArgumentError # Raises exception, id is a query parameter expect do client.index(index: index, body: { name: 'A test 3', _id: 'a test 3' }) end.to raise_exception Elasticsearch::Transport::Transport::Errors::BadRequest end it 'escapes spaces for id when using create' do # Works with create response = client.create(index: index, id: 'a test 4', body: { name: 'A test 4' }) expect(response['_id']).to eq 'a test 4' end it 'escapes spaces for id when using bulk' do body = [ { create: { _index: index, _id: 'a test 5', data: { name: 'A test 5' } } } ] expect(client.bulk(body: body, refresh: true)) response = client.search(index: index) expect( response['hits']['hits'].select { |a| a['_id'] == 'a test 5' }.size ).to eq 1 end end context 'it doesnae escape plus signs in id' do it 'escapes spaces for id when using index' do response = client.index(index: index, id: 'a+test+1', body: { name: 'A test 1' }) expect(response['_id']).to eq 'a+test+1' end it 'escapes spaces for id when using create' do # Works with create response = client.create(index: index, id: 'a+test+2', body: { name: 'A test 2' }) expect(response['_id']).to eq 'a+test+2' end it 'escapes spaces for id when using bulk' do body = [ { create: { _index: index, _id: 'a+test+3', data: { name: 'A test 3' } } } ] expect(client.bulk(body: body, refresh: true)) response = client.search(index: index) expect( response['hits']['hits'].select { |a| a['_id'] == 'a+test+3' }.size ).to eq 1 end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch/spec/integration/client_integration_spec.rb000066400000000000000000000036411462737751600327530ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' require 'logger' context 'Elasticsearch client' do let(:logger) { Logger.new($stderr) } let(:client) do Elasticsearch::Client.new( host: ELASTICSEARCH_URL, logger: logger ) end context 'Integrates with elasticsearch API' do it 'should perform the API methods' do expect do # Index a document client.index(index: 'test-index', id: '1', body: { title: 'Test' }) # Refresh the index client.indices.refresh(index: 'test-index') # Search response = client.search(index: 'test-index', body: { query: { match: { title: 'test' } } }) expect(response['hits']['total']['value']).to eq 1 expect(response['hits']['hits'][0]['_source']['title']).to eq 'Test' # Delete the index client.indices.delete(index: 'test-index') end.not_to raise_error end end context 'Reports the right meta header' do it 'Reports es service name and gem version' do headers = client.transport.transport.connections.first.connection.headers expect(headers['x-elastic-client-meta']).to match Elastic.client_meta_version end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch/spec/integration/validation_integration_spec.rb000066400000000000000000000022341462737751600336240ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' require 'logger' describe 'Elasticsearch validation integration' do it 'Validates for Elasticsearch > 7.14' do client = Elasticsearch::Client.new( host: ELASTICSEARCH_URL, logger: Logger.new($stderr) ) expect(client.instance_variable_get('@verified')).to be false client.count expect(client.instance_variable_get('@verified')).to be true end end elastic-elasticsearch-ruby-c38be0c/elasticsearch/spec/spec_helper.rb000066400000000000000000000020571462737751600260260ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'elasticsearch' require 'rspec' ELASTICSEARCH_URL = ENV['TEST_ES_SERVER'] || "http://localhost:#{(ENV['PORT'] || 9200)}" raise URI::InvalidURIError unless ELASTICSEARCH_URL =~ /\A#{URI::DEFAULT_PARSER.make_regexp}\z/ RSpec.configure do |config| config.formatter = :documentation end elastic-elasticsearch-ruby-c38be0c/elasticsearch/spec/unit/000077500000000000000000000000001462737751600241635ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/elasticsearch/spec/unit/elasticsearch_product_validation_spec.rb000066400000000000000000000277071462737751600343230ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'spec_helper' require 'webmock/rspec' describe 'Elasticsearch: Validation' do let(:host) { 'http://localhost:9200' } let(:verify_request_stub) do stub_request(:get, host) .to_return(status: status, body: body, headers: headers) end let(:count_request_stub) do stub_request(:get, "#{host}/_count") .to_return(status: 200, body: nil, headers: {}) end let(:status) { 200 } let(:body) { {}.to_json } let(:client) { Elasticsearch::Client.new } let(:headers) do { 'content-type' => 'json' } end def error_requests_and_expectations(message = Elasticsearch::NOT_ELASTICSEARCH_WARNING) expect { client.count }.to raise_error Elasticsearch::UnsupportedProductError, message assert_requested :get, host assert_not_requested :get, "#{host}/_count" expect { client.cluster.health }.to raise_error Elasticsearch::UnsupportedProductError, message expect(client.instance_variable_get('@verified')).to be false expect { client.cluster.health }.to raise_error Elasticsearch::UnsupportedProductError, message end def valid_requests_and_expectations expect(client.instance_variable_get('@verified')).to be false assert_not_requested :get, host client.count expect(client.instance_variable_get('@verified')) assert_requested :get, host assert_requested :get, "#{host}/_count" end context 'When Elasticsearch replies with status 401' do let(:status) { 401 } let(:body) { {}.to_json } it 'Verifies the request but shows a warning' do stderr = $stderr fake_stderr = StringIO.new $stderr = fake_stderr verify_request_stub count_request_stub valid_requests_and_expectations fake_stderr.rewind expect(fake_stderr.string).to eq("#{Elasticsearch::SECURITY_PRIVILEGES_VALIDATION_WARNING}\n") ensure $stderr = stderr end end context 'When Elasticsearch replies with status 403' do let(:status) { 403 } let(:body) { {}.to_json } it 'Verifies the request but shows a warning' do stderr = $stderr fake_stderr = StringIO.new $stderr = fake_stderr verify_request_stub count_request_stub valid_requests_and_expectations fake_stderr.rewind expect(fake_stderr.string).to eq("#{Elasticsearch::SECURITY_PRIVILEGES_VALIDATION_WARNING}\n") ensure $stderr = stderr end end context 'When Elasticsearch replies with status 403' do let(:status) { 413 } let(:body) { {}.to_json } it 'Verifies the request but shows a warning' do stderr = $stderr fake_stderr = StringIO.new $stderr = fake_stderr verify_request_stub count_request_stub valid_requests_and_expectations fake_stderr.rewind expect(fake_stderr.string).to eq("#{Elasticsearch::SECURITY_PRIVILEGES_VALIDATION_WARNING}\n") ensure $stderr = stderr end end context 'When the Elasticsearch version is >= 7.14' do context 'With a valid Elasticsearch response' do let(:body) { { 'version' => { 'number' => '7.14.0' } }.to_json } let(:headers) do { 'X-Elastic-Product' => 'Elasticsearch', 'content-type' => 'json' } end it 'Makes requests and passes validation' do verify_request_stub count_request_stub valid_requests_and_expectations end end context 'When the header is not present' do it 'Fails validation' do verify_request_stub expect(client.instance_variable_get('@verified')).to be false assert_not_requested :get, host error_requests_and_expectations end end end context 'When the Elasticsearch version is >= 7.14-SNAPSHOT' do context 'With a valid Elasticsearch response' do let(:body) { { 'version' => { 'number' => '7.14-SNAPSHOT' } }.to_json } let(:headers) do { 'X-Elastic-Product' => 'Elasticsearch', 'content-type' => 'json' } end it 'Makes requests and passes validation' do verify_request_stub count_request_stub valid_requests_and_expectations end end context 'When the header is not present' do it 'Fails validation' do verify_request_stub expect(client.instance_variable_get('@verified')).to be false assert_not_requested :get, host error_requests_and_expectations end end end context 'When the Elasticsearch version is >= 7.15-SNAPSHOT' do context 'With a valid Elasticsearch response' do let(:body) { { 'version' => { 'number' => '7.15-SNAPSHOT' } }.to_json } let(:headers) do { 'X-Elastic-Product' => 'Elasticsearch', 'content-type' => 'json' } end it 'Makes requests and passes validation' do verify_request_stub count_request_stub valid_requests_and_expectations end end context 'When the header is not present' do it 'Fails validation' do verify_request_stub expect(client.instance_variable_get('@verified')).to be false assert_not_requested :get, host error_requests_and_expectations end end end context 'When the version is 7.x-SNAPSHOT' do let(:body) { { 'version' => { 'number' => '7.x-SNAPSHOT' } }.to_json } context 'When the header is not present' do it 'Fails validation' do verify_request_stub count_request_stub error_requests_and_expectations end end context 'With a valid Elasticsearch response' do let(:headers) do { 'X-Elastic-Product' => 'Elasticsearch', 'content-type' => 'json' } end it 'Makes requests and passes validation' do verify_request_stub count_request_stub valid_requests_and_expectations end end end context 'When Elasticsearch version is 7.4.0' do context 'When tagline is not present' do let(:body) { { 'version' => { 'number' => '7.4.0', 'build_flavor' => 'default' } }.to_json } it 'Fails validation' do verify_request_stub count_request_stub error_requests_and_expectations end end context 'When build flavor is not present' do let(:body) do { 'version' => { 'number' => '7.4.0' }, 'tagline' => Elasticsearch::YOU_KNOW_FOR_SEARCH }.to_json end it 'Fails validation' do verify_request_stub count_request_stub error_requests_and_expectations(Elasticsearch::NOT_SUPPORTED_ELASTICSEARCH_WARNING) end end context 'When the tagline is different' do let(:body) do { 'version' => { 'number' => '7.4.0', 'build_flavor' => 'default' }, 'tagline' => 'You Know, for other stuff' }.to_json end it 'Fails validation' do verify_request_stub count_request_stub error_requests_and_expectations end end context 'With a valid Elasticsearch response' do let(:body) do { 'version' => { 'number' => '7.4.0', 'build_flavor' => 'default' }, 'tagline' => 'You Know, for Search' }.to_json end it 'Makes requests and passes validation' do verify_request_stub count_request_stub valid_requests_and_expectations end end end context 'When Elasticsearch version is < 6.0.0' do let(:body) { { 'version' => { 'number' => '5.0.0' } }.to_json } it 'Raises an exception and client doesnae work' do verify_request_stub error_requests_and_expectations end end context 'When there is no version data' do let(:body) { {}.to_json } it 'Raises an exception and client doesnae work' do verify_request_stub error_requests_and_expectations end end context 'When Elasticsearch version is between 6.0.0 and 7.0.0' do context 'With an Elasticsearch valid response' do let(:body) do { 'version' => { 'number' => '6.8.10' }, 'tagline' => 'You Know, for Search' }.to_json end it 'Makes requests and passes validation' do verify_request_stub count_request_stub valid_requests_and_expectations end end context 'With no tagline' do let(:body) do { 'version' => { 'number' => '6.8.10' } }.to_json end it 'Fails validation' do verify_request_stub count_request_stub error_requests_and_expectations end end context 'When the tagline is different' do let(:body) do { 'version' => { 'number' => '6.8.10', 'build_flavor' => 'default' }, 'tagline' => 'You Know, for Stuff' }.to_json end it 'Fails validation' do verify_request_stub count_request_stub error_requests_and_expectations end end end context 'When Elasticsearch version is between 7.0.0 and 7.14.0' do context 'With a valid Elasticsearch response' do let(:body) do { 'version' => { 'number' => '7.10.0', 'build_flavor' => 'default' }, 'tagline' => 'You Know, for Search' }.to_json end it 'Makes requests and passes validation' do verify_request_stub count_request_stub valid_requests_and_expectations end end context 'When the tagline is not present' do let(:body) do { 'version' => { 'number' => '7.10.0', 'build_flavor' => 'default' } }.to_json end it 'Fails validation' do verify_request_stub count_request_stub error_requests_and_expectations end end context 'When the tagline is different' do let(:body) do { 'version' => { 'number' => '7.10.0', 'build_flavor' => 'default' }, 'tagline' => 'You Know, for other stuff' }.to_json end it 'Fails validation' do verify_request_stub count_request_stub error_requests_and_expectations end end context 'When the build_flavor is not present' do let(:body) do { 'version' => { 'number' => '7.10.0' }, 'tagline' => 'You Know, for Search' }.to_json end it 'Fails validation' do verify_request_stub count_request_stub error_requests_and_expectations(Elasticsearch::NOT_SUPPORTED_ELASTICSEARCH_WARNING) end end end context 'When doing a yaml content-type request' do let(:client) do Elasticsearch::Client.new(transport_options: {headers: { accept: 'application/yaml', content_type: 'application/yaml' }}) end let(:headers) { { 'content-type' => 'application/yaml', 'X-Elastic-Product' => 'Elasticsearch' } } let(:body) { "---\nversion:\n number: \"7.14.0-SNAPSHOT\"\n" } it 'validates' do verify_request_stub count_request_stub valid_requests_and_expectations end end end elastic-elasticsearch-ruby-c38be0c/elasticsearch/spec/unit/wrapper_gem_spec.rb000066400000000000000000000027031462737751600300340ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'elasticsearch' require 'webmock/rspec' describe 'Elasticsearch: wrapper gem' do it 'requires all neccessary subgems' do expect(defined?(Elasticsearch::Client)) expect(defined?(Elasticsearch::API)) end it 'mixes the API into the client' do client = Elasticsearch::Client.new expect(client).to respond_to(:search) expect(client).to respond_to(:cluster) expect(client).to respond_to(:indices) end it 'can access the client transport' do client = Elasticsearch::Client.new expect(client.transport).to be_a(Elasticsearch::Transport::Client) expect(client.transport.transport).to be_a(Elasticsearch::Transport::Transport::HTTP::Faraday) end end elastic-elasticsearch-ruby-c38be0c/examples/000077500000000000000000000000001462737751600212565ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/examples/README.md000066400000000000000000000012451462737751600225370ustar00rootroot00000000000000# Doc Examples In this directory you can find: - `apm`: A practical example of integrating elasticsearch-ruby and [Elastic APM](https://www.elastic.co/apm) with the [Ruby APM Agent](https://github.com/elastic/apm-agent-ruby). See the [the README](https://github.com/elastic/elasticsearch-ruby/tree/master/docs/examples/apm/README.md#observability-example). - `guide`: Contains the generated Ruby code examples for the [Elasticsearch Reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html). - `percolator`: An example using a percolator in Elasticsearch version 5.x and higher. - `rabbitmq`: Example of indexing the payload of a RabbitMQ queue. elastic-elasticsearch-ruby-c38be0c/examples/apm/000077500000000000000000000000001462737751600220335ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/examples/apm/Gemfile000066400000000000000000000015471462737751600233350ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. source 'https://rubygems.org' do gem 'elastic-apm' gem 'elasticsearch' gem 'sinatra' end elastic-elasticsearch-ruby-c38be0c/examples/apm/README.md000066400000000000000000000051021462737751600233100ustar00rootroot00000000000000# Observability Example This example provides a `docker-compose` file based on the [Quick start development environment](https://www.elastic.co/guide/en/apm/get-started/current/quick-start-overview.html) for APM. It gets the default distributions of Elasticsearch, Kibana and APM Server up and running in Docker. The docker-compose file also includes a basic Sinatra App and a script to ping the web app with different endpoints. Run `docker-compose up` on the root folder of this example and you'll get everything set up. Follow the steps on the full documentation [at elastic.co](https://www.elastic.co/guide/en/apm/get-started/current/quick-start-overview.html) to get APM set up in your Kibana instance. [Install Docker Compose](https://docs.docker.com/compose/install/), cd into this directory and run it: ```bash $ cd docs/examples/apm $ docker-compose up ``` The following services will be available: - Kibana: http: //localhost:5061 - Elasticsearch: http: //localhost:9200 - APM Server: http: //localhost:8200 - Example Sinatra app: http: //localhost:9292 Use your web browser or `curl` against http://localhost:9292/ to check that everything is working. You should see a JSON response from `cluster.health`. The docker-compose file will also run a `pinger` script. This script will make requests irregularly to the web app to simulate proper traffic and fill your APM Dashboard with data, even errors. You can comment the pinger container from `docker-compose.yml` if you want to have all the services running and test the different endpoints (or add your own) by yourself. # Screenshot ![Kibana APM Dashboard](screenshot.jpg) # Routes in the example Sinatra app Once the app is running, you can open the following routes in your web browser or via `curl`. The responses are in JSON: * `/` - The root path returns the response from `cluster.health` * `/ingest` - This will bulk insert 1,000 documents in the `games` index in slices of 250 at a time. * `/search/{param}` - Returns search results for `param`. * `/error` - This route will trigger an error. * `/delete` - This route will delete all the data in the `games` index. * `/delete/{id}` - This route will delete a document with the given id from the `games` index. * `/update/` - This route will update the `modified` field on some docs in the `games` index. * `/doc/{id}` - This route will return a document with a given ID from Elasticsearch. # Data Source Data is based on a DB dump from February 25, 2020 of [TheGamesDB](https://thegamesdb.net/) game data: https://cdn.thegamesdb.net/json/database-latest.json elastic-elasticsearch-ruby-c38be0c/examples/apm/config.ru000066400000000000000000000002401462737751600236440ustar00rootroot00000000000000require 'elastic-apm' require_relative './elastic_sinatra_app.rb' ElasticAPM.start(app: ElasticSinatraApp) run ElasticSinatraApp at_exit { ElasticAPM.stop } elastic-elasticsearch-ruby-c38be0c/examples/apm/config/000077500000000000000000000000001462737751600233005ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/examples/apm/config/elastic_apm.yml000066400000000000000000000006071462737751600263070ustar00rootroot00000000000000# Set service name - allowed characters: a-z, A-Z, 0-9, -, _ and space # Defaults to the name of your Rack app's class. service_name: 'ruby-client-apm' # Use if APM Server requires a token # secret_token: '' # Set custom APM Server URL (default: http://localhost:8200) # In this example, we're using the URL from the docker-compose apm-server instance server_url: 'http://apm-server:8200' elastic-elasticsearch-ruby-c38be0c/examples/apm/docker-compose.yml000066400000000000000000000051411462737751600254710ustar00rootroot00000000000000version: '2.2' services: apm-server: image: docker.elastic.co/apm/apm-server:7.6.2 depends_on: elasticsearch: condition: service_healthy kibana: condition: service_healthy cap_add: ["CHOWN", "DAC_OVERRIDE", "SETGID", "SETUID"] cap_drop: ["ALL"] ports: - 8200:8200 networks: - elastic command: > apm-server -e -E apm-server.rum.enabled=true -E setup.kibana.host=kibana:5601 -E setup.template.settings.index.number_of_replicas=0 -E apm-server.kibana.enabled=true -E apm-server.kibana.host=kibana:5601 -E output.elasticsearch.hosts=["elasticsearch:9200"] healthcheck: interval: 30s retries: 12 test: curl --write-out 'HTTP %{http_code}' --fail --silent --output /dev/null http://localhost:8200/ elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:7.6.2 environment: - bootstrap.memory_lock=true - cluster.name=docker-cluster - cluster.routing.allocation.disk.threshold_enabled=false - discovery.type=single-node - ES_JAVA_OPTS=-XX:UseAVX=2 -Xms1g -Xmx1g ulimits: memlock: hard: -1 soft: -1 volumes: - esdata:/usr/share/elasticsearch/data ports: - 9200:9200 networks: - elastic healthcheck: interval: 30s retries: 10 test: curl -s http://localhost:9200/_cluster/health | grep -vq '"status":"red"' kibana: image: docker.elastic.co/kibana/kibana:7.6.2 depends_on: elasticsearch: condition: service_healthy environment: ELASTICSEARCH_URL: http://elasticsearch:9200 ELASTICSEARCH_HOSTS: http://elasticsearch:9200 ports: - 5601:5601 networks: - elastic healthcheck: interval: 30s retries: 20 test: curl --write-out 'HTTP %{http_code}' --fail --silent --output /dev/null http://localhost:5601/api/status ruby_app: container_name: ruby_app build: dockerfile: ${PWD}/dockerfiles/ruby/Dockerfile context: ${PWD} depends_on: - apm-server environment: ELASTICSEARCH_HOSTS: http://elasticsearch:9200 ports: - 9292:9292 networks: - elastic healthcheck: interval: 30s retries: 20 test: curl --write-out 'HTTP %{http_code}' --fail --silent --output /dev/null http://localhost:9292/ pinger: container_name: pinger build: dockerfile: ${PWD}/dockerfiles/pinger/Dockerfile context: ${PWD} depends_on: - ruby_app networks: - elastic volumes: esdata: driver: local networks: elastic: driver: bridge elastic-elasticsearch-ruby-c38be0c/examples/apm/dockerfiles/000077500000000000000000000000001462737751600243255ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/examples/apm/dockerfiles/pinger/000077500000000000000000000000001462737751600256115ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/examples/apm/dockerfiles/pinger/Dockerfile000066400000000000000000000001131462737751600275760ustar00rootroot00000000000000From ruby:2.7 WORKDIR /usr/src/app COPY ./pinger.rb . CMD ruby pinger.rbelastic-elasticsearch-ruby-c38be0c/examples/apm/dockerfiles/ruby/000077500000000000000000000000001462737751600253065ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/examples/apm/dockerfiles/ruby/Dockerfile000066400000000000000000000002771462737751600273060ustar00rootroot00000000000000From ruby:2.7 RUN bundle config --global frozen 1 WORKDIR /usr/src/app COPY . . RUN bundle install EXPOSE 9292 CMD RACK_ENV=production bundle exec rackup -p 9292 --host 0.0.0.0 config.ruelastic-elasticsearch-ruby-c38be0c/examples/apm/elastic_sinatra_app.rb000066400000000000000000000061301462737751600263650ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'sinatra' require 'json' require 'elasticsearch' require_relative './games_data.rb' class ElasticSinatraApp < Sinatra::Base use ElasticAPM::Middleware before do @client = Elasticsearch::Client.new( hosts: ENV['ELASTICSEARCH_HOSTS'] || 'localhost:9200' ) end get '/' do response = @client.cluster.health json_response(response) end get '/ingest' do unless @client.indices.exists(index: 'games') @client.indices.create(index: 'games') end ElasticAPMExample::GAMES.each_slice(250) do |slice| @client.bulk( body: slice.map do |game| { index: { _index: 'games', data: game } } end ) end json_response(status: 'ok') end get '/search/:query' do query = sanitize(params[:query]) response = search_elasticsearch(query) json_response(response['hits']['hits']) end get '/delete' do response = @client.delete_by_query( index: 'games', body: { query: { match_all: {} } } ) json_response(response) end get '/delete/:id' do id = sanitize(params[:id]) begin response = @client.delete(index: 'games', id: id) json_response(response) rescue Elasticsearch::Transport::Transport::Errors::NotFound => e json_response(e, 404) end end get '/update' do response = [] docs = search_elasticsearch docs['hits']['hits'].each do |doc| response << @client.update( index: 'games', id: doc['_id'], body: { doc: { modified: DateTime.now } } ) end json_response(response) end get '/error' do begin @client.delete(index: 'games', id: 'somerandomid') rescue Elasticsearch::Transport::Transport::Errors::NotFound => e json_response(e, 404) end end get '/doc/:id' do response = @client.get(index: 'games', id: sanitize(params[:id])) json_response(response) end private def json_response(response, code = 200) [ code, { 'Content-Type' => 'application/json' }, [response.to_json] ] end def sanitize(params) Rack::Utils.escape_html(params) end def search_elasticsearch(query = '') @client.search( index: 'games', body: { query: { multi_match: { query: query } } } ) end end elastic-elasticsearch-ruby-c38be0c/examples/apm/games_data.rb000066400000000000000000040207201462737751600244520ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # frozen_string_literal: true module ElasticAPMExample GAMES = [ { 'id' => 1, 'game_title' => 'Halo: Combat Evolved', 'release_date' => '2003-09-30', 'platform' => 1, 'overview' => "In Halo's twenty-sixth century setting, the player assumes the role of the Master Chief, a cybernetically enhanced super-soldier. The player is accompanied by Cortana, an artificial intelligence who occupies the Master Chief's neural interface. Players battle various aliens on foot and in vehicles as they attempt to uncover the secrets of the eponymous Halo, a ring-shaped artificial planet.", 'youtube' => 'dR3Hm8scbEw', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1389, 3423], 'genres' => [1, 8], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 2, 'game_title' => 'Crysis', 'release_date' => '2007-11-13', 'platform' => 1, 'overview' => "From the makers of Far Cry, Crysis offers FPS fans the best-looking, most highly-evolving gameplay, requiring the player to use adaptive tactics and total customization of weapons and armor to survive in dynamic, hostile environments including Zero-G. \r\n\r\nEarth, 2019. A team of US scientists makes a frightening discovery on an island in the South China Sea. All contact with the team is lost when the North Korean Government quickly seals off the area. The United States responds by dispatching an elite team of Delta Force Operators to recon the situation. As tension rises between the two nations, a massive alien ship reveals itself in the middle of the island. The ship generates an immense force sphere that freezes a vast portion of the island and drastically alters the global weather system. Now the US and North Korea must join forces to battle the alien menace. With hope rapidly fading, you must fight epic battles through tropical jungle, frozen landscapes, and finally into the heart of the alien ship itself for the ultimate Zero G showdown.", 'youtube' => 'i3vO01xQ-DM', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1970], 'genres' => [8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 4, 'game_title' => 'Star Fox 64', 'release_date' => '1997-06-30', 'platform' => 3, 'overview' => "The Lylat system has been invaded! Join Fox McCloud and his Star Fox team as they fight to save the galaxy from the clutches of the evil Andross. Travel to many different 3-D worlds. Battle the enemy in the air and on the ground and listen in as Fox McCloud interacts with a cast of characters.\r\n\r\nSee how it feels to feel what you see! The N64 Rumble Pak controller accessory instantly transmits all the bumps and blasts during the action. It’s a new jolt to your game play experience!\r\n\r\n* Four Players compete simultaneously in Vs. mode!\r\n* Game Pak memory saves the top 10 scores!\r\n* Outstanding cinema scenes tell the Star Fox saga!", 'youtube' => 'jsEcmfPwnHo', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [1, 8], 'publishers' => [3], 'alternates' => ['Lylat Wars (EU)', 'Lylat Wars'], 'uids' => nil, 'hashes' => nil }, { 'id' => 5, 'game_title' => 'Donkey Kong', 'release_date' => '1982-01-01', 'platform' => 7, 'overview' => "Can you save Mario's girl from the clutches of Donkey Kong? Donkey Kong has kidnapped Mario's girlfriend Pauline and taken her to the top of a construction site. It's up to you to help Mario save Pauline before time runs out. But it won't be easy. Donkey Kong will do everything in his power to stop you. He'll throw barrel bombs, flaming fireballs and anything else he can get his hands on. So if you're looking for action, don't monkey around. Get the original Donkey Kong from the Nintendo Arcade Classics Series!", 'youtube' => 'C_PrG8P5W8o', 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [6037], 'genres' => [1], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 6, 'game_title' => 'Tapper', 'release_date' => '1983-01-01', 'platform' => 23, 'overview' => "The Tapper game screen features four bars. Patrons arrive periodically at the end of the bar opposite the player and demand drinks. The player must draw and serve drinks to the patrons as they slowly advance towards the player. If any customers reach the player's end of the bar, they impatiently grab the player-as-bartender and toss him out the far end of the bar, costing the player a life.[6]\r\n\r\nThe player serves customers by filling a mug at one of the four taps. Once the mug is full, the player releases the tap which automatically slides the mug towards the advancing customer. Customers catch mugs that are slid towards them, as long as they are not already drinking a beer, or otherwise distracted. If a mug is not caught by a customer (whether the customer is already drinking or distracted, or if there is no customer), then it falls off the bar on the other end, resulting in a loss of a life for the player. If a customer does catch the mug, though, then he or she is pushed back some amount towards the opposite end of the screen. The goal is to push the customer completely off the screen, but if they are not then they will stay and consume their drink in place. When a customer finishes his drink, he slides the empty mug back towards the player, after which the customer resumes his advance on the player. The player must collect the empty mugs before they reach the end of the bar and fall to the ground, as a mug falling to the ground costs a life.\r\n\r\nPeriodically, customers will leave tips on the bar for the player. These tips can be left at any place on the bar. The tip will appear after a specific number of empty mugs are released by the customers, and will appear wherever the customer who releases the required mug is standing. For example, in all levels, the first tip is left by the customer who returns the second empty mug, and will be left beside wherever this customer is standing. By collecting the tip, the player earns extra points and initiates \"entertainment\" for that level (dancing girls on the wild-west level, cheerleaders on the sports level, etc.). While the entertainment is active, some fraction of the customers will be distracted and stop advancing towards the player, but they will also stop catching mugs.\r\n\r\nTo complete a level the player must clear the entire bar of customers. Once this is done, the player is presented with a short vignette in which the bartender draws a drink for himself, drinks it, then tosses the empty mug into the air with varying (usually humorous) results, such as kicking it and shattering it or having the mug fall atop his head and cover it.\r\n\r\nAs the game progresses, the customers appear more frequently, move faster along the bar, and are pushed back shorter distances when they catch their drinks. In addition, the maximum number of customers per bar gradually increases until every bar can have up to four customers at a time.\r\n\r\nIn between levels of different settings, the player is presented with a shell game-type round. In this segue, the player is presented with a single bar that has six cans of beer or root beer sitting on top of it. A masked villain shakes every can except one and then pounds on the bar, causing the cans to shuffle their positions. If any other shaken can is picked, it explodes in the bartender/soda jerk's face, after which the right can is revealed. If the player selects the unshaken can, the hero is shown smiling and a message reads \"This Bud's For You\" (on the Budweiser version) or \"This one's for you\" (on Root Beer Tapper), and the player is rewarded with extra points.\r\n\r\nThere are four settings for the game, each setting lasting for two to four levels. The settings of the game are:\r\n\r\n- A western bar with cowboys (2 levels)\r\n- A sports bar with athletes (3 levels)\r\n- A punk rock bar with punk rockers (4 levels)\r\n- A space bar with aliens (4 levels)\r\n\r\nAfter completing all the levels, 13 in all, the player starts at the first again, harder than the first time through, and with some minor variations.", 'youtube' => 'dqrRKStaN_4', 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [5280], 'genres' => [1], 'publishers' => [4], 'alternates' => ['Root Beer Tapper'], 'uids' => nil, 'hashes' => nil }, { 'id' => 9, 'game_title' => 'Halo 2', 'release_date' => '2007-05-31', 'platform' => 1, 'overview' => 'Halo 2 is the sequel to the highly successful and critically acclaimed Halo®: Combat Evolved. In Halo 2, the saga continues as Master Chief—a genetically enhanced super-soldier—is the only thing standing between the relentless Covenant and the destruction of all humankind.', 'youtube' => 'Zz6FNKawJBc', 'players' => 2, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1389], 'genres' => [1, 8], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 10, 'game_title' => 'Ace Combat 6: Fires of Liberation', 'release_date' => '2007-10-23', 'platform' => 15, 'overview' => "Throughout Ace Combat 6, the player must pilot a fighter jet or other aircraft to destroy foes both in the air and on the ground. As an arcade flight game, it simplifies flight controls and gives the player a large amount of bullets, missiles and other weapons, putting them up against a very large amount of enemy forces. In addition to missiles and a vulcan cannon, the player can equip special weapons such as heat-seeking missiles, bombs, rocket launchers, and others. The player can lock on to a number of foes, and assist different tactical squads by switching between their respective HUD readouts.\r\n\r\nThe game includes 4 default multiplayer modes: Battle Royale, Siege Battle, Team Battle, and Co-Op Battle. In Battle Royale, the basic Deathmatch game mode, up to sixteen players shoot each other down to earn the highest points at the time limit. In Team Battle, a basic Team Deathmatch game is created. Points are awarded based on the type of aircraft destroyed. A unique type of multiplayer game, Siege Battle is played with two teams, Attacking and Defending. The Attacking team attempts to destroy the target (usually heavily defended by flak) within the time limit. The Defending team tries to halt their attack. The co-op battle mode consists of two single-player missions without AI that can be played with up to three other players.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5804], 'genres' => [13], 'publishers' => [6], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 11, 'game_title' => 'Army of Two', 'release_date' => '2008-03-06', 'platform' => 15, 'overview' => "Focusing on cooperative strategies, Army of Two's main feature is the necessity to use coordinated teamwork to accomplish the game's goals. While the game is meant to be played with another human as a partner, a \"Partner Artificial Intelligence\" (PAI) is also included and programmed to follow the player's strategies. Dependence on a partner (whether human or PAI) is so pronounced that most objectives are impossible to complete without it.", 'youtube' => '', 'players' => 2, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [2582], 'genres' => [1, 8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 12, 'game_title' => "Assassin's Creed", 'release_date' => '2008-04-09', 'platform' => 1, 'overview' => "The game centers on the use of a machine named the \"Animus\", which allows the viewing of the protagonist's genetic memories of his ancestors.\r\n\r\nThrough this plot device, details emerge of a struggle between two factions, the Knights Templar and the Assassins (Hashshashin), over an artifact known as a \"Piece of Eden\" and the game primarily takes place during the Third Crusade in the Holy Land in 1191.", 'youtube' => 'cc-ClutaN_I', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9149], 'genres' => [1, 2, 12], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 13, 'game_title' => 'BioShock', 'release_date' => '2007-08-21', 'platform' => 1, 'overview' => 'Set in an alternate history 1960, the game places the player in the role of a plane crash survivor named Jack, who must explore the underwater city of Rapture, and survive attacks by the mutated beings and mechanical drones that populate it. The game incorporates elements found in role-playing and survival games, and is described by the developers and Levine as a "spiritual successor" to their previous titles in the System Shock series.', 'youtube' => 'CoYorK3E4aM', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4357], 'genres' => [1, 8], 'publishers' => [8], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 14, 'game_title' => 'Dead Space', 'release_date' => '2008-10-14', 'platform' => 1, 'overview' => 'The player takes on the role of an engineer named Isaac Clarke, who battles a polymorphic, virus-like, alien infestation which turns humans into grotesque alien monsters called "Necromorphs", on board a stricken interstellar mining ship named the USG Ishimura.', 'youtube' => 'aE2lPGsvjC4', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9428], 'genres' => [8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 15, 'game_title' => 'Devil May Cry', 'release_date' => '2001-10-16', 'platform' => 11, 'overview' => "Set in modern times on the fictional Mallet Island, the story centers on the characters Dante and Trish and their quest to confront the demon lord Mundus. The story is told primarily through a mixture of cutscenes, which use the game's engine and several pre-rendered full motion videos.", 'youtube' => 'zZIKeE199Tk', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => ['Devil may cry 1'], 'uids' => [{ 'uid' => 'SLUS-20216', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPM-74230', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPM-65038', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 16, 'game_title' => "Devil May Cry 3: Dante's Awakening", 'release_date' => '2005-03-01', 'platform' => 11, 'overview' => "Set in modern times in an enchanted tower named Temen-ni-gru, the story centers on the dysfunctional relationship between Dante and his brother Vergil. The events of the game take place just as Dante has opened up the Devil May Cry agency, and before Dante's demonic heritage has reached its full potential.", 'youtube' => 'Q9UiezHyR8o', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => nil, 'uids' => [{ 'uid' => 'SLUS-20964', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPM-65880', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLES-53038', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 17, 'game_title' => 'Devil May Cry 4', 'release_date' => '2008-02-05', 'platform' => 12, 'overview' => 'In the game, the player controls both Nero and Dante, and fights enemies in close combat using firearms, swords, and other weapons. The characters Lady and Trish from previous games in the series make appearances, along with new characters Nero, Kyrie, Credo, Gloria, and Agnus. The game is set after Devil May Cry but before Devil May Cry 2.', 'youtube' => 'Dp5fobWucds', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1436], 'genres' => [1, 4, 18], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 18, 'game_title' => 'Driver: Parallel Lines', 'release_date' => '2007-06-26', 'platform' => 1, 'overview' => 'Diverging from previous Driver games, Parallel Lines takes place in just one city, New York, instead of multiple cities, but in the middle of the story you change to different eras of the city - 1978 and 2006. Due to the underwhelming performance of Driv3r, particularly the often-derided on-foot sections, Parallel Lines returns to the formula used in earlier games in the series, focusing on driving, although shooting remains in the game.', 'youtube' => 'nw1j8zatcEc', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7109], 'genres' => [7], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 19, 'game_title' => 'Final Fantasy X-2', 'release_date' => '2003-11-18', 'platform' => 11, 'overview' => "The game's story follows the character Yuna from Final Fantasy X as she seeks to resolve political conflicts in the fictional world of Spira before it leads to war.\r\n\r\nThe story begins as Yuna, Rikku and Paine recover Yuna's stolen Garment Grid from the Leblanc Syndicate in the first of several encounters in which they vie for spheres. The game is punctuated by a narration of Yuna addressing Tidus, as though she is recounting the events of the game to him as they occur in a style reminiscent of Tidus' own narration in Final Fantasy X. Although Yuna's quest is to find clues that may lead her to Tidus, much of the storyline of the game follows the clash of the factions that have established themselves in the time since the coming of the Eternal Calm in Final Fantasy X, and the uncovering of hidden legacies from Spira's ancient history. A significant portion of the game's events are unnecessary for the completion of the main storyline, but much of the depth of the story—including characterization and background details—are featured in the optional content, which generally follows how each part of Spira is healing in the time since the passing of Sin.", 'youtube' => 'f_T4TF0Id6U', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2808], 'genres' => [4], 'publishers' => [12, 78], 'alternates' => ['ファイナルファンタジーX-2 Fainaru FantajÄ« Ten TsÅ«', 'Final Fantasy 10-2', 'FFX-2'], 'uids' => [{ 'uid' => 'SLUS-20672', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPS-25250', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPM-66125', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 20, 'game_title' => 'Final Fantasy X', 'release_date' => '2001-12-17', 'platform' => 11, 'overview' => "There are seven main playable characters in Final Fantasy X. Tidus is a cheerful young teenager and the star blitzball player for the Zanarkand Abes. He has long resented his father, a renowned blitzball player who disappeared during Tidus's youth. Yuna is the daughter of the High Summoner Braska, who defeated Sin to bring about the Calm, a time of peace. Yuna embarks on a pilgrimage to obtain the final aeon and defeat Sin. Kimahri Ronso is a young warrior of the Ronso tribe who watched over Yuna during her childhood. Wakka is a blitzball player and devout follower of the Yevon order. Lulu is a stoic and self-possessed, but well-meaning Black Mage. Auron is a taciturn former warrior monk, and finally Rikku is a perky Al Bhed girl with extensive knowledge of machinery. The primary antagonists of the game are Maester Seymour Guado and the other maesters of the Yevon religion, while the enormous whale-like monster Sin serves as the primary source of conflict.", 'youtube' => 'tJvGJsXT8Ac', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8096], 'genres' => [4], 'publishers' => [11], 'alternates' => ['Final Fantasy 10', 'FFX'], 'uids' => [{ 'uid' => 'SLUS-20312', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPM-66124', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPM-66677', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPS-25050', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPS-25088', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SCES-50491', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 21, 'game_title' => 'Final Fantasy XIII', 'release_date' => '2010-03-09', 'platform' => 12, 'overview' => 'Final Fantasy XIII is a console role-playing video game developed and published by Square Enix for the PlayStation 3 and Xbox 360. Released in 2009 in Japan and North America and PAL regions in March 2010, it is the thirteenth major installment in the Final Fantasy series. The game includes fast-paced combat, a new system for the series for determining which abilities are developed for the characters called "Crystarium", and a customizable "Paradigm" system to control which abilities are used by the characters. Final Fantasy XIII includes elements from the previous games in the series, such as summoned monsters, chocobos, and airships.', 'youtube' => 'hDjkGUM7skk', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2808], 'genres' => [4], 'publishers' => [12], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 22, 'game_title' => 'Left 4 Dead', 'release_date' => '2008-11-17', 'platform' => 1, 'overview' => "From Valve (the creators of Counter-Strike, Half-Life and more) comes Left 4 Dead, a co-op action horror game for the PC and Xbox 360 that casts up to four players in an epic struggle for survival against swarming zombie hordes and terrifying mutant monsters.\r\n\r\nSet in the immediate aftermath of the zombie apocalypse, L4D's survival co-op mode lets you blast a path through the infected in four unique “movies,†guiding your survivors across the rooftops of an abandoned metropolis, through rural ghost towns and pitch-black forests in your quest to escape a devastated Ground Zero crawling with infected enemies. Each \"movie\" is comprised of five large maps, and can be played by one to four human players, with an emphasis on team-based strategy and objectives.\r\n\r\nNew technology dubbed \"the AI Director\" is used to generate a unique gameplay experience every time you play. The Director tailors the frequency and ferocity of the zombie attacks to your performance, putting you in the middle of a fast-paced, but not overwhelming, Hollywood horror movie.\r\n\r\nAddictive single player, co-op, and multiplayer action gameplay from the makers of Counter-Strike and Half-Life\r\nVersus Mode lets you compete four-on-four with friends, playing as a human trying to get rescued, or as a zombie boss monster that will stop at nothing to destroy them.\r\nSee how long you and your friends can hold out against the infected horde in the new Survival Mode\r\nAn advanced AI director dynamically creates intense and unique experiences every time the game is played\r\n20 maps, 10 weapons and unlimited possibilities in four sprawling \"movies\"\r\nMatchmaking, stats, rankings, and awards system drive collaborative play\r\nDesigner's Commentary allows gamers to go \"behind the scenes\" of the game\r\nPowered by Source and Steam", 'youtube' => '4_Xz9aJ9yGY?hd=1', 'players' => 4, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [9289], 'genres' => [8, 18], 'publishers' => [13], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 23, 'game_title' => 'Gears of War', 'release_date' => '2006-11-07', 'platform' => 1, 'overview' => 'The game focuses on the troops of Delta Squad as they fight to save the human inhabitants of the fictional planet Sera from a relentless subterranean enemy known as the Locust Horde. The player assumes the role of Marcus Fenix, a former prisoner and war-hardened soldier. The game is based on the use of cover and strategic fire for the player to advance through the scenarios; a second player can play cooperatively through the main campaign to assist. The game also features several online multiplayer game modes for up to eight players.', 'youtube' => '_D9r8Xm2aDw', 'players' => 2, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [2833], 'genres' => [8], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 24, 'game_title' => 'Gears of War 2', 'release_date' => '2008-11-07', 'platform' => 15, 'overview' => 'In Gears of War 2, The COG continues its fight against the Locust horde, who are attempting to sink all of the cities on the planet Sera by using a big riftworm to eat the ground beneath them. Sergeant Marcus Fenix leads Delta Squad into the depths of the planet to try to stop the worm from eating but instead they discover the true intent of the Locust actions.', 'youtube' => '6yMwniG9NuM', 'players' => 2, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [2834], 'genres' => [1, 8], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 25, 'game_title' => 'God Hand', 'release_date' => '2006-10-10', 'platform' => 11, 'overview' => "THERE AIN'T NO JUSTICE IN THE\r\nWILD, WEIRD WEST. JUST YOU.\r\nThings can't get any worse after demonic thugs cut your arm off, right? Dead wrong, partner. The lady you saved from them has only gone and given you the legendary GOD HAND as a replacement - the ultimate hand-to-hand weapon. Every undead outlaw in a Stetson, rootin' tootin' demon and circus freak in the prairies is going to want to fight you for it. Welcome to the town of Asskickin... have a nice stay y'all.\r\n\r\nBIG HAND - Explosive martial arts and hand-to-hand action get in your face and ugly. No bullets, lots of bruised knuckles.\r\n\r\nSLAP STICKS - Totally customisable fight system. Pull off the most outrageous combo moves ever with awesome God Hand powers - punch your opponent into orbit!\r\n\r\nFIGHTING FORM - Pugilistic adventure from the makers of RESIDENT EVIL, DEVIL MAY CRY and VIEWTIFUL JOE!", 'youtube' => 'xTqzeMSBYFA', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1705], 'genres' => [1, 10], 'publishers' => [9], 'alternates' => nil, 'uids' => [{ 'uid' => 'SLPM-66550', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLUS-21503', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPM-74241', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 26, 'game_title' => 'God of War', 'release_date' => '2005-03-22', 'platform' => 11, 'overview' => 'This action/adventure/combat game makes powerful use of the darkly imaginative world of Ancient Greek mythology, where the realms of the mortal and the divine collide in a pervasive atmosphere of brute force and violence. Playing as Kratos, throughout the game players will wield double blades bound to his body by long chains, weapons symbolic of this vicious world to which he is bound and the fate from which he seeks to escape. Featuring an hour of cinematic sequences and a deep combat system incorporating context-sensitive actions and an extensive range of combos, GOD OF WAR takes players through various environments that will have them fighting fierce enemies, swinging on ropes, scaling mountain cliffs, swimming through rivers and sliding down zip lines. The result is a unique and thrilling adventure through Greek mythology.', 'youtube' => 'https://www.youtube.com/watch?v=0Qxkd5EHguo', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7435], 'genres' => [1, 15], 'publishers' => [14], 'alternates' => ['GOD OF WAR'], 'uids' => [{ 'uid' => 'SLPM-67010', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPM-67011', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPM-67012', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SCES-53133', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 27, 'game_title' => 'Golden Axe: Beast Rider', 'release_date' => '2008-10-14', 'platform' => 15, 'overview' => 'Beast Rider is the first Golden Axe game in 3D as opposed to side scrolling hack and slash. While this is a major shift in game style from the previous games, Beast Rider maintains many of the elements from the originals such as magic and riding beasts, as well as sending the player on a quest to defeat Death Adder.', 'youtube' => 'Bk-9qXCbaBk', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7544], 'genres' => [1, 2], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 28, 'game_title' => 'GRID', 'release_date' => '2008-06-03', 'platform' => 1, 'overview' => 'The game begins with the player accepting jobs to drive for other teams to earn money, and once the player gains enough capital they can purchase their own vehicles and drive independently, as well as continuing to drive for other teams should they choose to. GRID features a unique gameplay mechanic known as Flashback which allows the player to rewind gameplay by up to ten seconds and resume from their chosen point. This is a limited-use feature, determined by the difficulty setting.', 'youtube' => 'p_i1HLLo_j0', 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1726], 'genres' => [7], 'publishers' => [16], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 29, 'game_title' => 'Grand Theft Auto IV', 'release_date' => '2008-12-02', 'platform' => 1, 'overview' => "For Niko Bellic, fresh off the boat from Europe, it is the hope he can escape his past. For his cousin, Roman, it is the vision that together they can find fortune in Liberty City, gateway to the land of opportunity. As they slip into debt and are dragged into a criminal underworld by a series of shysters, thieves and sociopaths, they discover that the reality is very different from the dream in a city that worships money and status, and is heaven for those who have them and a living nightmare for those who don't.", 'youtube' => 'FS2Aw6vxUPY?hd=1', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7279], 'genres' => [1, 2, 8], 'publishers' => [17], 'alternates' => ['GTA 4'], 'uids' => nil, 'hashes' => nil }, { 'id' => 30, 'game_title' => 'Guild Wars', 'release_date' => '2005-04-26', 'platform' => 1, 'overview' => "Guild Wars is a a massively multi-player online role-playing game (MMORPG) with an emphasis on tactical combat. In single player, multiplayer and guild-based missions, players will explore a fantasy world while pursuing professions and gaining skills that help them develop and advance their unique character.\r\n\r\nKey members of the creative teams behind the hit games Warcraft, StarCraft, and Diablo, as well as Battle.net founded Guild Wars, the first title from Seattle-based ArenaNet. Guild Wars offers cooperative group combat, single player missions, and large head-to-head guild battles. While each combat experience is different, achievements will be permanent so that the character grows and progresses over time. Unique items, special abilities, and a wide variety of skills add meaningful value for the player and for his or her comrades. Missions are not scripted adventures, but are tactical battlegrounds where victory or loss is determined by skill and teamwork.", 'youtube' => 'H2foBd3NT_s', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [609], 'genres' => [2, 4, 14], 'publishers' => [18], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 31, 'game_title' => 'Heavenly Sword', 'release_date' => '2007-09-12', 'platform' => 12, 'overview' => "The gameplay of Heavenly Sword resembles a martial arts title focused on melee combat while featuring opportunities for ranged attacks. The main character, Nariko, uses a weapon called the \"Heavenly Sword\" which changes into one of three forms depending on what attack stance the player uses as part of a unique fighting style. Speed Stance, the default, provides an even balance between damage and speed, where the sword takes the form of two separate blades. Range Stance allows fast, long-ranging, but weaker attacks, with the sword resembling two blades, chained together. Power Stance is the most powerful, but slowest style, where attacks are made with the Sword in the shape of one large, two-handed blade.\r\nFor exploration and certain battles, the game also makes use of \"Quick Time Events\" (QTE). During a QTE, a symbol for a certain button or for an action such as moving the analog stick to the right or left appears on screen and the player must match what is shown to successfully complete the scene.", 'youtube' => 'djY3_E2Z41M', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6032], 'genres' => [1, 2, 10], 'publishers' => [19], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 34, 'game_title' => 'Killer7', 'release_date' => '2005-07-07', 'platform' => 2, 'overview' => "Step into the mind of an assassin!\r\n\r\nKiller7 is a hard hitting surreal action adventure game starring Harman Smith - a mysterious assassin who can harness the unique power of his seven personalities. Working together these personalities are the Killer7.\r\n\r\nTheir mission: stop the evil Kun Lan and his minions known as the Heaven Smile from taking over the world.", 'youtube' => 'ln7MBdwH3SM', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3577], 'genres' => [1, 2], 'publishers' => [9], 'alternates' => ['Killer 7'], 'uids' => nil, 'hashes' => nil }, { 'id' => 35, 'game_title' => 'Killzone', 'release_date' => '2004-11-02', 'platform' => 11, 'overview' => "The game is set in an era of space colonization where the Helghast Empire has recovered from its defeat in the First Helghan War and launched a blitzkrieg against the outer Interplanetary Strategic Alliance (I.S.A.) colony planet Vekta. Vekta's orbital Strategic Defense (S.D.) platforms failed during the initial assault, allowing the Helghast to land swarms of soldiers onto the surface and making it all the more difficult for the outnumbered I.S.A. forces.\r\n\r\nIn the game, the Helghast are a faction of human descendants who colonized the planet Helghan many generations ago. The planet's harsh environment forced the Helghast to adapt and mutate so much that they can no longer be considered human. They are stronger, faster and more resilient than their human cousins, and possess a burning hatred for humanity. Except for a small number of half-breed Helghast and trained troopers, they require a gas mask and air processing tank that creates air similar to that found on the planet Helghan.\r\n\r\nThe player takes control of I.S.A. Captain Jan Templar, who is fighting off the Helghast invasion. Templar and his squad are called back to the base for reassignment, and are promptly sent to find the I.S.A. operative Gregor Hakha and the information in his possession. During the course of the game, the player also takes control of several other characters, such as Shadow Marshal Luger (a female special operations assassin), a heavy weapons specialist Staff Sergeant Rico Velasquez (a Helghast-hating soldier with an itchy trigger finger), and Colonel Hakha, a half-Helghast, half-Human spy.\r\n\r\nAs the game progresses the player discovers that General Stuart Adams, a high ranking ISA officer, is a traitor and a servant of Joseph Lente (the commanding General of The Third Helghast Special Forces Army) and was responsible for sabotaging the SD platforms, rendering them unable to defend against the Helghast. The Earth Defense Fleet (EDF) go to assist the Vektan Army, however Adams kills General Voughton and receives his security key, allowing him to reboot the platforms, and prepare an ambush for the EDF relief force.\r\n\r\nJan and the others confront Lente, only to find out that Hakha was a commander in chief for him. Lente says that Hakha's family was ashamed to even be related to him, except his brother who talked of his heroism. Because of this, Lente had Hakha's brother shot down. With anger in his eyes, Hakha shoots Lente dead.\r\n\r\nThe team fly to the central SD platform and confront Adams, who is wounded by Templar. The platform begins to break up and Adams is killed by falling debris while trying to escape. Finally, the team restore the SD platform, allowing the EDF fleet to fight off the Helghast.", 'youtube' => 'wYDXFgptR-Q', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3657], 'genres' => [8], 'publishers' => [20], 'alternates' => nil, 'uids' => [{ 'uid' => 'SCUS-97402', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPM-66151', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 36, 'game_title' => 'Killzone 2', 'release_date' => '2009-02-27', 'platform' => 12, 'overview' => "Killzone 2 is the third game in the Killzone franchise and continues the story two years after the events of the first two games. The game takes place on Helghan, the home-world of the Helghast who assaulted the Interplanetary Strategic Alliance's colony on Vekta. The ISA retaliates on the Helghan's own ground with the aim to secure the Helghast leader, Emperor Visari, and bring the Helghast war machine to a halt. Assuming the role of Sergeant Tomas \"Sev\" Sevchenko, a battle-hardened veteran and a member of the special forces unit known as the Legion. Under his command, players lead a group of highly trained soldiers on a mission to take out the Helghast threat.\r\n\r\nThe gameplay consists of what the developers describe as Hollywood Realism, focusing on scripted, cinematic gameplay. The game is played entirely from the first-person perspective, except for the portions with vehicular combat with a tank and an exoskeleton. A large portion is dedicated to seeking cover and peeking from behind objects to open fire. Next to the single-player campaign, there is squad-based multiplayer called Warzone with five different kinds of missions (Assassination, Search & Retrieve, Search & Destroy, Bodycount and Capture & Hold) based on seven kinds of classes. There is support for up to 32 players, with the addition of bots to fill the remaining spots.", 'youtube' => 'b-4HNmuEAKg', 'players' => 16, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3657], 'genres' => [1, 8], 'publishers' => [21], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 37, 'game_title' => 'Lair', 'release_date' => '2007-08-30', 'platform' => 12, 'overview' => 'In a world ravaged by endless conflict and natural disaster, a call for peace turns into a bloodbath of betrayal and deceit. Playing as a warrior riding a voracious dragon trained for deadly aerial and ground combat, and capable of scorching, clawing and smashing thousands of enemies, gamers must defeat countless armies to save a civilization. Together, the gamer and the beast will attempt to change the destiny of a world on the brink of extinction.', 'youtube' => '467zs7pt0wE', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2976], 'genres' => [1], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 38, 'game_title' => 'The Last Remnant', 'release_date' => '2008-11-20', 'platform' => 15, 'overview' => "The Last Remnant is set in a fictional world featuring a number of distinct humanoid races: the Mitras, human in appearance, the Yamas, strong fish-like people, the Qsitis, small reptilians, and the Sovanis, feline people with four arms. The world itself is broken up into multiple city-states, each with their own unique culture. The story of the game revolves around \"Remnants\", mysterious and coveted ancient artifacts of varying shapes and sizes which possess magic powers and have been the cause of several wars throughout the game's history. Each Remnant is \"bound\" to a specific person, who is the only one who can then use their power; powerful Remnants that remain unbound for too long have the potential to cause a \"collapse\" and spawn monsters. As Remnants come in varying forms, all cities throughout the world have at least one that their ruler is bound to that assist to govern and bring peace to their assigned realm", 'youtube' => 'XUkAsfgP-XQ', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2808], 'genres' => nil, 'publishers' => [12], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 39, 'game_title' => 'Lost Odyssey', 'release_date' => '2008-02-12', 'platform' => 15, 'overview' => "Lost Odyssey is set in a world in which a \"Magic-Industrial Revolution\" is taking place. While magic energy existed in all living creatures beforehand, it suddenly became far more powerful thirty years before the beginning of the game. Because of this, it has affected society greatly, with devices called \"Magic Engines\" harnessing this power for lighting, automobiles, communication, and robots, among other uses. While previously only a select few could wield magic, many magicians gained the ability. However, such progress has also caused two nations to develop new and more powerful weapons of mass destruction. The kingdom of Gohtza and the Republic of Uhra (which recently converted from a monarchy). Uhra is building Grand Staff, a gigantic magic engine, while the heavily industrialized Gohtza actively pursues magic research of their own. A third nation, the Free Ocean State of Numara, remains isolated and neutral, though it is falling into disarray due to a general attempting to stage a coup d'etat. Uhra, at war with Khent, a nation of beastmen, sends its forces to the Highlands of Wohl for a decisive battle at the start of the game.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5624, 10_184], 'genres' => [4], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 40, 'game_title' => 'Super Mario Galaxy', 'release_date' => '2007-11-12', 'platform' => 9, 'overview' => "Experience a gravity-defying adventure!\r\n\r\nBecome Mario as he traverses gravity-bending galaxies, traveling in and out of gravitational fields by blasting from planet to planet. Players experience dizzying perspective shifts as they run upside down through wild alien worlds that need to be seen to be believed. Whether you're surfing on a ray across an ocean in the clouds, rolling on a ball through a treacherous garden, or floating in a bubble over a poisonous swamp, there's no limit to the cosmic challenges you'll encounter!\r\n\r\n* Shake it! Controlling Mario is as simple as can be with the Wii Remote and Nunchuk. Move Mario with the Control Stick and shake the Wii Remote to perform a spin move or cue Ring Stars that launch you to and from planetary objects. You can even point at bits of stardust to collect them or latch onto Beam Stars to blaze a magnetic trail through the heavens.\r\n\r\n* Mario can run, tiptoe, jump, triple-jump, backflip, and long-jump, but what he'll do most is spin. By shaking the Wii Remote, players make Mario spin around with fists outstretched, allowing him to pummel enemies and cue Star Rings that launch him from planet to planet.\r\n\r\n* He can also find plenty of power-ups: A Bee Mushroom turns him into Bee Mario, allowing him to fly for short periods of time and cling to honeycombs. A Boo Mushroom turns him into Boo Mario, allowing him to float and turn invisible to pass through mesh gates.\r\n\r\n* He'll constantly collect bits of stardust. These can be fired at enemies using the B Button. A second player can even take on this role, using a second Wii Remote to stall enemies, fire stardust, or even sweep aside projectiles.", 'youtube' => 'XgVItfrZvOU', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [1, 2, 15], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 41, 'game_title' => 'Super Mario Kart', 'release_date' => '1992-09-01', 'platform' => 6, 'overview' => "The Super Mario GoKart Park is open for tons of racing fun! Hit the track with Mario, Luigi, Yoshi and the Princess. Get tough and lock fenders with Donkey Kong, Jr. and Bowser. Even Toad and Koopa Troopa will mix it up in an all-out quest for the Gold Cup! Race head-to-head with a friend or challenge the computer in great, split-screen, Mode 7 graphics.\r\n\r\nFeel like a bit less speed and a lot more strategy? Take a crack at the Battle Mode! In four different maze-like courses you’ll use Koopa Shells, Banana Peels, Super Stars and other wacky weapons to burst your opponent's target balloons and triumph!\r\n\r\n* 2 games in 1 - Mario Grand Prix and Battle Mode\r\n* 8 Familiar Characters\r\n* 20 Different Tracks\r\n* 3 Different Skill Levels\r\n* Battery-backed memory saves your best times!", 'youtube' => 'vRg-89M665c', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [7], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 42, 'game_title' => 'Mario Party', 'release_date' => '1999-02-08', 'platform' => 3, 'overview' => "Every game in the main series has a standard Party Mode in which up to four players play through a board, trying to collect as many stars as possible. In every turn, each player rolls a die and progresses on the board, which usually has branching paths. Coins are primarily earned by performing well in a minigame played at the end of each turn. On most boards, players earn stars by reaching a star space and purchasing a star for a certain amount of coins. The star space appears randomly on one of several pre-determined locations and moves every time a star is purchased, usually occupying a blue space.\r\nEvery Mario Party contains at least 50 to almost 110 minigames with a few different types. Four-player games are a free-for-all in which players compete individually. In 2-on-2 and 1-on-3 minigames, players compete as two groups, cooperating to win, even though they are still competing individually in the main game. Some minigames in Mario Party are 4-player co-op, even though it doesn't say it. In most situations, winners earn ten coins each.", 'youtube' => 'sScj7MwjHBs', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3923], 'genres' => [1, 2, 6, 11], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 43, 'game_title' => 'Metal Gear Acid', 'release_date' => '2005-03-24', 'platform' => 13, 'overview' => "The Metal Gear series comes to the PSP offering a new gameplay system and storyline. In Metal Gear Acid, you'll take on the role of Solid Snake, a top-secret agent who's an expert at infiltration. It's up to you to make calculated decisions to plan out your strategy and accomplish missions in a turn-based style of game. Strategic battle cards give you different abilities and stealth tactics that help you achieve mission objectives. Experience a deeper kind of tactical espionage in the palm of your hand.", 'youtube' => 'KR2pfqpj7vo', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4619], 'genres' => [6, 16], 'publishers' => [23], 'alternates' => ['Metal Gear Ac!d'], 'uids' => nil, 'hashes' => nil }, { 'id' => 44, 'game_title' => 'Metal Gear Solid 3: Snake Eater', 'release_date' => '2004-11-17', 'platform' => 11, 'overview' => "Set in the 60s and using the Cold War as its inspiration, Metal Gear Solid 3: Snake Eater forces the player to adopt a number of new skills to survive in Snake's new jungle environment. Danger lurks everywhere as Snake explores the beautifully-realised forests, encampments and rivers, with guards patrolling key routes, dangerous animals to contend with, and the uneven terrain and noisy foliage making the silent approaches the Metal Gear hero is famed for virtually impossible.\r\n\r\n Gameplay set in Cold War era 1960's\r\n Camoflage System: Use different combinations of uniform and face paints to blend into your environment\r\n Food: Capture and eat animals & plants to sustain Snake's health and abilities\r\n Close Quarters Combat (CQC): Take on enemies up close and personal with knives and martial arts techniques for silent kills\r\n Exclusive content for the PAL version includes:\r\n Duel Mode - Battle through the game's Boss Fights independently\r\n Demo Theatre - Watch all the cut scenes in sequence\r\n European Extreme difficulty level\r\n 2 New Levels in Snake Vs Monkey Mode\r\n New Face Paint and Camoflage Designs not available in US or Japanese versions", 'youtube' => 'hXUono66wxI', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4765], 'genres' => [1, 2, 16], 'publishers' => [23], 'alternates' => nil, 'uids' => [{ 'uid' => 'SLUS-20915', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPM-65790', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPM-66794', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLES-82013', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 45, 'game_title' => 'Metal Gear Solid 4: Guns of the Patriots', 'release_date' => '2008-06-12', 'platform' => 12, 'overview' => 'Metal Gear Solid 4 is set in 2014, five years after the Big Shell incident and nine years after Shadow Moses incident. The world economy relies on continuous war, fought by PMCs, which outnumber government military forces. PMC soldiers are outfitted with nanomachines to enhance their abilities and control the stress on the battlefield. The control network created through these nanomachines is called Sons of the Patriots (SOP), and Liquid Ocelot is preparing to hijack the system. Snake accepts a request from Roy Campbell to terminate Liquid, with Otacon and Sunny providing mission support from the Nomad aircraft.', 'youtube' => 'pjYE7GkZg-A', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4760], 'genres' => [1, 2], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 46, 'game_title' => "Mirror's Edge", 'release_date' => '2008-11-11', 'platform' => 12, 'overview' => "Mirror's Edge introduces players to Faith, a \"runner\" in a world where communication channels are highly monitored and the movement of human traffic is closely watched. When Faith's sister gets framed for a murder she did not commit, Faith finds herself on the edge of the city, on the wrong side of the law. \r\n\r\n Mirror's Edge delivers players straight into the shoes of this modern day heroine as she traverses the vertigo-inducing cityscape, engaging in intense combat, fast-paced chases and challenging puzzles. With a never-before-seen sense of movement and perspective, players are drawn into Faith's world.", 'youtube' => '2N1TJP1cxmo', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2576], 'genres' => [1, 2], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 47, 'game_title' => 'Need for Speed: ProStreet', 'release_date' => '2007-11-13', 'platform' => 1, 'overview' => 'The game begins where a former street racer known as Ryan Cooper enters a challenge day and wins it with a Nissan 240SX. Ryan is mocked by Ryo Watanabe, the Showdown King.', 'youtube' => '3YcFDXp4tD8', 'players' => nil, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [2563], 'genres' => [7], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 48, 'game_title' => 'NiGHTS into Dreams...', 'release_date' => '1996-08-31', 'platform' => 17, 'overview' => "Immerse yourself in an unparalleled 3D flying experience. NiGHTS truly delivers an amazing virtual world of dreams -- filled with unbelievable real-time effects, fantastic creatures and nightmarish monsters.\r\n\r\n* Master a showcase of Sega Saturn's Processing Power.\r\n* Face your worst nightmares in a stunning world of 3D gameplay.\r\n* Dozens of camera angles, never-seen-before effects and 3D positional sound.\r\n* Developed exclusively for Sega Saturn by the creators of \"Sonic the Hedgehog.\"", 'youtube' => 'IqMGYy5btJQ', 'players' => 1, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [7979], 'genres' => [1], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 49, 'game_title' => 'Ninja Gaiden II', 'release_date' => '2008-06-03', 'platform' => 15, 'overview' => 'In "Ninja Gaiden II," gamers must guide Ryu Hayabusa on a mission to avenge his clan and prevent the destruction of the human race. Armed with an assortment of ninja weaponry, players must help Ryu skillfully maneuver through a world fraught with peril. "Ninja Gaiden II" will feature an all-new gameplay engine, a new auto-health regeneration system, levels, adventures, enemies and thrilling combat with an extensive assortment of ninja weaponry, representing a true evolution of the highly popular franchise.', 'youtube' => 'uS-IhxhW4T8', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [8563], 'genres' => [1, 2], 'publishers' => [24], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 50, 'game_title' => 'Ninja Gaiden: Dragon Sword', 'release_date' => '2008-03-25', 'platform' => 8, 'overview' => "This action-adventure title is presented in a third person, pseudo-3D manner, meaning all the game-models are rendered in full 3D, but the world the player travels around in is pre-rendered. When played, the Nintendo DS is held sideways, as in Hotel Dusk: Room 215 and Brain Age: Train Your Brain in Minutes a Day!. The left screen shows the area map, while the right displays the main gameplay, when set for right-handed play, and reverse when set for left-handed play.\r\nSet six months after Ninja Gaiden, Ryu Hayabusa has rebuilt the Hayabusa Village. When fellow villager and kunoichi, Momiji, is kidnapped by the Black Spider Ninja Clan, he is forced to find her, while uncovering the secrets behind the mysterious Dark Dragonstones and their relation to the Dragon Lineage", 'youtube' => 'VbwuQDPwOWo', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8563], 'genres' => [1, 2], 'publishers' => [24], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 51, 'game_title' => 'Okami', 'release_date' => '2006-09-19', 'platform' => 11, 'overview' => "The game is set in Nippon based on Japanese classic history, and begins with a flashback to events 100 years prior to the game's present, and describes how Shiranui, a pure white wolf, and Nagi, a swordsman, together fought the eight-headed demon Orochi to save Kamiki Village and the maiden Nami, Nagi's beloved. Shiranui and Nagi are unable to defeat Orochi but manage to seal the demon away. In the game's present, Susano, a descendant of Nagi and self-proclaimed greatest warrior, breaks Orochi's seal due to the fact that he does not believe in the legend, and Orochi escapes and curses the lands, sapping the life from every living being. Sakuya, the wood sprite and guardian of Kamiki Village, calls forth Amaterasu, the sun goddess, known to the villagers as the reincarnation of the white wolf Shiranui, and pleads her to remove the curse that covers the land. Accompanied by the artist Issun (an inch-high Poncle), Amaterasu is able to restore the land to its former beauty. Throughout the journey, Amaterasu is hounded by Waka, a strange but powerful individual that seems to have the gift of foresight, and further teases Amaterasu and Issun to his own mysterious ends. Additionally, Amaterasu locates several Celestial Gods who have hidden in the constellations that bestow upon the goddess powers of the Celestial Brush to aid in her quest.", 'youtube' => 'K4trRdKm9CA', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1705], 'genres' => [1, 2], 'publishers' => [9], 'alternates' => nil, 'uids' => [{ 'uid' => 'SLPM-66375', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLUS-21115', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLES-54439', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 52, 'game_title' => 'Perfect Dark Zero', 'release_date' => '2005-11-22', 'platform' => 15, 'overview' => "The Xbox 360 prequel to Rare's Nintendo 64 hit, Perfect Dark. Players once again slip into the role of Joanna Dark and fight their way through a twisting sci-fi storyline. The franchise's staple multiplayer mode returns, this time with full online support.\r\n\r\nSet in the year 2020, three years before the original hit game Perfect Dark, Perfect Dark Zero features a gripping story, multiple game scenarios for endless replayability, a massive arsenal of weapons and combat-enabled vehicles. The sci-fi, first-person shooter features a fully interactive world, support for up to 50 players online via Xbox Live, breathtaking high-resolution graphics and spectacular special effects.", 'youtube' => '7lM5kZKnnzM', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [6991], 'genres' => [1, 8], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 53, 'game_title' => 'Prince of Persia', 'release_date' => '2008-12-09', 'platform' => 1, 'overview' => "Escape to experience the new fantasy world of ancient Persia. Masterful storytelling and sprawling environments deliver a brand new adventure that re-opens the Prince of Persia saga. Now you have the freedom to determine how the game evolves in this non-linear adventure. Players will decide how they unfold the storyline by choosing their path in the open-ended world. \r\n\r\n In this strange land, your rogue warrior must utilize all of his skills, along with a whole new combat system, to battle Ahriman’s corrupted lieutenants to heal the land from the dark Corruption and restore the light. Also, history;s greatest ally is revealed in the form of Elika, a dynamic AI companion who joins the Prince in his fight to save the world. Gifted with magical powers, she interacts with the player in combat, acrobatics and puzzle-solving, enabling the Prince to reach new heights of deadly high-flying artistry through special duo acrobatic moves or devastating fighting combo attacks.", 'youtube' => 'https://www.youtube.com/watch?v=WsPTD_2q5u8', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9149], 'genres' => [1, 2], 'publishers' => [7], 'alternates' => ['Prince of Persia (2008)'], 'uids' => nil, 'hashes' => nil }, { 'id' => 54, 'game_title' => "Tom Clancy's Rainbow Six: Vegas", 'release_date' => '2006-11-22', 'platform' => 1, 'overview' => "Rainbow Six Vegas changes the series with multiple new features, such as a new health system where the player regenerates health while not taking fire (it should be noted that the player may sometimes be killed instantly, without a chance to regenerate health; this usually happens from grenades, as well as taking close range fire from very powerful weapons, particularly to the head). \r\nIn the year 2010, Rainbow operatives Logan Keller (Andrew Pifko), Gabriel Nowak (Thomas Michael) and Kan Akahashi (Dennis Akayama) are on a mission in a Mexican border town, assisted by intelligence officer Joanna Torres (Athena Karkanis) and pilot Brody Lukin (Andrew Pifko). Their objective is to arrest Irena Morales (Amanda Martinez), a terrorist ringleader. As the team reaches its landing zone in a helicopter, Logan fast-ropes down first but is separated from his group.", 'youtube' => '9QeNEoEWxqg', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9150], 'genres' => [1, 8], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 55, 'game_title' => 'Command & Conquer: Red Alert 3', 'release_date' => '2008-10-28', 'platform' => 1, 'overview' => "The game is set in a parallel universe in which World War II never happened—in the original Red Alert, Albert Einstein travelled back in time and removed Hitler in the 1920s. After an Allied victory in Red Alert 2, the Soviet leaders travelled back in time and removed Albert Einstein in 1927, preventing the Allies from creating atomic weapons while the Soviet Union rose to power, battling the Allies in the 1950s. In this game, the Empire of the Rising Sun rises to power as a threat as well (an unintentional result of the Soviets' time travelling). All three factions are playable, with the main gameplay involving constructing a base, gathering resources, and training armies composed of land, sea, and airborne units to defeat other players. Each faction has a fully co-operative campaign, playable with an artificial intelligence or with another human player online. These campaigns follow a storyline, with specific mission objectives and unit restrictions applied.", 'youtube' => 'EfmpKq_6nCo', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2579], 'genres' => [6], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 56, 'game_title' => 'Resident Evil 4', 'release_date' => '2005-01-11', 'platform' => 2, 'overview' => "U.S. agent Leon Kennedy has been tasked to look into the abduction of the President's daughter and his investigation has led him to a mysterious location in Europe. As Leon encounters unimaginable horrors, he must find out what is behind the terror.", 'youtube' => '-fGYWQs2WgM', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1436], 'genres' => [1, 2, 18], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 57, 'game_title' => 'Resident Evil 5', 'release_date' => '2009-09-15', 'platform' => 1, 'overview' => 'Produced by series veteran Jun Takeuchi, this next-generation follow-up to the terrifying series introduces the theme of escape as its core survival instinct. As Chris Redfield (former S.T.A.R.S. member and now part of the BSAA unit), your life is in danger as you strive to complete your most dangerous mission yet in a sweltering desert colony where a new breed of evil has been unleashed. Swarms of marauding evil beings will charge at you when your pulse is racing at a heart-shattering pace. Environments will play a bigger factor than ever here, using the power of next-gen systems to create a world where terror might lurk in any alcove or shadow. Powerful lighting effects overwhelm the player with mirage movement and blinding brilliance, and even in the light of day, there is no safe haven in this Resident Evil.', 'youtube' => 'UX89tmpiuDA', 'players' => 2, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [1436], 'genres' => [1, 8], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 58, 'game_title' => 'Resident Evil Archives: Resident Evil Zero', 'release_date' => '2009-12-01', 'platform' => 9, 'overview' => "The game's storyline serves as a prequel to Resident Evil, covering Rebecca Chambers' ordeal a day prior. \r\n\r\nOn July 23, 1998, special police STARS Bravo team is sent in to investigate a series of grisly murders in the Arklay Mountains region outside of Raccoon City. On the way to the scene, Bravo's helicopter malfunctions and is forced to crash land in the forest. The team soon discover an overturned military police transport truck, along with the mutilated corpses of two officers. The team split up and Bravo team's field medic, Rebecca Chambers, finds a train stopped in the middle of the forest.\r\nRebecca soon discovers that the train, the Ecliptic Express, is infested with zombies.", 'youtube' => 's49FPBRsC7c', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1436], 'genres' => [1, 8, 18], 'publishers' => [9], 'alternates' => ['Resident Evil Archives: Resident Evil 0'], 'uids' => nil, 'hashes' => nil }, { 'id' => 59, 'game_title' => 'Ridge Racer 6', 'release_date' => '2005-11-17', 'platform' => 15, 'overview' => "Ridge Racer 6 is the sixth installment in the Ridge Racer series of racing games. It was released on Xbox 360 on 22 November 2005 in North America, 10 December 2005 in Japan, and 20 January 2006 in Europe.\r\n\r\n\r\nLike previous Ridge Racer titles, the focus of gameplay is on placing first out of 14 in numerous 3-lap races across several tracks and numerous cars. In most races, the player can earn up to three nitrous boosts by successfully drifting around corners without crashing, which can then be used to give the player a short burst of speed. Some races are labeled as \"no-nitrous,\" which prevent the player from earning any nitrous during the race, though the player can optionally enable nitrous. If the player wins using this option, the race is considered complete, but noted for breaking the no-nitrous rule. Some races are also Duels between the player and a boss opponent, who is usually equipped with a much better car than the player can select from.\r\n\r\nRidge Racer 6 introduces a career-mode \"World Xplorer,\" a branching-tree arrangement of races in which the player can only attempt races next to a race that has already been successfully completed. The layout of the races in the Xplorer is such that the position of a race will indicate what class of car can be used (horizontal position) and the difficulty of the course (vertical position). Rewards can be obtained by completing certain races or completing all races that enclose an area on the Xplorer, and usually offers new cars but also include additional variations of the tracks (mirroring and reverse) or new branches added to the tree. A player can also engage in quick races and time challenges for any track and car that has been unlocked.\r\n\r\nThere are thirty new circuits available including \"Surfside Resort\" and \"Harborline 765.\" Also, there are around 130 cars (including 10 special). Online multiplayer is possible with up to 14 players racing against each other and downloadable content is available via Microsoft's Xbox Live service. Players can download another player's \"ghost\" replay from Xbox Live and attempt to beat it.\r\n\r\nLike other Ridge Racer games, this iteration goes beyond cars to feature other outlandish vehicles as well, called \"special machines\" in the game. These include a hovercraft (Assoluto Pronzione), a tripod supercar (Himmel 490B) and an oversized SUV that can be very loud (Danver Bass Cruiser).[1] The game, as with all games in the Ridge Racer series, contains copious amount of references to other Namco games, such as Pac-Man, Soulcalibur, and Ace Combat.\r\n\r\nThe game also features a Full Motion Video opening, starring series mascot Reiko Nagase.\r\n\r\nIn Japan, Namco announced that it expected to sell 500,000 copies of Ridge Racer 6 for the Xbox 360, although far fewer copies were actually sold. Ridge Racer 7 for the PlayStation 3 is something of a \"director's cut\"/\"final version\" of Ridge Racer 6, but with major differences such as new vehicles that were not seen in Ridge Racer 6 such as Sinseong, a Korean brand.", 'youtube' => 'g38xo7TEFPI', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5804], 'genres' => [7], 'publishers' => [39], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 60, 'game_title' => 'Rumble Roses XX', 'release_date' => '2006-03-28', 'platform' => 15, 'overview' => 'The female wrestling series Rumble Roses returns for another round with Rumble Roses XX. Rumble Roses XX features a range of visual and gameplay enhancements, including new game modes and new wrestlers. You can create your own wrestler and upgrade their abilities by taking down their opponents. The game offers Xbox Live integration, featuring leaderboards, shared photos, and matches with up to four players.', 'youtube' => 'ys8XnKxykUw', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4765], 'genres' => [1, 11], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 61, 'game_title' => 'Sam & Max Hit the Road', 'release_date' => '1993-11-01', 'platform' => 1, 'overview' => "Grab your nightstick, squeal like a siren and Hit the Road with Sam & Max, Freelance Police, as they attempt to crack their toughest case. Sam (a shamus canine) and Max (a hyperkinetic rabbity thing) are hot on the trail of a runaway carnival bigfoot across America's quirky underbelly in this deranged animated adventure!\r\n\r\nHelp our frightening, furry flatfoots find the fugitive freak! Do it now!", 'youtube' => 'OtaCwN6wOAw', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5068], 'genres' => [2], 'publishers' => [25], 'alternates' => ['Sam and Max: Hit the Road'], 'uids' => nil, 'hashes' => nil }, { 'id' => 62, 'game_title' => 'Shaun White Snowboarding', 'release_date' => '2008-12-03', 'platform' => 1, 'overview' => 'There are six mountains in Shaun White Snowboarding, including Alaska, Park City, Europe and Japan. Each mountain features up to three different sections: peak, back country and park (or resort). There is also a special version of the game only available from Target which costs more. This version gives the player access to Target Mountain, an exclusive mountain with Target branding all over it; this mountain has been described as extremely difficult to find. The last mountain comes in with the "Mile-High pack", downloadable content for the game. It is called B.C. It is set in British Columbia (Canada). While you progress through the game you will earn abilities that will help you throughout the game. Some of the abilities consist of gaining high speeds or the ability to break through obstacles to progress further in the game.', 'youtube' => 'CJZLFm-pgGc', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9150], 'genres' => [11], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 63, 'game_title' => 'Sonic Riders', 'release_date' => '2006-11-17', 'platform' => 1, 'overview' => "The game's got a quite a few modes of play, a few of which support up to two people. There's a story mode, though there isn't much of a story. Its vaguely comprehensible plot points involve Eggman setting up an air-board tournament for Sonic, Tails, Knuckles, and his various cartoonish enemies. The winner gets a bunch of Chaos Emeralds, which unlocks long lost Babylon. Since he's a super villain, it makes sense that Eggman eventually steals all the Chaos Emeralds after the story mode's fifth race, prompting a sixth race amongst Babylon's ruins. In addition to the story for Sonic and friends, there's a separate one for his enemies, though the tracks are quite similar. There's also Free Race, Time Attack, and World Grand Prix modes, a Tag mode, and Race and Battle stage variations of a Survival mode.", 'youtube' => 'MQ6w0jvQSK8', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7979], 'genres' => [7], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 64, 'game_title' => "Tom Clancy's Splinter Cell", 'release_date' => '2002-11-19', 'platform' => 1, 'overview' => "Set in the fall of 2004, the player takes on the role of Sam Fisher, a long-dormant secret agent called back to duty by the American National Security Agency, to work with a secret division dubbed \"Third Echelon\". At this point, Fisher hasn't \"been in the field in years\". Fisher must investigate the disappearance of two CIA agents in the country of Georgia, which soon leads to a larger mission: saving the world from war with Georgia.", 'youtube' => 'Ia1tI12b7tg', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9150], 'genres' => [1, 16], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 65, 'game_title' => 'Tabula Rasa', 'release_date' => '2007-10-30', 'platform' => 1, 'overview' => nil, 'youtube' => '6XsAox0RQ8A', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5850], 'genres' => nil, 'publishers' => [18], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 66, 'game_title' => 'Tomb Raider (1996)', 'release_date' => '1996-11-22', 'platform' => 1, 'overview' => "In Tomb Raider, the player controls the female archaeologist Lara Croft, in search for the three mysterious Scion artefacts across the world. The game is presented in third person perspective. Lara is always visible and the camera follows the action from behind or over her shoulder. The world she inhabits is fully drawn in three dimensions and characterized by its cubic nature. Ledges, walls and ceilings mostly sit at 90 degrees to each other, but sometimes feature sloping planes.\r\nThe object of Tomb Raider is to guide Lara through a series of tombs and other locations in search of treasures and artefacts. On the way, she must kill dangerous animals and other creatures, while collecting objects and solving puzzles to gain access to an ultimate prize, usually a powerful artefact. Gunplay is restricted to the killing of various animals that appear throughout each stage, although occasionally Lara may be faced with a human opponent. Instead the emphasis lies on solving puzzles and performing trick jumps to complete each level.", 'youtube' => 'QNZzji8iShM', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1827], 'genres' => [1, 2], 'publishers' => [26], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 67, 'game_title' => 'Tomb Raider: Underworld', 'release_date' => '2008-11-21', 'platform' => 1, 'overview' => "Tomb Raider: Underworld begins where its predecessor left off, with Lara Croft searching for the mythical resting place of King Arthur, Avalon. Underneath the Mediterranean Sea Lara discovers Thor's gauntlet and then has an encounter with an old enemy, Jacqueline Natla, who has been imprisoned by Legend's antagonist, Amanda Evert. Natla tells Lara that the Norse underworld, Helheim and Avalon are one and the same and that she will need to find Thor's Hammer to open the Underworld. Lara soon discovers to find and wield the hammer she will have to find Thor's other gauntlet and his belt, to retrieve these artefacts she must explore underworlds all around the globe, facing the creatures, traps and puzzles that guard them. However, Lara discovers that Helhiem may contain a powerful weapon that could put the world in danger. Lara also finds herself faced with a doppelgänger of herself created by Natla, who burns down her house and kills one of Lara's assistants, Alister Fletcher. After finally completing her quest to find Mjolnir, taking her from the Mediterranean to Thailand to her own Manor to Central America then finally to Jan Mayan Island, she goes to Natla one more time and threatens to kill her if she doesn't tell her where Helheim is. Natla gives her the coordinates, but states that she knows the sacred Ritual of Odin, which partially opens the gate and allows Mjolnir to finish the job. Here Amanda enters, but before she and Lara can start fighting, the Doppelgänger takes Amanda and throws her down a shaft. Lara almost kills the Atlantean, but stops herself and simply releases her, letting Natla fly ahead to Helheim, beneath the Arctic icecap. With the ritual performed, Lara uses Mjolnir and enters Helheim, battling her way through hoards of Thralls, reanimated corpses of men and yetis protecting the secret at the heart of the city. Along the way, Lara encounters and shoots her mother, who has turned into a Thrall herself, and Natla reveals the true extent of her manipulation of Lara, even going back to when the Atlantean killed Lord Richard Croft when he saw Natla's intentions. Natla goes, saying '[she has] a serpent to raise', leaving the Doppelgänger to kill Lara. Amanda saves Lara's life and Lara pursues Natla, who is activating an ancient doomsday device called the Midgard Serpent, which could cause massive volcanic activity across the whole planet and destroy most of humanity, leaving Natla to be the ruler of what's left. Lara successfully destabilises the device and while Natla desperately tries to repair the damage, Lara throws Mjolnir at Natla, sending her down into the pool of deadly Eitr below and bringing the Midgard Serpent down with it. But this causes the pool to slowly rise and, as Amanda comes round from holding off the Yeti Thralls, she states the legend of Thor and the Serpent, ending 'We'll die here, just like your mother'. Lara suddenly sees a dais like the one that brought her mother to Helheim and together Lara and Amanda repair and use it, teleporting into the temple in Nepal. Lara and Amanda have one final face-off, before Amanda walks away and Lara bids one final farewell to her mother, then too departs", 'youtube' => 'aM1MqQua4hY', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2685], 'genres' => [1, 2], 'publishers' => [27], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 68, 'game_title' => 'Turok: Dinosaur Hunter', 'release_date' => '1997-03-04', 'platform' => 3, 'overview' => "Much like your usual 1st person shooter, although with dinosaurs as your main enemy. Includes 14 high tech weapons, like the Quad Rocket Launcher and the Atomic Fusion Cannon. You control Turok, who must take on the Campaigner and his highly evolved dino's. The objective is to collect pieces of the Chronoscepter, which is the only weapon that can help to destory the Campaigner, and to stop him from using the power of the weapon to destory the Lost Land.", 'youtube' => '3AKbul3ILM0', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4065], 'genres' => [8], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 69, 'game_title' => "Ultimate Ghosts 'n Goblins", 'release_date' => '2006-08-29', 'platform' => 13, 'overview' => "An exclusive PSP edition of Capcom's legendary platforming game, directed by the original's creator Tokurou Fujiwara. The game makes use of a 3D graphics engine, giving depth to the visuals, but plays in a side-scrolling perspective and similar art design to stay true to the original. Your goal is to work your way through side-scrolling stages, defeating enemies and using your best platforming skills. The game lets you build up your skills as you progress. You start off with just a basic jump, but eventually gain a double jump and even the ability to fly. You'll also earn lots of magic spells along the way. The game promises a greater number of spells and weapons than ever before. New for Goku Makaimura is non-linear gameplay. You're no longer on a fixed path from start to end. The levels include branching points and even warp points. By using a warp point, you can warp back to previous levels and collecting items that you might have missed.", 'youtube' => 'TlkRpMvbKfs', 'players' => 1, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [1436], 'genres' => [1, 15], 'publishers' => [9], 'alternates' => ['Goku Makai-Mura'], 'uids' => nil, 'hashes' => nil }, { 'id' => 70, 'game_title' => "Uncharted: Drake's Fortune", 'release_date' => '2007-11-19', 'platform' => 12, 'overview' => "A 400-year-old clue in the coffin of Sir Francis Drake sets a modern-day fortune hunter on an exploration for the fabled treasure of El Dorado, leading to the discovery of a forgotten island in the middle of the Pacific Ocean. The search turns deadly when Nathan Drake becomes stranded on the island and hunted by mercenaries. Outnumbered and outgunned, Drake and his companions must fight to survive as they begin to unravel the terrible secrets hidden on the Island.\r\nTaking full advantage of the power of PS3, Uncharted: Drake’s Fortune is developed using proprietary technology that promises to impress players with incredibly realistic characters and lifelike environments. Building on its legacy of extraordinary storytelling, developer Naughty Dog has created an elaborate plot that will have players guessing at every turn. Uncharted: Drake's Fortune, brings players into a world ripe with realism and unexpected juxtapositions.", 'youtube' => '8TxYmAKCXSE', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5839], 'genres' => [1, 2], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 71, 'game_title' => 'Viewtiful Joe', 'release_date' => '2003-10-07', 'platform' => 2, 'overview' => "Joe is no ordinary man and Viewtiful Joe is no ordinary game. Capcom's new superhero action game mixes funky cartoon-style visuals with classic side-scrolling gameplay and introduces the world's quirkiest million dollar action hero. More than just any ordinary dude, Joe must transform into the ultimate superhero. It's up to you to activate the correct view mode like \"slow\" or \"zoom in\" in order to clobber your enemies with beautiful style. You can also speed up or slow down your visual effects for even more \"viewtiful\" moves. Viewtiful Joe mixes an innovative viewpoint with an amazing stunt-filled action movie universe.", 'youtube' => '-Fb-L9tQ_ic', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1705], 'genres' => [1, 10], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 72, 'game_title' => 'Viking: Battle for Asgard', 'release_date' => '2008-03-25', 'platform' => 15, 'overview' => "Viking: Battle for Asgard thrusts players into a twisted mythological world overrun with demonic warriors unleashed by Hel, the Norse goddess of death. As Skarin, a rage-fueled Viking hero, players will wage all-out war to free mankind from the grip of evil and ultimate annihilation. Enemies will suffer graphic dismemberment with disturbing realism from an array of Skarin's melee, range and magic attacks.", 'youtube' => 'rQ6i1KKxVj4', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1891], 'genres' => [1, 2], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 73, 'game_title' => 'Age of Conan: Hyborian Adventures', 'release_date' => '2008-05-20', 'platform' => 1, 'overview' => 'Age of Conan is set in a low fantasy pseudo-historical ancient world called the Hyborian Age, created by Robert E. Howard. The warlord Conan has seized the throne of Aquilonia, but ancient evils seek to overthrow him.', 'youtube' => 'GESzNCBnphk', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3233], 'genres' => [4, 14], 'publishers' => [29], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 74, 'game_title' => 'Aliens: Colonial Marines', 'release_date' => '2013-02-12', 'platform' => 1, 'overview' => "Aliens: Colonial Marines is a squad-based first-person shooter in which the player controls four Colonial Marines, each with a different personality and primary weapon. Each player character can carry additional weapons including a flamethrower, pulse rifle, smartgun, pistol, RPG, and many types of grenades.\r\n\r\nThe player controls one marine at a time, issues orders to the others using context-sensitive commands, and may switch between characters at any time.\r\n\r\nThe player will also occasionally be required to control a particular location, using tactical positioning and turrets to fend off attacks. Aliens: Colonial Marines will have no HUD to provide the player with onscreen information.\r\n\r\nThe primary enemies of the game are Aliens which will generally attempt to sneak up on or outflank the player, forcing the player to use tactical combat to confront them. Several different types of Aliens will appear and will attack differently. Facehuggers will attempt to attach themselves to the player character's face, implanting an embryo inside them which will then kill them. \"Warrior\" Aliens are the primary enemies and are based primarily on the appearance of the Alien in Aliens. \"Scouts\" are faster and will spy on the player characters' activities. They will work in small groups or alone. These Aliens will be based on the appearance seen in Alien. \"Drones\" primarily carry and position eggs and work in the heart of the Hive serving the Queen; they were originally going to be in Aliens along with the \"Warriors\". An Alien queen will also appear as a \"boss\" enemy.", 'youtube' => 'GjY7yFMEk-c', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3423], 'genres' => [8], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 75, 'game_title' => 'Alone in the Dark', 'release_date' => '2008-06-23', 'platform' => 1, 'overview' => "It has been 83 years since Edward Carnby investigated the suicide of Jeremy Hartwood. Now he wakes up in an apartment in New York and is moments away from being shot by a group of bad guys. He doesn't remember much and as he looks into a mirror, a man looks back at him that isn't even near the age of 80. But as all hell breaks loose and mysterious forces tear through the building and the city itself, the question about his looks becomes one of many. To make things even worse, an old enemy decides to return in a search for a powerful stone. So for Carnby a race for survival begins and all signs point to Central Park.\r\n\r\nEdward's mysterious journey is divided into eight episodes that can be played in chronological order or can be accessed directly from the main menu. Once in the game, the player controls Edward either in a 1st-person or a 3rd-person manner either by switching manually or depending on the situation and what item he uses. If he picks up a fire extinguisher for example, the player will be able to extinguish fires with it if he is in 1st-person mode. In 3rd-person mode it instead becomes a deadly weapon or a battering ram.\r\n\r\nThis is especially important since Edward won't find much ammunition for the pistols, shotguns and other weapons in the game. Instead he needs to be creative and use the items he finds or the environment for his advantage. Especially since most enemies can only be permanently killed by burning them, igniting a wooden chair at a nearby fire, or using a lighter and a can of hairspray are Edward's best bets to knock them out.\r\n\r\nFire plays an important role in the game at all times. If not extinguished, it will slowly burn through anything in the vicinity and spread until everything burnable has been reduced to a smoking pile of ash. This behavior can of course be useful to Edward if he for instance wants to get through a closed wooden door and has nothing heavy at hand to force his way.", 'youtube' => '_Nn30cqZEQI', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2652], 'genres' => [1, 18], 'publishers' => [506], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 76, 'game_title' => 'Bionic Commando', 'release_date' => '1988-12-06', 'platform' => 7, 'overview' => "Bionic Commando takes place ten years after an unspecified World War between two warring factions. The game follows a commando who must infiltrate an enemy base and foil the enemy's plot to launch missiles.", 'youtube' => 'a0C3E8-u4VM', 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 77, 'game_title' => 'Burnout Paradise: The Ultimate Box', 'release_date' => '2009-02-05', 'platform' => 1, 'overview' => "Paradise's gameplay is set in the fictional \"Paradise City\", an open world in which players can compete in several types of races. Players can also compete online, which includes additional game modes, such as \"Cops and Robbers\". Several free game updates introduce new features such as a time-of-day cycle and motorcycles. The game also features paid downloadable content in the form of new cars and the fictional \"Big Surf Island\".", 'youtube' => 'HmQWkoRi5zo', 'players' => 4, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [1932], 'genres' => [1, 7], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 78, 'game_title' => "Clive Barker's Jericho", 'release_date' => '2007-10-23', 'platform' => 1, 'overview' => "Jericho's core gameplay consists of leading the game's eponymous seven-man team, allowing control of all team members by jumping to each character during certain points in the game, through various environments that have been warped by the Firstborn while fighting off a variety of twisted creatures.", 'youtube' => 'https://www.youtube.com/watch?v=wePhq7wNR-Q', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [5388], 'genres' => [1], 'publishers' => [16], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 79, 'game_title' => "Command & Conquer 3: Kane's Wrath", 'release_date' => '2008-03-28', 'platform' => 1, 'overview' => 'In the name of Kane! The Command & Conquerâ„¢ series continues to thrive with Command & Conquerâ„¢ 3: Kane’s Wrath. As the expansion pack to the critically-acclaimed and fan favorite, Command & Conquer 3: Tiberium Warsâ„¢, this Real-time Strategy (RTS) game returns to the Tiberium Universe with Kane at the center of an epic new single player campaign spanning 20 years – from the rebirth of the Brotherhood of Nod after the Second Tiberium War through the dramatic events of the Third Tiberium War and beyond. This story will be told through a new set of high-definition, live action video sequences starring a celebrity cast including Joe Kucan, playing the megalomaniac leader of the Brotherhood of Nod, alongside new talent Natasha Henstridge and Carl Lumbly. With your help, Commander, the Dark Messiah may rise again!', 'youtube' => '96LNtvpIjiQ', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2579], 'genres' => [3], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 80, 'game_title' => 'Command & Conquer 3: Tiberium Wars', 'release_date' => '2007-03-26', 'platform' => 1, 'overview' => "Tiberium Wars takes place in the year 2047, at the advent of and during the \"Third Tiberium War\" when the Brotherhood of Nod launches a worldwide offensive against the Global Defense Initiative, abruptly ending 17 years of silence and crippling GDI forces everywhere. With the odds tipped in the Brotherhood's favor this time, GDI field commanders rally their troops and begin to combat Nod's second re-emergence, trying to restore lost hope. In the middle of it all, a new playable faction of extraterrestrials appears: the Scrin.", 'youtube' => 'gCimGS7I1UQ', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2727], 'genres' => [6], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 81, 'game_title' => 'Crisis Core: Final Fantasy VII', 'release_date' => '2008-03-24', 'platform' => 13, 'overview' => "Seven years prior to the events of FINAL FANTASY VII, the Shinra Company is finalizing construction of its base and symbol of prosperity: the enormous city of Midgar. When Genesis, a prominent SOLDIER 1st Class in Shinra's private army disappears with his contingent, young prodigy Zack is given the task of seeking him out. The story continues where it all began in an enthralling prelude to one of gaming's greatest sagas.\r\n\r\n-The exciting prequel to FINAL FANTASY VII uncovers the origin and secrets behind some of the most popular characters in SQUARE ENIX history.\r\n-Home console-quality graphics on a portable platform. Stunning, state-of-the-art visuals bring the FINAL FANTASY VII universe to life on the PSP & reg; system.\r\n-A blend of action and RPG elements provide for a completely new FINAL FANTASY VII experience. The fast-paced real-time battle system is the latest evolution of classic FINAL FANTASY gameplay", 'youtube' => 'PwVf7DAPIBs', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2808], 'genres' => [1, 4], 'publishers' => [12], 'alternates' => ['Crisi Core Final Fantasi VII'], 'uids' => nil, 'hashes' => nil }, { 'id' => 82, 'game_title' => 'Dark Sector', 'release_date' => '2008-03-25', 'platform' => 15, 'overview' => "Set in the crumbling infrastructure of a fictional Eastern Bloc country in the near future, the game features both single and multiplayer action, with players working their way through a world where biological weapons are a hellish nightmare, let loose on an unsuspecting populace.\r\n\r\nThe game's main character is a man named Hayden Tenno (voiced by Michael Rosenbaum), a morally ambivalent clean-up man employed by the CIA. He has congenital analgesia which renders him unable to feel pain. On a mission in a fictional former Eastern Bloc nation, he is exposed to a biological compound which mutates him, dramatically changing his right arm, and giving him the ability to grow a three-bladed throwable weapon called a glaive at will. The glaive is a part of his body, can be used to generate light, and can be controlled remotely by the player.", 'youtube' => '7nl8890-C2w', 'players' => 10, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2322], 'genres' => [8], 'publishers' => [31], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 83, 'game_title' => 'Final Fantasy III', 'release_date' => '1994-04-02', 'platform' => 6, 'overview' => "MagiTek has been reborn. And the end of the world is near.\r\nAges ago, evil beings created powerful creatures called Espers, and unleashed them against each other. The resulting battles left their world a smoldering rubble. Legend has it, the Espers destroyed themselves and most of humanity. Magic disappeared forever.\r\n\r\nCenturies have passed and a rational world now exists with Espers living only in myths, until one frozen solid since the ancient wars is unearthed. Suddenly, there are reports of magical attacks on civilians. Imperial Commandos launch raids using magic-powered MagiTek weapons. Magic is obviously alive and the world is in danger again.\r\n\r\nWho or what is behind the rediscovery and redeployment of this legendary power? What chaotic plans exists that will wreak havoc on this orderly world?", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8096], 'genres' => [4], 'publishers' => [11], 'alternates' => ['ファイナルファンタジーVI (JP)', 'Final Fantasy 3', 'Final Fantasy VI (JP)', 'Final Fantasy 6 (JP)'], 'uids' => nil, 'hashes' => nil }, { 'id' => 84, 'game_title' => 'Empire Earth III', 'release_date' => '2007-11-06', 'platform' => 1, 'overview' => "Empire Earth III is a real-time strategy video game developed by Mad Doc Software and published by Sierra Entertainment, released on November 6, 2007.[1][2][3] It is the latest installment of the Empire Earth series and has generally received widespread negative reviews.[4]\r\n\r\nEmpire Earth III contains five epochs, fewer than other games in the series but covering roughly the same time period. The game features three factions: Middle Eastern, Western, and Far Eastern.[5] Each faction comprises unique buildings, units, and technologies.", 'youtube' => 'F7PS0GLrQ7M', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5130], 'genres' => [3, 6], 'publishers' => [32], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 85, 'game_title' => 'Enemy Territory: Quake Wars', 'release_date' => '2007-09-28', 'platform' => 1, 'overview' => "Quake Wars is a class-based, objective focused, team-oriented game. Teams are based on human (GDF) and alien (Strogg) technology. While the teams are asymmetrical, both sides have the same basic weapons and tools to complete objectives. \r\n\r\nUnlike other team-based online games, the gameplay is much more focused on one or two main objectives at once, rather than spread all over the combat area.", 'youtube' => 'xBm1jWchEqY', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8079], 'genres' => [8], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 86, 'game_title' => 'Fallout 3', 'release_date' => '2008-10-28', 'platform' => 1, 'overview' => "Fallout 3 takes place in the year 2277, 36 years after the setting of Fallout 2 and 200 years after the nuclear apocalypse that devastated the game's world in a future where international conflicts culminated in a Sino-American war in the second half of the 21st century. The game places the player in the role of an inhabitant of Vault 101, a survival shelter the size of a village, designed to protect a small number of humans from the nuclear fallout. When the player character's father disappears under mysterious circumstances, the player is forced to escape from the Vault and journey into the ruins of Washington D.C. to track him down. Along the way the player is assisted by a number of human survivors and must battle a myriad of enemies that inhabit the area now known as the \"Capital Wasteland\".", 'youtube' => 'iYZpR51XgW0', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1009], 'genres' => [1, 2, 4, 8], 'publishers' => [34], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 87, 'game_title' => 'Final Fantasy XII', 'release_date' => '2006-10-31', 'platform' => 11, 'overview' => "Final Fantasy XII takes place in the fictional location of Ivalice, where the empires of Archadia and Rozarria are waging an endless war. Dalmasca, a small kingdom, is caught between the warring nations. When Dalmasca becomes annexed by Archadia, its princess, Ashe, creates a resistance movement. During the struggle, she meets Vaan, a young adventurer who dreams of commanding an airship. They are quickly joined by a band of allies; together, they rally against the tyranny of the Archadian Empire.\r\n\r\nAlso Available:\r\nFinal Fantasy XII: Collector's Edition\r\n\r\nThis edition includes the original game packaged in a metallic case along with a special bonus disc, which contains Final Fantasy XII developer interviews, an art gallery, U.S. and Japanese trailers, and a featurette entitled \"History of Final Fantasy\", which gives a brief overview of most released and upcoming Final Fantasy games.", 'youtube' => 'sEpQ8rmWwRA', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2808], 'genres' => [4], 'publishers' => [12], 'alternates' => ['Final Fantasy 12', 'FFXII', 'FF12'], 'uids' => [{ 'uid' => 'SLPM-66320', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLUS-20963', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLES-54354', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLUS-21475', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLES-54355', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 88, 'game_title' => 'God of War II', 'release_date' => '2007-03-13', 'platform' => 11, 'overview' => 'Kratos is now the God of War, having defeated the Olympian god Ares. Shunned by the other gods and still haunted by nightmares from his past, Kratos decides to join an army of Spartans in an attack on the city of Rhodes. Kratos also ignores a warning from the goddess Athena that his lust for revenge is alienating the other gods.', 'youtube' => 'GjYbK_-w9pM', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7435], 'genres' => [1, 15], 'publishers' => [14], 'alternates' => nil, 'uids' => [{ 'uid' => 'SCUS-97481', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPM-67013', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLUS-97481', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SCES-54206', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 89, 'game_title' => 'God of War: Chains of Olympus', 'release_date' => '2008-03-04', 'platform' => 13, 'overview' => "The game is set in Ancient Greece and loosely based on its mythology. The player controls Kratos, a Spartan warrior in the service of the Olympian Gods. Kratos is guided by the goddess Athena, who instructs him to find the Sun God Helios, as the Dream God Morpheus has caused the remaining gods to slumber in Helios' absence. With the power of the sun, Morpheus and Persephone, the Queen of the Underworld, with the aid of the Titan Atlas, intend to destroy the Pillar of the World and in turn Olympus. God of War: Chains of Olympus is chronologically the second chapter in the series, which focuses on vengeance as its central theme.", 'youtube' => 'TCD_lGhEzPI', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7030], 'genres' => [1, 2], 'publishers' => [14], 'alternates' => ['God-of-War'], 'uids' => nil, 'hashes' => nil }, { 'id' => 90, 'game_title' => 'Halo 3', 'release_date' => '2007-09-25', 'platform' => 15, 'overview' => "Master Chief returns to a Covenant Dominated Earth on a mission to kill the final alien leader. Meanwhile, the Arbiter, Johnson, and Keyes form a loose alliance and escape from Delta Halo. The Covenant is ripped in civil war, and the Elites along with a handful of other alien races become sympathetic to the human cause. Delta Halo's impromptu dis-activation has brought all of the Halos to a \"remote activation phase\". They can be activated from a facility called the ark, which happens to be on Earth.", 'youtube' => 'xhzJumt6264', 'players' => 2, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [1389], 'genres' => [8], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 91, 'game_title' => 'Iron Man', 'release_date' => '2008-05-06', 'platform' => 1, 'overview' => "Iron Man is a 2008 video game based on the film of the same name as well as the classic iterations of the character.[2] It was released on May 2, 2008 to coincide with the release of the film in cinemas. The game is published by Sega, and was released on PlayStation 3, Xbox 360 (developed by Secret Level), PlayStation 2, PlayStation Portable, Nintendo DS, Wii, Microsoft Windows (developed by Artificial Mind and Movement) and Mobile platforms.\r\n\r\nThe enemies are Advanced Idea Mechanics, the Maggia and the Ten Rings terrorist group. The supervillains in the game includes Blacklash, Controller, Titanium Man, Melter, and Iron Monger.[3]\r\n\r\nA significant feature has Robert Downey, Jr., Terrence Howard and Shaun Toub reprising their roles from the film.[4]", 'youtube' => '1WxdJTnn8fA', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [670], 'genres' => [1, 2], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 92, 'game_title' => 'Medal of Honor: Airborne', 'release_date' => '2007-09-14', 'platform' => 1, 'overview' => 'The game begins as Boyd Travers, a member of the 82nd Airborne Division of the U.S. Army, begins his first mission in the Invasion of Sicily in 1943. The story begins with a brief training level, but then takes you to the first mission: "Operation Husky". The single player campaign includes six missions, each mission can be easily played in under two hours for a total of about 10-12 hrs of total game play.', 'youtube' => 'rbca7C_ObRc', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2563], 'genres' => [8], 'publishers' => [35], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 93, 'game_title' => 'Monster Hunter 2', 'release_date' => '2006-02-16', 'platform' => 11, 'overview' => "Monster Hunter 2 has an improved weapon tree and upgradeable armors. As in all Monster Hunter games, armor pieces can be worn to obtain skills and abilities. A new feature in Monster Hunter 2 is the use of gems. Gems add skill points to complement those added by armor and weapons. Gems are created by combining ore and/or monster parts. Gems can be attached and detached from armor and weapons that have special gem slots.\r\n\r\nAlong with the various species of monster returning from the first Monster Hunter, Monster Hunter 2 contains many new monsters, such as the metallic wind dragon Kushala Daora, the lion-headed dragon Teo Teskatoru (named Teostra in the North American and PAL versions of Monster Hunter Freedom 2) and his female counterpart Nana Teskatory (named Lunastra in the North American and PAL versions of MHF2), the primates Babakonga and Dodobrango (Congalala and Blangonga in MHF2), the bull or minotaur-like monster Rajang, and the chameleon-like dragon Oonazuchi (Chameleos in MHF2). With new monsters also comes the prospect of new weapons and armor.", 'youtube' => 'j-LuD7MPRXM', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [1436], 'genres' => [1, 4], 'publishers' => [9], 'alternates' => nil, 'uids' => [{ 'uid' => 'SLPM-66280', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLPM-74245', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 94, 'game_title' => 'MotorStorm: Pacific Rift', 'release_date' => '2008-10-28', 'platform' => 12, 'overview' => "The game moves away from the desert environments of the original title and relocates itself in \"a lush island environment, full of interactive vegetation\"; and also includes monster trucks and four-player split-screen capability. Monster trucks are able to ride over cars (except big rigs), break most vegetation, and destroy structures. Bikes also have new capabilities so they can bunny hop and the driver can duck. Custom music tracks using a player's own music stored on their PS3 hard drive are available as are trophies (to unlock more Drivers and Vehicles) and camera angles are improved for crashes; vehicle damage is also improved. Users can now select drivers from the Garage menu, thus not having to rely on picking the vehicles, depending on the Driver's gender. \"Speed\" events are firstly introduced in the game, which consists numerous checkpoints in each tracks that users must pass through to achieve extra times before the timer runs out. Any class that isn't the ATV or Bikes can ram their vehicles left or right. The ATV and Bike ram by their driver throwing punches at the other drivers.", 'youtube' => 'DZyXHESAC5U', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2911], 'genres' => [7], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 95, 'game_title' => 'Project Gotham Racing 4', 'release_date' => '2007-11-18', 'platform' => 15, 'overview' => 'Project Gotham Racing 4 is the fourth title in the main Project Gotham Racing series, developed by Bizarre Creations and published by Microsoft Game Studios.', 'youtube' => 'dhyYj2g8hb0', 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1131], 'genres' => [7], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 96, 'game_title' => 'Prototype', 'release_date' => '2009-06-09', 'platform' => 1, 'overview' => "The game is set in New York City, where a virulent plague is spreading through Manhattan. Those infected are mutated into hideous monsters. The United States Marine Corps, under the command of the black ops organization Blackwatch, is dispatched to contain it. At the center of it is the protagonist, Alex Mercer, a shapeshifter with no memory of his past. Alex has the ability to absorb other individuals, taking on their biomass, memories, experiences, and physical forms. Parallel to the game's storyline is the ability to play the game as a sandbox-style video game giving the player freedom to roam Manhattan.", 'youtube' => 'JvsUkUaJjYs', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [6942], 'genres' => [1, 2], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 97, 'game_title' => 'Resistance: Fall of Man', 'release_date' => '2006-11-17', 'platform' => 12, 'overview' => "By 1949 an alien race known as the Chimera spread throughout Europe. Originating in Russia, the creatures propagate by infecting humans virally; mutating them into fellow Chimeran breeds. Their rapid infection and warfare overwhelm the continent as nations fall. Within months, the Chimera cross the English Channel by digging tunnels underneath and invade the United Kingdom, which quickly loses the war and has its troops scattered.\r\nIn 1951, the game begins with the protagonist Sgt. Nathan Hale, on his way with a large United States task force, to retrieve a secret weapon that the British claim can be used against the Chimera in exchange for supplies. However, soon after landing in York, the forces are ambushed by the Chimera and the remnants are quickly wiped out by a Chimeran spire attack, which unleashes insect like creatures that infects all of the soldiers. Hale, the only survivor, resists the full effects of infection and does not go into a coma. Instead, he possesses increased strength, health regeneration and gold-coloured irises, somewhat like the Chimera.", 'youtube' => 'nJ8Yuq8qpbM', 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [4232], 'genres' => [8], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 98, 'game_title' => 'SOCOM: U.S. Navy SEALs Confrontation', 'release_date' => '2008-10-14', 'platform' => 12, 'overview' => 'SOCOM: Confrontation focuses on online play and the global community and clans that support it. With support for Tournaments, Clan Ladders, Leader Boards, this latest title in the multi-million unit selling franchise is exactly what SOCOM fans have been clamoring for. Additionally, players will be able to modify their appearance through facial and physical customization. A global-scale experience, SOCOM Confrontation gives players the opportunity to battle against the best and brightest from the U.S., Europe and Asia. SOCOM Confrontation deploys with five new North African themed maps, including a 32-player version of "Crossroads." Additional themed packs for SOCOM Confrontation will be made available for download via the Playstation Store.', 'youtube' => 'GVWQzvfDY18', 'players' => 4, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [7837], 'genres' => [8], 'publishers' => [21], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 99, 'game_title' => 'SoulCalibur IV', 'release_date' => '2008-07-29', 'platform' => 15, 'overview' => "Soulcalibur IV (ソウルキャリãƒãƒ¼IV SÅruKyaribÄ FÅ?) is the fifth installment in Namco's Soul series of fighting games, released for the PlayStation 3 and Xbox 360 in 2008. Soulcalibur IV included three characters from the Star Wars franchise as playable fighters.", 'youtube' => 'oHe-AxsB450', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5804], 'genres' => [1, 10], 'publishers' => [6], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 100, 'game_title' => 'Spider-Man 3', 'release_date' => '2007-05-04', 'platform' => 12, 'overview' => "The game's plot expands on the film by including additional characters and elements from the Spider-Man comics and the Marvel Universe. Depending on the platform, different villains from the comics are featured, but all versions of the game feature the film's main villains: Venom, New Goblin, and Sandman.", 'youtube' => 'O4JB4B4RXpg', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9025], 'genres' => [1], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 101, 'game_title' => 'S.T.A.L.K.E.R.: Clear Sky', 'release_date' => '2008-09-05', 'platform' => 1, 'overview' => "S.T.A.L.K.E.R.: Clear Sky is a survival FPS game for PC based on a 'what-if' scenario of the second Chernobyl Nuclear Power Plant accident. The game is set in 2011 and brings forth the events to have preceded the third campaign of Strelok to the Zone center. S.T.A.L.K.E.R.: Clear Sky introduces an alternative look onto the events of the original game and offers the player to try himself out as a mercenary s.t.a.l.k.e.r. in search of his own path in the world of S.T.A.L.K.E.R.", 'youtube' => 'IJzJU1638oc', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3645], 'genres' => [1, 8], 'publishers' => [37], 'alternates' => ['S.T.A.L.K.E.R.: ЧиÑтое небо (RU)'], 'uids' => nil, 'hashes' => nil }, { 'id' => 102, 'game_title' => 'Star Wars: The Force Unleashed', 'release_date' => '2009-11-30', 'platform' => 1, 'overview' => "The game bridges the two Star Wars trilogies and introduces a new protagonist, code named \"Starkiller\", as Darth Vader's secret apprentice.", 'youtube' => 'RkBiYpD3SDc', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5068], 'genres' => [1], 'publishers' => [25], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 103, 'game_title' => 'Street Fighter IV', 'release_date' => '2008-07-18', 'platform' => 1, 'overview' => 'Street Fighter IV is a 2008 fighting game produced by Capcom. It is the first numbered Street Fighter game released by Capcom for the arcades since 1999.', 'youtube' => 'JWhOsX_LAfw', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1436], 'genres' => [10], 'publishers' => [9], 'alternates' => ['Street Fighter 4'], 'uids' => nil, 'hashes' => nil }, { 'id' => 104, 'game_title' => 'The Eye of Judgment', 'release_date' => '2007-10-24', 'platform' => 12, 'overview' => "Sony Computer Entertainment introduces a new concept in trading card games with THE EYE OF JUDGMENTâ„¢ developed exclusively for PLAYSTATION®3 computer entertainment system. Utilizing Hasbro® and its Wizards of the Coast subsidiary's trading card expertise, the immense power of the PS3® system, and the PLAYSTATION®Eye, Sony's groundbreaking next-generation USB camera for PS3, THE EYE OF JUDGMENT provides a visually stunning experience that adds a third dimension to the trading card game genre.\r\nDeveloped by Sony Computer Entertainment Worldwide Studios, JAPAN Studio, THE EYE OF JUDGMENT presents a new style of gameplay where collectable trading cards, embedded with a CyberCode, are brought to life in the 3D game through use of the innovative PLAYSTATION Eye. Players compete by selecting a card and placing the coded card in front of the PLAYSTATION Eye for their respective creatures to come to life and battle on screen. Players take turns placing cards as they jostle for control; the winner is the first player to conquer five of the nine squares of the \"9 Fields\" battle mat. The gamers task is to conquer the board by deploying their cards more skillfully than their opponent.\r\nPlayers have four ways to play THE EYE OF JUDGMENT, single player against their PS3, against an opponent in two-player mode, against an opponent online, or letting the PS3 play out a round with the cards the player owns. THE EYE OF JUDGMENT comes with a starter deck of 30 character and spell cards manufactured by Hasbro.", 'youtube' => '1OTdOjSfiSs', 'players' => 3, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [4441], 'genres' => [6], 'publishers' => [38], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 105, 'game_title' => 'Wheelman', 'release_date' => '2009-03-24', 'platform' => 1, 'overview' => 'The game is set in an open world modeled after Barcelona, full of destructible objects, alleyways, shortcuts through office blocks and a total of 31 story missions and 105 side missions. While most missions are driving-oriented there are also foot missions which are played from a third person and incorporated a crouching system similar to the one used in Goldeneye. A wide variety of guns are preserved for the player including pistols to RPGs.', 'youtube' => 'TxKpYUJQ8cI', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5516], 'genres' => [1], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 106, 'game_title' => "Tom Clancy's Rainbow Six: Vegas 2", 'release_date' => '2008-03-18', 'platform' => 1, 'overview' => "The game, billed as \"part sequel, part prequel\", has events that run both before and concurrently to the story of Logan Keller and continue after where the first game concluded.\r\n\r\nBishop is the main protagonist that the player controls and guides throughout the events of Rainbow Six: Vegas 2. His/her appearance and gender vary, depending on the intended look by the player. Either way, Bishop is still called \"sir\" in the game. He or she is a high-ranking veteran of the Rainbow organization, and is an instructor at the organization's training academy when the game first begins. Bishop is referred five years after the first mission in the French Alps, Bishop returns from retirement as the team leader of Jung and Michael. Bishop and Chavez are old friends and served together in the Army.", 'youtube' => 'ZfG3vjxnQlk', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9150], 'genres' => [8], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 107, 'game_title' => 'Transformers: The Game', 'release_date' => '2007-06-26', 'platform' => 1, 'overview' => "Transformers: The Game is the name of multiple versions of a video game based on the 2007 live action film Transformers, all of which were released in North America in June 2007. Home console and PC versions were developed by Traveller's Tales for the PlayStation 2, Xbox 360, Wii, PlayStation 3 and PC. A different PlayStation Portable version was developed by Savage Entertainment.\r\n\r\nTransformers Autobots and Transformers Decepticons are the Nintendo DS versions of Transfomers: The Game. Vicarious Visions, who was tasked with bringing the adaptation to the Nintendo DS, chose to adapt the DS version into two separate games.[1] Autobots follows the heroes' perspective while Decepticons follows the villains'. Unlike games with multiple SKUs such as Pokémon which feature only minor differences between versions, these are two separate games, sharing some basic similarities, but with unique characters, missions and locations.[2]", 'youtube' => 'WpkBSONusT0', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => nil, 'genres' => nil, 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 108, 'game_title' => 'Wet', 'release_date' => '2009-09-15', 'platform' => 15, 'overview' => "Rubi is a problem fixer. She fixes problems. She's good at it. But when she agrees to fix a wealthy man's problem by finding and bringing back his wayward son, she thinks it's all going to be cut and dry. She thought wrong. The job wasn't so simple. And the man who hired her isn't who he appears to be. Now Rubi's on the run, needing to find the man who left her for dead, leaving a massive body count in her wake. Double-crosses. Enemies. Allies. Guns. Swords. Drugs. Old books. In an adventure that spans three continents, two warring factions, and one very agitated problem fixer, WET keeps the adrenaline pumping from start to finish.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [670], 'genres' => [1, 8], 'publishers' => [34], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 109, 'game_title' => 'The Legend of Zelda: Twilight Princess', 'release_date' => '2006-11-19', 'platform' => 9, 'overview' => "Join Link for an legendary adventure on the Wii console.\r\n\r\nWhen an evil darkness enshrouds the land of Hyrule, a young farm boy named Link must awaken the hero – and the animal – within. When Link travels to the Twilight Realm, he transforms into a wolf and must scour the land with the help of a mysterious girl named Midna. Besides his trusty sword and shield, Link will use his bow and arrows by aiming with the Wii Remote controller, fight while on horseback and use a wealth of other items, both new and old.\r\n\r\nFeatures\r\n\r\n* Arm Link: The Wii Remote and Nunchuk controllers are used for a variety of game activities from fishing to projectile-weapon aiming. The game features incredibly precise aiming control using the Wii Remote controller. Use the controllers for sword swings, spin attacks and shield shoves.\r\n\r\n* Thrilling Adventure: Players ride into battle against troops of foul creatures and wield a sword and shield with the Wii Remote and Nunchuk controllers, then take on massive bosses that must be seen to be believed.\r\n\r\n* Mind & Muscle: Many puzzles stand between Link and the fulfillment of his quest, so players must sharpen their wits as they hunt for weapons and items.", 'youtube' => 'ceCktUEG4jA', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6037], 'genres' => [1, 2, 4, 5, 15], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 110, 'game_title' => 'Warhammer: Mark of Chaos', 'release_date' => '2006-11-14', 'platform' => 1, 'overview' => 'The gameplay is primarily focused on battlefield tactics, thus not featuring RTS gameplay aspects like base-building, resource harvesting or in-battle unit production. Instead, the gameplay is intended to be focused on high fantasy/late medieval battles. Its gameplay is superficially similar to its predecessors and the Total War games; however, the basic game play model is significantly more simplified, and battles are more similar to real-time strategy games like Warcraft III than other real-time tactics titles.', 'youtube' => 'https://www.youtube.com/watch?v=2iO9cGopQq0', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1140], 'genres' => [6], 'publishers' => [39], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 111, 'game_title' => 'Warhammer 40,000: Dawn of War II', 'release_date' => '2009-02-18', 'platform' => 1, 'overview' => "Warhammer 40,000: Dawn of War II is set in the grim, war-ravaged world of Games Workshop's Warhammer 40,000 universe - a dark, futuristic, science-fiction setting where armies of technologically advanced warriors, fighting machines and hordes of implacable aliens wage constant war. Dawn of War II ushers in a new chapter in the RTS series, as ancient races - including the dauntless Space Marines and savage Orks - clash across ruined worlds on a mission to claim the galaxy and preserve their own existence. Powered by the re-vamped Essence Engine 2.0, the next evolution of Relic's proprietary game engine made famous in the award winning Company of Heroes, Warhammer 40,000: Dawn of War II delivers fast-paced RTS action with ferocious melee and ranged combat in fully destructible environments. The game immerses players in an in-depth non-linear single-player campaign and a fully-co-operative multiplayer mode.\r\nFAQs, Guides, Cheats, and Secrets", 'youtube' => '', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7131], 'genres' => [6], 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 112, 'game_title' => 'Super Mario Bros. 3', 'release_date' => '1990-02-12', 'platform' => 7, 'overview' => "Fight monsters and mini-bosses, avoid ghosts and the burning sun. Make your way through water and quicksand. Dodge cannonballs and bullets and rescue the King’s wand!\r\n\r\nIn Super Mario Bros. 3 there are more warps, more chances at extra lives, and new special suits! The raccoon suit lets you fly and knock out blocks. The frog suit helps you out-swim the deadly fish. There are suits for every occasion!\r\n\r\nStore up flowers and mushrooms to use later on. Play game-show type bonus rounds! Go back to that last screen and get a mushroom! Pause to take a break, then continue where you left off!\r\n\r\nSuper Mario Bros. 3 is fun to play alone, or team up with a buddy to prolong the adventure!\r\n\r\nNote: Turn based Co-op as players work in turn to clear individual levels in a world. There is also a vs. mini-game where players try to steal items from each other.", 'youtube' => 'PKuFlO8FdRA', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [6055], 'genres' => [1, 2, 15], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 113, 'game_title' => 'The Legend of Zelda', 'release_date' => '1987-07-01', 'platform' => 7, 'overview' => "Welcome to the Legend of Zelda. Where the only sound you’ll hear is your own heart pounding as you race through forests, lakes, mountains and dungeonous mazes in an attempt to restore peace to the land of Hyrule. Along the way you’ll be challenged by Tektites, Wizzrobes and an endless array of ruthless creatures who’ll stop at nothing to prevent you from finding the lost fragments of the Triforce of Wisdom. But don’t despair. With a little luck and a lot of courage, you’ll conquer your adversaries, unite the Triforce fragments and unravel the mystery of the Legend of Zelda!\r\n\r\n• Explore the vast Overworld terrain of the land of Hyrule and discover hidden treasures.\r\n• Explore the mystical labyrinths of the Underworld and ward-off ruthless enemies.", 'youtube' => 'uI3rO3PbYOo', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6055], 'genres' => [1, 2], 'publishers' => [3], 'alternates' => ['The Hyrule Fantasy: Zeruda no Densetsu', 'The Hyrule Fantasy: The Legend of Zelda', 'The Legend of Zelda: The Hyrule Fantasy'], 'uids' => nil, 'hashes' => nil }, { 'id' => 114, 'game_title' => 'Sonic the Hedgehog', 'release_date' => '1991-06-23', 'platform' => 18, 'overview' => "Super Speed! Bust the video game speed barrier wide open with Sonic the Hedgehog. Blaze by in a blur using the super sonic spin attack. Loop the loop by defying gravity. Plummet down tunnels. Then dash to safety with Sonic's power sneakers. All at a frenzied pace. Super Graphics! Help Sonic escape bubbling molten lava. Swim through turbulent waterfalls. Scale glistening green mountains. And soar past shimmering city lights. There's even a 360 degree rotating maze. You've never seen anything like it. Supper Attitude! Sonic has an attitude that just won't quit. He's flip and funny, yet tough as nails as he fights to free his friends from evil. So just wait. Sonic may be the world's next SUPER hero...", 'youtube' => 'TR7r4PlNeOY', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7979], 'genres' => [1, 15], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 115, 'game_title' => 'Castle of Illusion Starring Mickey Mouse', 'release_date' => '1990-11-22', 'platform' => 18, 'overview' => "The search is on! Mickey is on the trail of a wicked Witch named Mizrabel, who has kidnapped Minnie. Mickey must find seven gems hidden in the fantastic chambers of Mizrabel's Castle of Illusion and use them to save Minnie. Can Mickey find them? It's up to you.\r\n\r\nBe on your guard! Behind every door lurks an enchanted land of beauty and danger. You must defeat angry chess knights, overcome the evil haunted trees, and do battle with ghoulish ghosts and a deadly dragon. No place is safe -- even the library is fraught with danger. Playing three levels in the practice mode will prepare you for the challenge you will face. Then, just when you think you've mastered the Illusions, you come face to face with the most dangerous of them all -- Witch Mizrabel!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [2, 15], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 116, 'game_title' => 'Space Invaders', 'release_date' => '1978-06-01', 'platform' => 23, 'overview' => "Space Invaders is a two-dimensional fixed shooter game in which the player controls a laser cannon by moving it horizontally across the bottom of the screen and firing at descending aliens. The aim is to defeat five rows of eleven aliens—some versions feature different numbers—that move horizontally back and forth across the screen as they advance towards the bottom of the screen. The player defeats an alien, and earns points, by shooting it with the laser cannon. As more aliens are defeated, the aliens' movement and the game's music both speed up. Defeating the aliens brings another wave that is more difficult, a loop which can continue indefinitely.", 'youtube' => '437Ld_rKM2s', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8449], 'genres' => [8], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 117, 'game_title' => 'Space Harrier', 'release_date' => '1994-12-03', 'platform' => 33, 'overview' => "Space Harrier is set in the \"Fantasy Zone\", a surreal world composed of bright colors and a checkerboard-styled ground. The enemies are also unique, featuring prehistoric animals, Chinese dragons, and alien pods. The player is forced along the levels, running or flying around enemy fire, while shooting back with fireballs via the character's under-arm cannon (which doubles as a rocket-esque device allowing the character to fly).", 'youtube' => 'https://www.youtube.com/watch?v=Hzgrb-mjLaM', 'players' => 1, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [7549], 'genres' => [8], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 118, 'game_title' => 'Altered Beast', 'release_date' => '1988-11-27', 'platform' => 18, 'overview' => "Altered Beast is a side scrolling, platform, beat 'em up game that puts the player in control of a centurion who had died in battle. The centurion has been raised from the dead to rescue Zeus' daughter Athena from the demon Neff. The player battles undead and demonic hordes, controlling the shapeshifting hero. He must fight through several levels in order to save the kidnapped goddess. Although 'Centurion' was a rank in the Roman Army, the game takes place in a setting resembling Ancient Greece, complete with gods, temples and ruined Ionic columns.", 'youtube' => 'https://www.youtube.com/watch?v=rG3pMeaqnqw', 'players' => 2, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [7549], 'genres' => [1], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 119, 'game_title' => 'R-Type', 'release_date' => '1987-07-01', 'platform' => 18, 'overview' => "R-Type is set in the 22nd century, and the player flies a futuristic fighter craft called the R-9a \"Arrowhead\", named for its shape, and because it is the ninth model in the 'R' series of fighter craft (but it is the first of the series to actually be used in combat; the previous models were all prototypes). The mission is to 'blast off and strike the evil Bydo Empire'.", 'youtube' => 'https://www.youtube.com/watch?v=cGFOhrANwts', 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4335], 'genres' => [8], 'publishers' => [42], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 120, 'game_title' => 'Shinobi III: Return of the Ninja Master', 'release_date' => '1994-05-18', 'platform' => 18, 'overview' => "The Shinobi master of stealth and the lethal ninja arts is back, bigger and deadlier than ever! Joe Musashi's sworn enemy, the Neo Zeed, grips the city in a vicious crime ring. Shadow Master, a super ninja cloned from Joe's own bloodline, controls the Zeed's savage army of bio-ninja. Musashi has no choice but to annihilate them all!", 'youtube' => 'https://www.youtube.com/watch?v=1wcyaZDG3f4', 'players' => 1, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [5367], 'genres' => [1], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 121, 'game_title' => "Kirby's Adventure", 'release_date' => '1993-03-26', 'platform' => 7, 'overview' => "What would Dream Land be without dreams? A nightmare! The Dream Spring, source of all dreams, has dried up, taking with it all the blissful dreams of Dream Land. It's up to Kirby, the bombastic blimp, To return happy naps to the inhabitants of Dream Land! Kirby's appetite for adventure is as big as ever as he eats his way through a feast of all-new enemies! In this adventure, he can also steal the abilities of the bad guys he scarfs down! With this new power, Kirby can perform 20 new tricks that will help him make his way through the nightmare infested Dream Land! Kirby's Adventure features brand new worlds to explore with the same fun action-packed feel that made Kirby's Dream Land for Gameboy a hit!", 'youtube' => 'https://www.youtube.com/watch?v=AWbKfgZPguc', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3694], 'genres' => [2], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 122, 'game_title' => 'Contra III: The Alien Wars', 'release_date' => '1992-04-06', 'platform' => 6, 'overview' => "Welcome to 2636, the year the Notorious One gets even, with an unprecedented alien onslaught orchestrated to push 16-bit technology and its commandos to their ultimate reaches.\r\n\r\nPlunge through a molten hot massacre on a high speed voyage to the guts of the archenemy alien. Scope out the side and top perspectives and backgrounds that do a 360 to engulf you in 3-D sensation.\r\n\r\nPick off solar slimedogs like the Mutant Megasquitos and the Psycho Cyclers while you scale over walls, swing from girders and ropes, hitch rides on a missile, whatever it takes. Sweat through six gut splitting stages, including the Battle of the Blazing Sky and the Mucho Grande Badlands.\r\nThe graphics are so real the explosions will nearly knock you off your feet. And the Boss Enemies are so gigantic, your screen can hardly hold them. You'll need to wrap both hands around artillery powerful enough to make today's weapons look like squirt guns. The Contra legacy is alive and dangerous!", 'youtube' => 'https://www.youtube.com/watch?v=P7tvMb19YlE', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E10+ - Everyone 10+', 'developers' => [4765], 'genres' => [1, 8], 'publishers' => [23], 'alternates' => ['Contra Spirits (JP)', '魂斗羅スピリッツ (JP)', 'Kontora Supirittsu (JP)', 'Super Probotector: Alien Rebels (EU)', 'Contra 3', 'Contra Spirits'], 'uids' => nil, 'hashes' => nil }, { 'id' => 123, 'game_title' => 'Metroid', 'release_date' => '1987-08-15', 'platform' => 7, 'overview' => "It's you against the evil Mother Brain in the thrilling battle of Metroid!\r\n\r\nYou’re inside the fortress planet Zebes. The planet of endless secret passageways where the Metroid are multiplying. Left alone the Metroid are harmless. But in the wrong hands they could destroy the galaxy. It’s up to you to prevent the Mother Brain that controls Zebes from using the Metroid for evil purposes. But that won’t be easy. You’ll have to use your spacesuit to absorb valuable energy for your search to gain the use of power items like the Ice Beam, Wave Beam, High Jump Boots and Varia. If you survive, it will be you and your acquired powers against the Mother Brain.\r\n\r\nWorth Noting: \r\nMetroid introduced nonlinear, side-scroller, maze-like, gameplay, in a platform, shooter. Metroid required players to discover permanent power-ups to progress further along; while backtracking through previously visited areas. The style is affectionately known as Metroid-vania' (Castlevania: Symphony of the Night being the second half to the term, mirrored the concept).\r\n\r\nMetroid also used a password system to resume progression of the game (Before the addition of battery backups and save files in console cartridges). Additionally the password system could be used for cheat codes: 'JUSTIN BAILEY ------ ------' (Just in Ballet) being famous, would remove Samus' power suit and start the player with many of the power-ups and fairly progressed through the game.\r\n\r\nCompleting the game in time and with enough power-ups revealed different endings. At the end Samus removes the helmet or power suit (depending) to a reveal a shocking suprise that endeared the character and broke new ground in gaming.", 'youtube' => 'D6jOGd0L1Hc', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6051], 'genres' => [1, 2, 8, 15], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 124, 'game_title' => 'Worms', 'release_date' => '1995-11-29', 'platform' => 1, 'overview' => "Worms is a turn-based strategy game. It features up to 4 teams of 4 worms, aiming to destroy the others on a generated terrain. Each worm has 100 hit points, and dies when his hit points fall to 0. Upon death, a worm explodes, causing damage to everyone around.\r\n\r\nGameplay is turn-based. Each turn, the player can control one specific worm from his team. The worm can crawl left and right or jump. However, there is a time limit to make a move; also, if the worm falls from a great height, it loses health and the turn ends immediately; and if a worm falls into water or offscreen, it dies. Each turn, a worm can also make a single attack: the player can aim up and down, choose a weapon and then fire it. After attacking, the turn ends. \r\n\r\nThere's a lot of weapons available - the standard ones as bazookas (which is affected by the (random) wind settings and gravity) and grenades. The others include a Fire Punch, dynamite, air strikes, and utilities such as ropes and girders.\r\n\r\nThere are 10 styles of terrain, ranging from forests and deserts to Candy land and the moon (complete with affected gravity). Shots leave craters in the ground, and complex tunnels can be formed.", 'youtube' => 'https://www.youtube.com/watch?v=08C-ttHHKFs', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8538], 'genres' => [1, 6], 'publishers' => [43], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 125, 'game_title' => 'Mega Man 5', 'release_date' => '1992-12-04', 'platform' => 7, 'overview' => "Protoman has gone berserk! Destroying half the city was not enough. Now, he has snatched Dr. Light and is holding him and the entire city hostage. Speeding to the rescue is Mega Man and his modified Mega Buster, but eight of Protoman's cybernetic soldiers plan to send Mega Man to the scrap heap for good! Feel the weight of the world on your shoulders as you battle Gravity Man! Chip away at the rock-like defenses of Stone Man and bring him crumbling down! Hit the surf and sail up against the tidal power of Wave Man! Help Mega Man defeat all eight of Protoman's robots and then get ready for the fight that pits brother against brother in the battle of the century!", 'youtube' => 'https://www.youtube.com/watch?v=eUWn6X105l4', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => ['Rock Man 5', 'Megaman 5'], 'uids' => nil, 'hashes' => nil }, { 'id' => 127, 'game_title' => 'Phantasy Star IV - The End of the Millennium', 'release_date' => '1995-02-01', 'platform' => 18, 'overview' => "Launch into the biggest RPG ever on Genesis! This is the explosive magic-and-monster packed FINALE to the incredible Phantasy Star saga. An ancient, hideous Dark Force stalks the Algol star system. You, a young hunter, are destined to become Motavia's greatest warrior and strike the death-blow that destroys evil FOREVER!", 'youtube' => 'https://www.youtube.com/watch?v=niVH43m0_2A', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [4], 'publishers' => [15], 'alternates' => ['Phantasy Star 4 - The End of The Millennium', 'Phantasy Star 4'], 'uids' => nil, 'hashes' => nil }, { 'id' => 128, 'game_title' => "Michael Jackson's Moonwalker", 'release_date' => '1990-08-24', 'platform' => 18, 'overview' => "\"Michael!\" Katy's voice rings out - you've found her! But more children are still lost! Can you stop the psycho mastermind Mr. Big and his goon squad before they kidnap all the kids? You can, if you're Michael Jackson! Moonwalk on muggers, lean on meanies, and pop the punks! Outfight, outjump, outdance! Move like only Michael can, to the beat of Smooth Criminal, Beat it, Billie Jean, and Bad! No bad guy can last through Michael's Star Magic! Punch down gangsters in Club 30. Rumble in the streets. Swing, spin, and kick past graveyard ghouls. Chill in the caverns, then sizzle 'em with ultra-tech weapons in Mr. Big's hideout. Experience the baddest video game ever. Defy physics with Michael's dancing! You never lose your cool. See it and be it - Michael Jackson's Moonwalker!", 'youtube' => 'Z3SpHXSpM98', 'players' => 2, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [9201], 'genres' => [2], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 129, 'game_title' => 'Sonic CD', 'release_date' => '1993-09-23', 'platform' => 21, 'overview' => "Sonic's gameplay remains similar to that of Sonic the Hedgehog but with the addition of the Spin Dash and the Super Peel Out, which lets him zoom into a quick speed from a standing point.The main innovation of this chapter in the Sonic series is the manner in which the player can travel to four different versions of each zone, each a different time period of the same location: Present, Past, Good Future and Bad Future. This is accomplished by speed posts scattered around the level, bearing the labels \"Past\", and \"Future\". After running through one of these posts, the player has to run at top speed for a few seconds without stopping, to travel into the respective time period. Because these teleports are relative, there are no \"Past\" signs in the Past, and no \"Future\" signs in the Future; that is, warping to the past in the future returns the player to the \"present\" time and vice versa.", 'youtube' => 'https://www.youtube.com/watch?v=5uN9_PPOM8Y', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [2], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 130, 'game_title' => 'Kid Icarus', 'release_date' => '1986-12-18', 'platform' => 7, 'overview' => "Far away in a kingdom called \"Angel Land,\" the evil goddess Medusa has stolen the Three Sacred Treasures and imprisoned the goddess of light, Palutena. As Kid Icarus, your mission is to find the treasures, destroy Medusa and rescue Palutena from the depths of the Palace in the Sky. To find the treasures you'll travel through ruins collecting weapons and storing power for use in combat against creatures of Medusa's army. Use your bow and arrow to ward off gatekeepers of the Underworld, Overworld and Skyworld as you strive towards your battle against Medusa. Will you survive to restore Palutena's light and return it to \"Angel Land?\" Only you know!", 'youtube' => 'https://www.youtube.com/watch?v=ad2TURb5qp4', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [2], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 131, 'game_title' => 'Donkey Kong Country', 'release_date' => '1994-11-21', 'platform' => 6, 'overview' => "Madness and Mayhem in this 3-D Gorilla Thriller!\r\n\r\nDonkey Kong is back with a new sidekick, Diddy Kong, in a crazy island adventure! Challenged by the crazed tribe of reptilian Kremlings, they endeavor to get back their stolen banana horde! Armed with lightning-quick moves, chest-pounding muscle and awesome aerial acrobatics, our duo is ready to face their cunning adversaries. With the help of Donkey Kong's quirky family and his wild animal mounts, they squabble and scamper their way through the unending monkey mayhem!", 'youtube' => 'SbHL8-XkXMA', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [6991], 'genres' => [1, 2, 15], 'publishers' => [3], 'alternates' => ['Super Donkey Kong'], 'uids' => nil, 'hashes' => nil }, { 'id' => 132, 'game_title' => 'Ecco the Dolphin', 'release_date' => '1992-07-29', 'platform' => 21, 'overview' => "The game begins with Ecco as he and his pod are swimming in their home bay. One podmate challenges him to see how high into the air he can jump. When he is in the air, a waterspout storm forms and sucks up all marine life in the bay except Ecco, leaving him alone in the bay. Upon leaving the bay to search for his pod, he contacts several dolphins from other pods, who tell him the entire sea is in chaos, and that all marine creatures had felt the storm. After talking to an orca, Ecco travels to the Arctic to find a blue whale named The Big Blue. The Big Blue tells him such storms had been occurring every 500 years and directs him to the Asterite, the oldest creature on Earth. He leaves the Arctic and travels to a deep cavern where he finds the Asterite. Although it has the power to aid him, one of its globes is missing, and needs it returned. However, this can only be achieved by traveling back in time using a machine built by the ancient Atlanteans.\r\nEcco travels to the sunken city of Atlantis, where he discovers the time machine and an ancient library. He learns the cause of the storm; it was a harvest of Earth's waters that was conducted every 500 years by an alien species known as the Vortex. The Vortex had lost their ability to make their own food, and so every 500 years, they would harvest from the waters of Earth. Learning this, he activates the time machine and travels 55 million years into Earth's past. Ecco locates the Asterite in the past but is immediately attacked by it. Forced into battle, he manages to dislodge a globe from it. This opens a time portal and he is sent back into the present. After receiving the globe, the Asterite grants him the power to turn his sonar into a deadly weapon against the Vortex, as well as the abilities to breathe underwater and to slowly regenerate lost health. The Asterite instructs him to use the time machine to travel back in time to the hour of the harvest. This time he manages to be sucked into the waterspout with his pod. Once inside the waterspout, Ecco makes his way towards the Vortex Queen, the leader of the Vortex race. Eventually, the Vortex Queen is destroyed and Ecco rescues his pod.", 'youtube' => 'PCPIJy0Rjiw', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6155], 'genres' => [2], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 133, 'game_title' => 'Lemmings', 'release_date' => '1991-02-14', 'platform' => 7, 'overview' => "Lemmings was one of the most popular computer games of its time, and several gaming magazines gave it some of their highest review scores at the time.\r\n\r\nThe behavior of the creatures in Lemmings is based on the supposed behavior of real lemmings, who by urban legend are believed to go on migrations en masse that eventually lead to disaster. The basic objective of the game is to guide lemmings through a number of obstacles to a designated exit. In order to save the required number of lemmings to win, one must determine how to assign a limited number of eight different skills to specific lemmings that allow the selected lemming to alter the landscape, to affect the behavior of other lemmings, or to clear obstacles in order to create a safe passage for the rest of the lemmings.", 'youtube' => 'gZwpbu37kCI', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2404], 'genres' => [5], 'publishers' => [43, 75, 135], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 135, 'game_title' => 'Castlevania', 'release_date' => '1987-05-01', 'platform' => 7, 'overview' => "If you think it's scary on the outside, wait'll you see the basement! You're in for the longest night of your life. Ghosts, goblins, demons, wolves, bats - creatures lurking around every corner. As you descend deeper and deeper, they get thicker and thicker. Better stick close to the cavern floor - it's your only chance of finding a weapon or two. You're gonna need 'em. Because when you finally meet the Count, you know he'll be going for the jugular. So keep your courage up and your stake sharp. And say your prayers!", 'youtube' => 'ENSDrPpFp-Y', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4765], 'genres' => [1, 2, 15], 'publishers' => [23], 'alternates' => ['Akumajou Dracula'], 'uids' => nil, 'hashes' => nil }, { 'id' => 136, 'game_title' => 'Super Mario World', 'release_date' => '1991-08-13', 'platform' => 6, 'overview' => "Mario’s off on his biggest adventure ever, and this time he’s brought along a friend. Yoshi the dinosaur teams up with Mario to battle Bowser, who has kidnapped Princess Toadstool once again. Guide Mario and Yoshi through nine peril-filled worlds to the final showdown in Bowser’s castle.\r\n\r\nUse Mario’s new powers and Yoshi’s voracious monster-gobbling appetite as you explore 96 levels filled with dangerous new monsters and traps. Climb mountains and cross rivers, and descend into subterranean depths. Destroy the seven Koopa castles and find keys to gain entrance to hidden levels. Discover more warps and thrilling bonus worlds than ever before!\r\n\r\nMario’s back, and this time he’s better than ever!", 'youtube' => 'https://www.youtube.com/watch?v=3RPYcfgKsNI', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [15], 'publishers' => [3], 'alternates' => ['Super Mario World- Super Mario Bros. 4 (Japan)'], 'uids' => nil, 'hashes' => nil }, { 'id' => 137, 'game_title' => "Super Mario World 2: Yoshi's Island", 'release_date' => '1995-10-04', 'platform' => 6, 'overview' => "Yoshi Returns to Save Baby Mario in this Sequel to Super Mario World!\r\nThe Evil Magikoopa, Kamek, is out to kidnap Baby Mario! In this sequel to Super Mario World, you play as Yoshi. Your goal is to successfully carry Baby Mario back to his parents in the Mushroom Kingdom while avoiding all of Kamek’s clever traps and evil minions. Enjoy the various backgrounds of the rich and vibrant locales of Yoshi’s Island as you race to complete your quest.\r\n\r\nIs Yoshi up to the momentous task at hand? Help him toss his eggs, manipulate unique objects and solve puzzling situations! When in doubt, don’t be afraid to try EVERYTHING!!\r\n\r\n* 16 megs of memory provide 6 worlds - each with 8 stages!\r\n* Morphmation delivers powerful special effects - scaling, rotating, and 360 degree scrolling.\r\n* Huge characters and even bigger bosses require quick thinking!\r\n* Battery back-up to save your progress.", 'youtube' => 'https://www.youtube.com/watch?v=Qv-6NzxgObw', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [15], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 138, 'game_title' => 'Gunstar Heroes', 'release_date' => '1993-09-09', 'platform' => 18, 'overview' => "Gunstar Heroes is a side scrolling shooter. The player has four weapons to choose from, and they can be combined in various pairs to create a total of 14 unique weapons. In addition to the weapons, the player can engage enemies in close quarters combat. It is possible to grab and toss enemies, perform sliding and jumping attacks and a long-range skid.\r\n\r\nUnlike most games in the genre, the player has a life total calculated in numbers. Death to a player requires multiple hits but just one death will issue the option to continue from the start of the level or to end the game. Players have unlimited continues.\r\n\r\nThe main highlight of the game are its boss encounters, which often feature large enemies made up of multiple sprites allowing for fluid movement.", 'youtube' => 'https://www.youtube.com/watch?v=Y5F7pzPQ24U', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9008], 'genres' => [8], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 139, 'game_title' => 'World of Illusion Starring Mickey Mouse and Donald Duck', 'release_date' => '1992-12-18', 'platform' => 18, 'overview' => "Alakazam! Here's classic Disney fun with your favorites, Mickey Mouse and Donald Duck! Transported into a world of wonder, Mickey and Donald must perform amazing feats of magic to defeat a crafty Sorcerer and find their way back home!", 'youtube' => 'https://www.youtube.com/watch?v=Buvds3POvhM', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [2, 15], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 140, 'game_title' => 'Super Mario Bros.', 'release_date' => '1985-09-13', 'platform' => 7, 'overview' => 'Do you have what it takes to save the Mushroom Princess? You’ll have to think fast and move even faster to complete this quest! The Mushroom Princess is being held captive by the evil Koopa tribe of turtles. It’s up to you to rescue her from the clutches of the Koopa King before time runs out. But it won’t be easy. To get to the Princess, you’ll have to climb mountains, cross seas, avoid bottomless pits, fight off turtle soldiers and a host of black magic traps that only a Koopa King can devise. It’s another non-stop adventure from the Super Mario Bros.!', 'youtube' => 'v74SVzuyOxA', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6042], 'genres' => [1, 15], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 141, 'game_title' => 'Paper Mario', 'release_date' => '2001-02-05', 'platform' => 3, 'overview' => "Mario pals around in an all-new action adventure! Mario's back in his first adventure since Super Mario 64, and this time, Bowser's bent on preventing a storybook ending. When Princess Peach is kidnapped, Mario plots to rescue the seven Star Spirits and rid the Mushroom Kingdom of Koopa's cruel cohorts. As he travels from the tropical jungles of Lavalava Island to the frosty heights of Shiver Mountain, he'll meet up with seven all-new companions... and he'll need help from each one or there'll be no happily ever after.", 'youtube' => 'WoGJd0k_FR8', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4248], 'genres' => [1, 4], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 142, 'game_title' => 'Sonic the Hedgehog 2', 'release_date' => '1992-11-21', 'platform' => 18, 'overview' => "Super Speed! Sonic's back and better than ever. He's a blur in blue! A blaze of action! With his new Super Spin Dash. And a new, fabulous friend, \"Tails\" the Fox. You won't believe it 'til you see it. And when you play, you won't stop. Super Play! Defy gravity in hair-raising loop-de-loops. Grab Power Sneakers and race like lightning through the mazes. Dash in a dizzying whirl across corkscrew speedway. Bounce like a pinball through the bumpers and springs of the amazing Zones. All at break-neck speed! Super Power! Sonic's attitude is can-do. The mad scientist Dr. Robotnik is planning a world takeover. Sonic gets tough in the fight to save his friends and squash Robotnik for good!", 'youtube' => 'https://www.youtube.com/watch?v=UUXFUqJOe38', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [7979], 'genres' => [1, 15], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 143, 'game_title' => 'Mega Man X', 'release_date' => '1994-01-21', 'platform' => 6, 'overview' => "Near the end of his life, Dr. Light succeeds in creating the first of a new series of robots which will change the world. Able to think and make decisions, this new robot holds great danger as well as great possibilities. Fearful of the possible consequences of unleashing his creation on the world, Dr. Light decides to seal him in a capsule and test his systems until they are totally reliable. The future will have to decide his fate...\r\n\r\nReleased from the capsule by Dr. Cain, \"X\" is born into the world of the future where the robot rebellions are a thing of the past. But when Dr. Cain tries to implement Dr. Light's designs into a new series of Reploids, something goes hideously wrong. Now the future lies on the brink of destruction and a new Mega Man must emerge to face Sigma and his forces before the human race is wiped from the planet!\r\n\r\n*12 Megs featuring 12 levels of action!\r\n*New Powers, New Abilities!\r\n*For 1 Player only.", 'youtube' => 'https://www.youtube.com/watch?v=F7Zxt7yZ2R4', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => ['Megaman X', 'Rockman X'], 'uids' => nil, 'hashes' => nil }, { 'id' => 144, 'game_title' => 'The Secret of Monkey Island', 'release_date' => '1990-01-31', 'platform' => 1, 'overview' => "The game begins on the Caribbean island of Mêlée, where a youth named Guybrush Threepwood wants to be a pirate. He seeks out the Pirate Leaders, who set him three challenges to prove himself a pirate: defeat Carla, the island's swordmaster in insult swordfighting, steal a statue from the Governor's mansion, and find buried treasure.\r\nAlong the way he meets several interesting characters, including Stan the used boat salesman, Meathook (a fellow with hooks on both hands), a prisoner named Otis, the three men of low moral fiber and, most significantly, the gorgeous Governor Elaine Marley. The ghost pirate LeChuck, however, has been in love with Elaine since his living days. While Guybrush is busy, LeChuck's ghost crew abduct her, taking her to Monkey Island. Guybrush gathers a crew (Carla, Meathook, and Otis), buys a boat, and sets out to find the mysterious island and free Elaine.\r\nWhen Guybrush finally reaches Monkey Island, he explores it and discovers a band of cannibals and a strange hermit named Herman Toothrot. After he helps the cannibals recover a lost voodoo ingredient (a magical root), they provide him with a seltzer bottle filled with \"voodoo root elixir\" that can destroy ghosts. However, when Guybrush goes after LeChuck, he is told that LeChuck went to Mêlée Island to marry Elaine.\r\nGuybrush returns to Mêlée and goes to the church to prevent the wedding. When he arrives at the church wedding, he realises that Elaine had her own plan to escape. Guybrush loses the elixir and LeChuck starts beating him, until they arrive at the ship emporium where he finds a bottle of root beer. Substituting root beer for the lost ghost-fighting elixir, he sprays LeChuck and the ghost pirate is destroyed. With LeChuck defeated, Guybrush and Elaine enjoy a romantic moment, watching fireworks.", 'youtube' => 'SZHBGVblNJA', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [5068], 'genres' => [2, 5], 'publishers' => [45], 'alternates' => ['The Secret of Monkey Island'], 'uids' => nil, 'hashes' => nil }, { 'id' => 146, 'game_title' => 'Half-Life 2', 'release_date' => '2004-11-16', 'platform' => 1, 'overview' => "At the start of the game, the G-Man speaks to Gordon Freeman in a hallucination-like vision as he pulls Gordon out of stasis and places him on a train going to City 17. When the train arrives, Gordon gets off and proceeds through the Combine's security checkpoints where he is detained by a civil protection officer. Once in an interrogation room, the officer reveals himself to be Freeman's former co-worker and colleague, Barney Calhoun who is working undercover, and helps Freeman to get to Dr. Isaac Kleiner's laboratory. After meeting Alyx Vance, Freeman is instructed by Kleiner to step into a makeshift teleporter so that he can be safely extracted to the anti-Combine resistance base Black Mesa East along with Alyx, headed by her father, Dr. Eli Vance. However, Kleiner's pet headcrab Lamarr disrupts the machine, and Freeman finds himself — after briefly appearing in several different locations — just outside Kleiner's lab. With the Combine now alerted to his presence, Freeman works his way through the drained canal system, avoiding enemy forces and using the help of human resistance fighters to safely arrive at Black Mesa East.", 'youtube' => 'UKA7JkV51Jw', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9289], 'genres' => [8], 'publishers' => [13], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 147, 'game_title' => 'LEGO Star Wars: The Video Game', 'release_date' => '2005-03-29', 'platform' => 1, 'overview' => "Gameplay in Lego Star Wars is geared towards family play, and as such does not feature a game over scenario. Given a specific set of characters in each scenario, based on a scene from each of the movies, up to two players can control them, using their different abilities. By walking up to another friendly character, the player can switch control over to that character, which is necessary for using some of their abilities to complete puzzles. \r\nStuds can be found by finding them, smashing or using the force on certain objects, or defeating enemies. Players will lose studs however if their character is destroyed (as opposed to losing lives). These studs can be spent on unlocking new characters for Free Play mode. Certain segments of the game feature players controlling spaceships flying on a flat plane. There are also several minikit canisters hidden throughout each level that, when collected, come together to form a vehicle. Completing certain requirements, such as collecting enough studs in a level, earns Golden Bricks that can be traded for cheats.\r\n\r\nWhen the player first starts the game, he/she must first complete Chapter I of The Phantom Menace. However, once that chapter is completed, the player may choose to play levels from the other two movies, able to play any unlocked levels in their desired order. Completing all the game's levels with full stud bars will unlock an additional chapter based on the opening scene of A New Hope.", 'youtube' => 'QwN2j_WJM-g', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8995], 'genres' => [1], 'publishers' => [25], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 148, 'game_title' => 'Hitman: Codename 47', 'release_date' => '2000-11-19', 'platform' => 1, 'overview' => 'The story centers around Agent 47, a bald test subject branded with a barcode tattooed on the back of his head, who is rigorously trained in methods of murder. Upon escaping from a test facility, 47 is hired by the Agency, a European contract killing organization. His mission takes him to several locations—Hong Kong, Colombia, Hungary, and the Netherlands—to assassinate wealthy and decadent criminals.', 'youtube' => 'https://www.youtube.com/watch?v=C8dtYOFPX-g', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4320], 'genres' => [1, 8, 16], 'publishers' => [26], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 149, 'game_title' => 'World of Warcraft', 'release_date' => '2004-11-23', 'platform' => 1, 'overview' => "World of Warcraft, often referred to as WoW, is a massively multiplayer online role-playing game (MMORPG) by Blizzard Entertainment, a subsidiary of Activision Blizzard. It is the fourth released game set in the fantasy Warcraft universe, which was first introduced by Warcraft: Orcs & Humans in 1994. World of Warcraft takes place within the Warcraft world of Azeroth, approximately four years after the events at the conclusion of Blizzard's previous Warcraft release, Warcraft III: The Frozen Throne.\r\n\r\nAs with other MMORPGs, players control a character avatar within a game world in third- or first-person view, exploring the landscape, fighting various monsters, completing quests, and interacting with non-player characters (NPCs) or other players. Also similar to other MMORPGs, World of Warcraft requires the player to pay for a subscription, either by buying prepaid game cards for a selected amount of playing time, or by using a credit or debit card to pay on a regular basis.", 'youtube' => 'dYK_Gqyf48Y', 'players' => 4, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [1203], 'genres' => [4, 14], 'publishers' => [47], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 151, 'game_title' => 'StarCraft II: Wings of Liberty', 'release_date' => '2010-07-27', 'platform' => 1, 'overview' => 'Set in the 26th century in a distant part of the Milky Way galaxy, the game revolves around three species: the Terrans, human exiles from Earth; the Zerg, a race of insectoid genetic assimilators; and the Protoss, a species with vast psionic power. Wings of Liberty focuses on the Terrans, while the expansions Heart of the Swarm and Legacy of the Void will focus on the Zerg and Protoss, respectively. The game is set four years after the events of StarCraft: Brood War, and follows the exploits of Jim Raynor as he leads an insurgent group against the autocratic Terran Dominion. The game includes both new and returning characters and locations from the original game.', 'youtube' => 'https://www.youtube.com/watch?v=FIaEugKWF_E', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1203], 'genres' => [6], 'publishers' => [47], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 152, 'game_title' => 'Call of Duty: Modern Warfare 2', 'release_date' => '2009-11-10', 'platform' => 1, 'overview' => "Modern Warfare 2, the much awaited game of the year can be played in single order or in multiple player mode as it's all up to you. During the single player campaign you can control five different characters from a first person perspective and this is what makes the player more excited to play. Check out the following different characters of the game play of Modern Warfare2:\r\n\r\nSergeant Gary Sanderson (Roach) - He is a member of a multinational and elite commando unit called Task Force 141.\r\n\r\nPrivate First Class Josepha Allen (Ranger) - This is the character that is staged in Afghanistan but who works undercover for the CIA in Russia under the name of Alexei Borodini.\r\n\r\nPrivate James Ramirez (Officer of the Ranger Regiment) - He is the first battalion's 75th Ranger Regiment in United States and is an important character that serves in defending the eastern coast of United States from Russian invasion.\r\n\r\nJohn Mac Travis (Soap) - He is an important character in the final three missions of the game play. He also assumes the role of the International Space Station Astronaut.\r\n\r\nThe Plot of the Game:\r\n\r\nThis game starts of in Afghanistan where First class Joseph Allen assists in taking the city from the insurgents. General Shepherd is impressed by Allen's combat abilities and recruits him in the task force 141 which is a multi National Counter Terrorists unit which runs under Shepherds commands. In the meantime, Roach and Soap who are both dominant characters according to the games scale, are taken to a mountain of the Tian Shan to infiltrate an airbase in Kazakhstan.\r\n\r\nAllen is then sent off on an under cover mission to Russia and he works under the CIA and goes under the name of Alexei Borodin. At the Zakhaev international Airport in Moscow, Allen joins Makarov in a massacre of civilians and as the story unfolds it reveals that Marakov was aware of the true identity of Allen and wanted to expose him so that the Russian police would believe that America was responsible for all the killing and the terrorist attacks. As the Russians are to believe the Americans are responsible for the massacre killing, they are angered and ready to retaliate with a massive surprise attack on America.\r\n\r\nIn this sequel of the Call of Duty game play, the non-playable characters play a dominate role. Soap returns as an NPC and serves as the superior officer and mentor to Roach. The other important character is the mysterious Simon Ghost Riley who wears a mask to conceal his face which is actually a skull print Balaclava.", 'youtube' => 'XWIJTydRLt8?hd=1', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4187], 'genres' => [8], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 153, 'game_title' => 'StarCraft', 'release_date' => '1998-03-31', 'platform' => 1, 'overview' => 'Set in the 26th century, the game revolves around three species fighting for dominance in a distant part of the Milky Way galaxy: the Terrans, humans exiled from Earth skilled at adapting to any situation; the Zerg, a race of insectoids in pursuit of genetic perfection obsessed with assimilating other races; and the Protoss, a humanoid species with advanced technology and psionic abilities attempting to preserve their civilization and strict philosophical way of living from the Zerg.', 'youtube' => 'H4Z6Rmbtk1k', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1203], 'genres' => [6], 'publishers' => [47], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 154, 'game_title' => 'Borderlands', 'release_date' => '2009-10-26', 'platform' => 1, 'overview' => 'Borderlands includes character-building elements found in role-playing games, leading to Gearbox calling the game a "role-playing shooter". At the start of the game, players select one of four characters, each with a unique special skill and with proficiencies with certain weapons. The four characters are: Roland the Soldier, Mordecai the Hunter, Lilith the Siren, and Brick (a Berserker) "as himself". From then on, players take on quests assigned through non-player characters or from bounty boards, each typically rewarding the player with experience points, money, and sometimes a reward item. Players earn experience by killing foes and completing in-game challenges (such as getting a certain number of kills using a specific type of weapon). As they gain levels from experience growth, players can then allocate skill points into a skill tree that features three distinct specializations of the base character; for example, Mordecai can become specialized in sniping, gunslinging with revolvers, or using his pet Bloodwing to assist in kills and health boosting. Players can distribute points among any of the specializations, and can also spend a small amount of in-game money to redistribute their skill points.', 'youtube' => 'O3iEuTuKvdU?hd=1', 'players' => 4, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [3423], 'genres' => [4, 8], 'publishers' => [8], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 156, 'game_title' => "Tom Clancy's H.A.W.X", 'release_date' => '2009-03-03', 'platform' => 1, 'overview' => "The story of the game takes place during the time of Tom Clancy's Ghost Recon Advanced Warfighter. H.A.W.X is set in the near future where private military companies have essentially replaced government-run military in many countries. The player is placed in the shoes of David Crenshaw — an ex-military elite pilot who was recruited by one of these corporations to work for them as one of their pilots, fighting whomever and whenever he is told to. Crenshaw later returns to the US Air Force together with his team, trying to prevent a full scale terrorist attack on the United States which was initiated by this military company.", 'youtube' => 'https://www.youtube.com/watch?v=-sx5l9cScOA', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9150], 'genres' => [1, 8, 19], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 157, 'game_title' => "Disney's Aladdin", 'release_date' => '1993-11-26', 'platform' => 18, 'overview' => "Hang onto your carpet for ACTION and FUN! Aladdin slashes his shining scimitar to fight through Agrabah, escape the Sultan's dungeon, survive the fiery Cave of Wonders, snatch the Genie's Lamp and save Princess Jasmine from the evil Jafar! All-new technology creates animation so smooth, it's like watching a real animated film. Aladdin battles thieves and desert warriors, and barely dodges danger on his high-speed carpet. Survive Jafar's troops for a dash through special bonus rounds. Hilarious! Palace Guards drop their drawers and camels spit dirt wads. Aladdin ping-pongs like a pinball INSIDE the Genie's Lamp!", 'youtube' => 'https://www.youtube.com/watch?v=EyZ8kP_kOpw', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2383], 'genres' => [1, 15], 'publishers' => [48], 'alternates' => ['Aladdin'], 'uids' => nil, 'hashes' => nil }, { 'id' => 158, 'game_title' => 'Portal', 'release_date' => '2007-10-09', 'platform' => 1, 'overview' => "Portalâ„¢ is a new single player game from Valve. Set in the mysterious Aperture Science Laboratories, Portal has been called one of the most innovative new games on the horizon and will offer gamers hours of unique gameplay.\r\n\r\nThe game is designed to change the way players approach, manipulate, and surmise the possibilities in a given environment; similar to how Half-Life® 2's Gravity Gun innovated new ways to leverage an object in any given situation.\r\n\r\nPlayers must solve physical puzzles and challenges by opening portals to maneuvering objects, and themselves, through space.", 'youtube' => 'TluRVBhmf8w', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9289], 'genres' => [5], 'publishers' => [13], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 159, 'game_title' => 'Battlefield: Bad Company 2', 'release_date' => '2010-03-02', 'platform' => 1, 'overview' => "In Battlefield: Bad Company 2, the Bad Company crew again find themselves in the heart of the action, where they must use every weapon and vehicle at their disposal to survive. The action unfolds with unprecedented intensity, introducing a level of fervor to vehicular warfare never before experienced in a modern warfare action game.\r\nThe 'B' company fight their way through snowy mountaintops, dense jungles and dusty villages. With a heavy arsenal of deadly weapons and a slew of vehicles to aid them, the crew set off on their mission and they are ready to blow up, shoot down, blast through, wipe out and utterly destroy anything that gets in their way. Total destruction is the name of the game -- either online or offline, enemies will soon learn there is nowhere to hide.", 'youtube' => 'DLYdoodBh5w?hd=1', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2328], 'genres' => [1, 8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 160, 'game_title' => 'GoldenEye 007', 'release_date' => '1997-08-25', 'platform' => 3, 'overview' => "You are Bond, James Bond.\r\n\r\nYou are assigned to covert operations connected with the GoldenEye weapons satellite. M will brief you on your mission and objectives from London. Q Branch will support your efforts with a plentiful supply of weapons and gadgets. Moneypenny offers you light-hearted best wishes and you’re off!\r\n\r\nYour mission begins in the heavily guarded chemical warfare facility at the Byelomorye Dam in the USSR. Look and shoot in any direction as you navigate 12 interactive 3-D environments. Use stealth and force as you see fit in matters of international security. Consider the military personnel expendable. You are licensed to kill!\r\n\r\n* Exciting 3-D environments.\r\n* Highly intelligent enemies!\r\n* Numerous Q gadgets and weapons!\r\n* Battery-backed memory saves game progress!", 'youtube' => 'VweKfwOnge0', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6991], 'genres' => [1, 2, 8, 16], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 161, 'game_title' => 'The Legend of Zelda: Ocarina of Time', 'release_date' => '1998-11-23', 'platform' => 3, 'overview' => "Ganondorf, the evil King of Thieves, is on the move, threatening the peaceful land of Hyrule. He is determined to steal his way into the legendary Sacred Realm in hopes of harnessing the power of the mythical Triforce. As the young hero Link, it is your destiny to thwart Ganondorf’s evil schemes. Navi, your guardian fairy, will guide you as you venture through the many regions of Hyrule, from the volcanic caves of Death Mountain to the treacherous waters of Zora’s Domain. Before you complete this epic quest, you’ll delve into deadly dungeons, collect weapons of great power and learn the spells you need to conquer the most irresistible force of all-time.\r\n\r\n• The immersive storyline and environments draw players into an amazing 3D world.\r\n• Time travel allows you to play as Link in different stages of his life.\r\n• New gameplay features include a unique targeting system and 1st and 3rd person perspectives.\r\n• Up to three games can be saved simultaneously to memory!", 'youtube' => 'gw1e2qFhGzY', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6043], 'genres' => [1, 2, 4, 5, 15], 'publishers' => [3], 'alternates' => ['Zelda No Densetsu Toki No Ocarina', 'Legend of Zelda, The - Ocarina of Time'], 'uids' => nil, 'hashes' => nil }, { 'id' => 162, 'game_title' => 'Banjo-Kazooie', 'release_date' => '1998-06-29', 'platform' => 3, 'overview' => "Action and Puzzles and Bears. Oh My!\r\n\r\nTrouble brews when Gruntilda the witch captures the unbearably beautiful cub, Tooty. But before the grisly hag can steal the bear’s good looks, big brother Banjo and his fine-feathered friend, Kazooie, join forces to stop her. Combining their 24 moves and special powers, Banjo and Kazooie will fend off armies of beasts. Bear and bird must hunt down the 100 puzzle pieces and 900 musical notes that will ultimately lead them to Gruntilda. However, miles of swamp, desert and snow and one bear of an adventure stand in their way.\r\n\r\n• Soar over islands to scout out buried treasure.\r\n• Brave past whirling blades in the belly of a mechanical shark.\r\n• With some voodoo magic, transform into different creatures to gain special powers.\r\n• Solve the puzzles of the ancients to unearth the cursed labyrinths.", 'youtube' => '3wiv-mQPl5M', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6991], 'genres' => [1, 2, 15], 'publishers' => [3], 'alternates' => ['Banjo to Kazooie no Daiboken (JP)'], 'uids' => nil, 'hashes' => nil }, { 'id' => 163, 'game_title' => 'Paradise', 'release_date' => '2006-04-21', 'platform' => 1, 'overview' => "# Paradise PC From the creator of the award-wining series Syberia comes Benoit Sokal s fascinating new work, Paradise. Sokal s latest adventure game masterpiece is set in four different worlds in the heart of darkest Africa. From the arid lands of Madargane to the dense jungle of the Maurane river, the world is both primitive and contemporary. Fraught with political turmoil, the lush landscapes are beautiful and dangerous.You play Ann Smith, a young woman suffering from amnesia struggling to make her way home and avoid the conflict surrounding her. To discover her true identity, she must escort a strange black leopard back to the land where it was born. Follow Ann through her journey as she finds clues to her identity and unravels the truth behind her mysterious past. A benchmark in art direction: Benoit Sokal, creator of the award-winning Syberia series contributes his unique vision in 4 visually dazzling worlds with over 360 backgrounds and Rembrandt-style lighting.\r\n# Unique Storyline: Ann Smith, estranged daughter of an African dictator, loses her identity and must journey through uncharted Africa to unravel her past and the mysterious existence of her leopard companion.\r\n# Unique Setting: First Adventure game to feature landscapes of Africa as a backdrop.\r\n# Play as the leopard: When day turns to night, players become the leopard and move in real time, climbing trees, leaping boundaries and frightening humans. This option adds a real-time element to the traditional point and click gameplay.\r\n# Puzzle solutions are seamlessly embedded into the story: For example, players must find a way to speak with the well-guarded prince, so they must pose as one of his wives to gain access (no gadgets or levers to pull).", 'youtube' => 'https://www.youtube.com/watch?v=lOTd1PWNMzU', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9601], 'genres' => [2], 'publishers' => [7, 2212], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 164, 'game_title' => 'Metro 2033', 'release_date' => '2010-03-16', 'platform' => 1, 'overview' => "Set in the shattered subway of a post apocalyptic Moscow, Metro 2033 is a story of intensive underground survival where the fate of mankind rests in your hands. In 2013 the world was devastated by an apocalyptic event, annihilating almost all mankind and turning the earth's surface into a poisonous wasteland. A handful of survivors took refuge in the depths of the Moscow underground, and human civilization entered a new Dark Age. The year is 2033. An entire generation has been born and raised underground, and their besieged Metro Station-Cities struggle for survival, with each other, and the mutant horrors that await outside. You are Artyom, born in the last days before the fire, but raised Underground. Having never ventured beyond your Metro Station-City limits, one fateful event sparks a desperate mission to the heart of the Metro system, to warn the remnants of mankind of a terrible impending threat. Your journey takes you from the forgotten catacombs beneath the subway to the desolate wastelands above, where your actions will determine the fate of mankind.", 'youtube' => 'Xc2hhef-Nzo', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [90], 'genres' => [1, 8], 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 165, 'game_title' => 'Dynasty Warriors 6', 'release_date' => '2008-02-19', 'platform' => 15, 'overview' => 'Dynasty Warriors 6 (真・三國無åŒï¼• Shin Sangoku MusÅu 5?) is a hack and slash video game set in Ancient China, during a period called Three Kingdoms (around 200AD). This game is the sixth official installment in the Dynasty Warriors series, developed by Omega Force and published by Koei. The game was released on November 11, 2007 in Japan; the North American release was February 19, 2008 while the Europe release date was March 7, 2008. A version of the game was bundled with the 40GB PlayStation 3 in Japan.[8] Dynasty Warriors 6 was also released for Windows in July 2008.[9] A version for PlayStation 2 was released on October and November 2008 in Japan and North America respectively. An expansion, titled Dynasty Warriors 6: Empires was unveiled at the 2008 Tokyo Game Show[10] and released on May 2009.', 'youtube' => 'QSYchTMF8Go', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6242], 'genres' => [1], 'publishers' => [50], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 166, 'game_title' => 'Mario Kart: Double Dash!!', 'release_date' => '2003-11-17', 'platform' => 2, 'overview' => 'The Mushroom Kingdom just got a whole lot more hectic as Mario and friends double up for furious kart racing. This time around, each kart holds two racers that can switch places at any time, so choose from a huge cast of favorites and pair them up any way you see fit. The character in front handles the driving duties, while the character in the rear doles out damage with six normal items and eight special items that only specific characters can use. Get ready for some intense multiplayer mayhem with your favorite characters, including Mario, Luigi, Donkey Kong, Peach, Bowser, and Koopa.', 'youtube' => 'CRbidBwajBc', 'players' => 4, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [1, 7, 11], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 167, 'game_title' => 'Mario Party 4', 'release_date' => '2002-10-21', 'platform' => 2, 'overview' => "Toad, Koopa, and other party-planning pranksters have hidden birthday presents for their closest friends inside the Party Cube. To win the presents, Mario, Yoshi, Peach, and other Mushroom Kingdom favorites will have to plunge into a circus of minigame trickery. As always, keep an eye out for Bowser and his trouble-making goons. Even Whomp and Thwomp have rockin' surprises for you in their Extra Room. Packed with surprises, wild multiplayer action, and zany challenges, Mario Party 4 is your ticket to a good time.", 'youtube' => 'Yjs04Woae98', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3923], 'genres' => [1, 5, 11], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 168, 'game_title' => 'Mario Party 8', 'release_date' => '2008-05-29', 'platform' => 9, 'overview' => 'All new features/boards! Mario Party for Wii also includes dozens of new mini-games, six new party boards and many new game modes. In a series first, players can transform their characters into many forms, such as player-smashing boulders and coin-sucking vampires. Mario Party Wii includes "extra large" mini games like Star Carnival Bowling and Table Menace. One to four players can play Mario Party, each with a Wii Remote.', 'youtube' => 'https://www.youtube.com/watch?v=oHfCG0UrezI', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3923], 'genres' => [5], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 169, 'game_title' => 'Mario Kart Wii', 'release_date' => '2008-04-27', 'platform' => 9, 'overview' => 'Mario and friends once again jump into the seat of their go-kart machines for the first Wii installment of this popular franchise. New features this year are an online racing mode, new motorbike vehicle types, a special balancing system for new and veteran players, and (in its initial release) a special Mario Kart wheel packaged with the game.', 'youtube' => 'nWybPOrwzdY', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [1, 7], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 170, 'game_title' => 'New Super Mario Bros. Wii', 'release_date' => '2009-11-15', 'platform' => 9, 'overview' => "Run and jump to your way to fun with Mario & friends!\r\n\r\n- Play together with up to 4 friends or family members\r\n\r\n- Rediscover legendary 2D gameplay loved by millions\r\n\r\n- Fun, simple controls—just like classic Mario games\r\n\r\nDevelopers at Nintendo have dreamed of creating a simultaneous multiplayer Super Mario Bros. game for decades. The Wii console finally makes that dream come true for everyone. Now players can navigate the side-scrolling worlds alone as before or invite up to three others to join them at the same time on the same level at any point in the game for competitive and cooperative multiplayer fun. With the multiplayer mode, the newest installment of the most popular video game franchise is designed to bring yet another type of family entertainment into living rooms and engage groups of friends in fast-paced Super Mario Bros. fun.\r\n\r\n- New Super Mario Bros. Wii offers a combination of cooperation and competition. Players can pick each other up to save them from danger or toss them into it.\r\n\r\n- Mario, Luigi and two Toads are all playable characters, while many others from the Mushroom Kingdom make appearances throughout the game. Players can even ride different Yoshi characters and use their tongues to swallow enemies, items and even balls of fire.\r\n\r\n- In some areas, players use the motion abilities of the Wii Remoteâ„¢ controller. The first player to reach a seesaw might make it tilt to help his or her character reach a higher platform – or might make it tilt incorrectly just to mess with other players.\r\n\r\n- New items include the propeller suit, which will shoot players high into the sky with just a shake of the Wii Remote, and Mario’s new ability to transform into Penguin Mario.\r\n\r\n- At the end of each stage during the coin battle multiplayer mode, players are ranked based on the number of coins they have collected.", 'youtube' => 'ht8r30Vk9P0', 'players' => 4, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [1, 2, 15], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 171, 'game_title' => 'Super Mario Bros. 2', 'release_date' => '1988-10-09', 'platform' => 7, 'overview' => 'Mario’s back! Bigger and badder than ever before! This time it’s a fierce action-packed battle to free the land of Subcon from the curse of the evil Wart. It’s up to you, along with Mario, Luigi, Toad and the Princess, to fight your way through bizarre multi-level worlds and find him! This time you’ve got a brand new kind of power - plucking power - and now anything you find can be a weapon. But beware! You’ve never seen creatures like these! Shyguys and Tweeters! Ninji and Beezos! And you’ve never had an adventure like this! Only cunning and speed can save you now…', 'youtube' => 'mMFdeYwPEQQ', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6055], 'genres' => [1, 2, 15], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 172, 'game_title' => 'Metroid Prime', 'release_date' => '2002-11-17', 'platform' => 2, 'overview' => "Ten years ago, beneath the surface of Planet Zebes, the mercenaries known as \"Space Pirates\" were defeated by interstellar bounty hunter Samus Aran. Descending to the very core of the pirate stronghold, Samus exterminated the energy based parasites called \"Metroids\" and defeated Mother Brain, the leader of the pirate hoarde.\r\n\r\nBut the Space Pirates were far from finished. Several pirate research vessels were orbiting Zebes when Samus fought on the surface below.\r\n\r\nAfter the fall of Mother Brain, the ships escaped, with the hope of finding enough resources to rebuild their forces and take their revenge.\r\n\r\nAfter discovering a possible pirate colony on planet Talon IV, Samus has once again prepared for war, hoping to end the Pirate threat forever.", 'youtube' => 'https://www.youtube.com/watch?v=kLfkkSD15zQ', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7160], 'genres' => [1, 2, 8, 15], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 173, 'game_title' => 'Perfect Dark', 'release_date' => '2000-05-22', 'platform' => 3, 'overview' => "Step into the Dark... As Carrington Institute's most promising new Agent, Joanna Dark must uncover the truth behind the dataDyne Corporation's recent technological breakthroughs - breakthroughs which could have serious consequences for mankind.", 'youtube' => 'N6VTzPU-yiE', 'players' => 4, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [6991], 'genres' => [1, 8, 16], 'publishers' => [51], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 174, 'game_title' => 'The Legend of Zelda: The Wind Waker', 'release_date' => '2003-03-24', 'platform' => 2, 'overview' => "The game is set on a group of islands in a vast sea—a first for the series. The player controls Link, the protagonist of the Zelda series. He struggles against his nemesis, Ganondorf, for control of a sacred relic known as the Triforce. Link spends a large portion of the game sailing, traveling between islands, and traversing through dungeons and temples to gain the power necessary to defeat Ganondorf. He also spends time trying to find his little sister.\r\nThe Wind Waker follows in the footsteps of Ocarina of Time and its sequel Majora's Mask, retaining the basic gameplay and control system from the two Nintendo 64 titles. A heavy emphasis is placed on using and controlling wind with a baton called the Wind Waker, which aids sailing and floating in air. Controversial during development for its use of cel shading graphics and younger Link character, The Wind Waker received acclaim on release and is one of the Nintendo GameCube's most popular games.\r\n\r\n* The \"Tingle Tuner\" is a special item allowing a second player to control the character Tingle if the system is connected to a Game Boy Advance by a link cable.", 'youtube' => '', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [6043], 'genres' => [1, 2, 4, 5, 15], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 175, 'game_title' => "The Legend of Zelda: Majora's Mask", 'release_date' => '2000-10-26', 'platform' => 3, 'overview' => "Link’s all-new epic adventure lands him in the mystical world of Termina, where ever-present clocks count down the hours until a menacing moon falls from the sky above. When his horse and Ocarina are stolen by a strange, masked figure, Link embarks on an urgent quest to solve the mystery of the moon, save the world from destruction, and find his way back to the peaceful land of Hyrule!\r\n\r\n* Link transforms before your eyes--Over 20 magical masks give Link powers and abilities he’s never had before! Watch him transform into a hapless Deku child, a mighty Goron hero and a legendary Zora guitarist.\r\n* Race against time--Characters and events flow with the hours of the day. Set your own schedule and even alter time itself in a race to stop the moon and save the world!\r\n* Panoramic environments! Powered-up action battles! Fully interactive characters and events! Experience gorgeous rendered landscapes, swarms of attacking enemies and a deep, engrossing world of wonders with the power of the N64 Expansion Pak.\r\n\r\nAlso Available\r\nThe Legend of Zelda: Majora's Mask Collector's Edition", 'youtube' => 'iWkRpOBPW8A', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6043], 'genres' => [1, 2, 4], 'publishers' => [3], 'alternates' => ['Zelda No Densetsu Mujura No Kamen', "Legend of Zelda, The - Majora's Mask"], 'uids' => nil, 'hashes' => nil }, { 'id' => 176, 'game_title' => 'Banjo-Tooie', 'release_date' => '2000-11-20', 'platform' => 3, 'overview' => "Grunty returns—and that's bad news for Banjo and Kazooie! In this all-new adventure, combine everything you learned in the award-winning prequel, Banjo-Kazooie, with dozens of brand-new moves and abilities. Explore eight original worlds—like a monstrous factory and a dilapidated amusement park. Solve incredible puzzles that link those worlds together—sometimes you'll have to complete tasks in several worlds to solve a single puzzle!\r\n\r\n• Divide and conquer! The bear and bird are back, and this time, they can split up and work alone.\r\n• Play as Mumbo! Now you'll get to take control of the bone-headed shaman himself.\r\n• Meet Humba Wumba! She'll transform Banjo into a number of objects, such as a walkin', talkin' statue or a tightie whitie shootin' washer.\r\n• Four-player mini-games! Play over a dozen mini-games, including five different shootout modes.", 'youtube' => 'dU6wLNrii9Y', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6991], 'genres' => [1, 2, 5, 15], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 178, 'game_title' => 'Diddy Kong Racing', 'release_date' => '1997-11-21', 'platform' => 3, 'overview' => "Timber the Tiger's parents go on vacation and leave their son in charge of the island they live on, leaving him and his friends to race for fun. Their enjoyment is derailed when an evil, intergalactic, pig wizard named Wizpig arrives at peaceful Timber's Island and attempts to take over after he conquered his own planet's racetracks. He turns the four island's guardians: Tricky the Triceratops, Bubbler the Octopus, Bluey the Walrus and Smokey the Dragon into his henchmen. The only solution available to the island's inhabitants is to defeat Wizpig in an elaborate series of races that involves cars, hovercrafts, and airplanes. Drumstick, the best racer on the island, failed this challenge and was transformed into a frog by Wizpig's black magic. Timber recruits a team of 7 racers: Diddy Kong, the first recruit; Conker (Dixie Kong on DS), recruited by Diddy; Banjo (Tiny Kong on DS), also recruited by Diddy; Krunch, Diddy's enemy who follows after him; Tiptup, an inhabitant of Timber's island; Pipsy, another inhabitant of Timber's island; and Bumper, another inhabitant of Timber's island. They eventually complete all of Wizpig's challenges and confront Wizpig himself to a race and defeat him. Shortly afterwards, Wizpig leaves for his home planet, Future Fun Land. Fearing that Wizpig would again attempt to invade Timber's Island, the islanders travel to Future Fun Land for a second challenge. When Wizpig loses the second race, the rocket he rides on malfunctions and blasts him to a distant planet and peace returns to Timber Island for good.", 'youtube' => 'XXvzvNZYOjc', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6991], 'genres' => [2, 7], 'publishers' => [51], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 179, 'game_title' => 'Full Throttle', 'release_date' => '1995-04-30', 'platform' => 1, 'overview' => 'The story is set in a dystopian future where motorized vehicles are giving way to anti-gravitational hovercrafts. A hardened biker named Ben is the leader of a motorcycle gang called the Polecats. As his gang rides down Highway 9, they come across an expensive white hovercraft limousine. Ben, in the lead, unceremoniously drives over the limousine, crushing the hood ornament. Unknown to the gang, the limo belongs to Malcolm Corley, the CEO and founder of the last domestic motorcycle manufacturer in the country, Corley Motors. Intrigued and impressed, Corley demands his driver catch up to the gang.', 'youtube' => 'https://www.youtube.com/watch?v=qj_1s_X3I-0', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5068], 'genres' => [2, 5], 'publishers' => [25], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 180, 'game_title' => 'The Dig', 'release_date' => '1995-11-01', 'platform' => 1, 'overview' => "A DEEP SPACE ADVENTURE BY SEAN CLARK IN COLLABORATION WITH FILMMAKER STEVEN SPIELBERG\r\n\r\nAn asteroid the size of a small moon is on a crash course toward Earth, and only NASA veteran Boston Low has the expertise to stop it. Along for the ride are award-winning journalist Maggie Robbins and internationally renowned geologist Ludger Brink.\r\n\r\nOnce the wayward asteroid is nuked into a safe orbit, the trio conducts a routine examination of the rocky surface.\r\n\r\nWhat they uncover is anything but routine.\r\n\r\nLow, Brink and Robbins unwittingly trigger a mechanism that transforms the asteroid into a crystal-like spacecraft. The team is hurtled across the galaxy to a planet so desolate, Brink is moved to name it Cocytus, after the 9th circle of Hell in Dante’s inferno. The bleak landscape was obviously once home to a highly evolved civilization, with remnants of sophisticated architecture, advanced technology and an intricate network of underground tunnels.\r\n\r\nBut no Cocytans.\r\n\r\nWho were the original inhabitants of this once rich empire-turned-wasteland? What are those apparitions that mysteriously appear from time to time? Why have Low, Robbins, and Brink been brought to this place? And how can Low keep his team from unraveling in the face of such uncertainty? To return to Earth, they must dig for answers, both on the planet’s surface and deep within themselves.\r\n\r\nFrom the combined talents of LucasArts and legendary Steven Spielberg comes an epic adventure that plunges headlong into the very core of the unknown. And takes you with it.", 'youtube' => 'https://www.youtube.com/watch?v=jRMGxQCitRU', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5068], 'genres' => [2], 'publishers' => [25], 'alternates' => ['thedig'], 'uids' => nil, 'hashes' => nil }, { 'id' => 181, 'game_title' => 'Blood Bowl', 'release_date' => '2009-06-26', 'platform' => 1, 'overview' => 'Blood Bowl - the game of fantasy football. Based on the famous Warhammer fantasy world and American football, Blood Bowl is a combination of a classic strategy game and a sports game. It’s also an incredibly brutal game, where you lead your team through bonecrunching leagues to compete in the prestigious Blood Bowl Cup! Create your team from the 8 playable races: Humans, Orcs, Wood Elves, Dwarves, Skaven, Lizardmen, Chaos or Goblins and manage them as they gain experience through the many championships and tournaments taking place in the Old World.', 'youtube' => 'https://www.youtube.com/watch?v=t3xsSN7UEFI', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2005], 'genres' => [6], 'publishers' => [53], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 183, 'game_title' => 'Shining Force', 'release_date' => '1992-03-19', 'platform' => 18, 'overview' => "Shining Force is a turn-based tactical RPG. Battles take place in square grids, and each unit occupies 1 square. Each unit can move up to a fixed amount of squares along the battlefield, determined by its Move statistic. Depending on its location relative to enemies and to allies, a unit can also perform one action: attack, cast a spell, use an item, or search the area. Some commands, such as equipping or dropping items, don't count as actions. The order of turns is determined by the unit's agility score and a random seed.", 'youtube' => 'https://www.youtube.com/watch?v=pewTGCkt4qE', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [1421], 'genres' => [4], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 184, 'game_title' => 'Shining Force II', 'release_date' => '1994-10-19', 'platform' => 18, 'overview' => "Shining Force II is a tactical role-playing game. The player assumes the role of the Shining Force leader, Bowie. When not in combat, the player can explore towns and other locales, talk with people, and set the members and equipment of the army. Some towns have a headquarters where the player can inspect and talk with his allies. While roaming through town or moving throughout the world, one can find both visible and hidden treasures and interact with certain objects.\r\nEach ally unit is represented by a character with a background and personality. Some of these characters are hidden, requiring specific events to occur before they will join the force. Each ally unit also has a class, which defines the abilities for that unit. These abilities range from what type of weapons they can use to what kind of spells they can learn. Units can become stronger by fighting enemies and performing various actions which gives them experience points (EXP), which allow them to gain levels. Once a unit reaches level 20, that character has the ability to advance to more powerful class through promotion. Some characters have two different classes they may be promoted to, one of which is only accessible using a special hidden item.\r\nBattles take place on a square grid, and each unit occupies a single square. Battle is turn-based. Each turn, a character can move and perform one action: either attack, cast a spell, or use an item. Some commands, such as equipping or dropping an item during the turn, do not count as actions.\r\nThe battle is won if all enemies are defeated, or if the enemy commander is defeated. If Bowie is defeated in combat or withdraws, the battle is lost and the player is returned to the nearest town, where he can recover his allies and fight the same battle again.", 'youtube' => 'https://www.youtube.com/watch?v=zNXND3tgFfk', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [1421], 'genres' => [4], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 185, 'game_title' => 'Shining Force III', 'release_date' => '1998-08-12', 'platform' => 17, 'overview' => "Scenario 1, God Warrior of the Kingdom, features Synbios, a young general from the Republic of Aspinia. Aspinia was once a part of the Empire of Destonia, but seceded after a war of independence spearheaded by some of the more democratic-minded nobles. They opposed Emperor Domaric's totalitarian policies, which disenfranchised a large number of people, creating a huge disparity between the wealthy and the poor. Tensions remained between Aspinia and Destonia after the secession, marked by occasional border disputes.\r\n\r\nAs the game begins, Synbios is part of a military force representing Aspinia at a peace conference in the neutral city of Saraband. Due to manipulation by outside forces - later discovered to be connected with a religious cult known as the \"Bulzome Sect\" - full-scale war breaks out again between Aspinia and Destonia. The majority of the game's storyline covers this conflict as well as Synbios and his team's fight against the Bulzome sect. Throughout the game Synbios has periodic encounters with Medion, Destonia's youngest prince, who also recognizes the truth behind the war. Although on opposite sides of the war, the two work together to identify the real threat.", 'youtube' => 'https://www.youtube.com/watch?v=nYlGQONqczc', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1421], 'genres' => [4, 6], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 186, 'game_title' => 'Mass Effect', 'release_date' => '2007-11-20', 'platform' => 1, 'overview' => "Mass Effect is set in the year 2183 AD. Thirty-five years prior, humankind discovered a cache of technology on Mars, supposedly built by a technologically advanced but long-extinct race called the Protheans. Studying and adapting this technology, humanity has managed to break free of the solar system and has established numerous colonies and encountered various extraterrestrial species within the Milky Way galaxy. Utilizing alien artifacts known as Mass Relays, the various space-faring races are able to travel instantly across vast stretches of the galaxy. Within the game, humanity has formed the Human Systems Alliance, one of many independent bodies that make up the collective of \"Citadel space\".\r\nThe Human Systems Alliance is a rising power in the galactic stage. The only war they have participated in was the \"First Contact War\" in 2157. A human exploration expedition was activating dormant mass relays (which was a practice considered unsafe by citadel races). The turians attacked the small fleet and proceeded to capture the closest human world, Shanxi. The turians proceeded to starve out the remaining humans and occupy the planet. Facing starvation the human garrison surrendered to the Turian Hierarchy. One month later, the human Second Fleet responded by annihilating the turian fleet around Shanxi. In response the turians prepared for full scale war. The citadel council saw that humanity would either be annihilated or annexed by the turians and stepped in. The humans were then given an embassy in the Citadel Council.\r\nCitadel space, as a whole, is ruled by a body of government known as the Council, which is made up of members of the three prominent alien races: the asari, a race of mono-gendered aliens which closely resemble blue-skinned human females; the short-lived salarians; and the raptor-like turians. Other alien species seen in the game include the reptilian krogan, the four-eyed, humanoid batarians, the aquatic hanar, and the methodical and quadrupedal elcor, and the environmental-suited quarians and volus. Dozens of other aliens are asserted to exist throughout the galaxy, but are not seen or mentioned in the game.\r\nThe game takes place primarily in two locations: the prototype frigate SSV Normandy, and the Citadel, a gigantic, ancient space station purportedly built by the Protheans and which currently acts as the center of galactic civilization. Throughout the game, however, the player may navigate the Normandy to various planets, moons and other destinations.", 'youtube' => 'yqJuJTIus7U?rel=0&hd=1', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1086], 'genres' => [1, 4, 8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 187, 'game_title' => 'Mass Effect 2', 'release_date' => '2010-01-26', 'platform' => 1, 'overview' => 'After the events of the original game, Commander Shepard is killed in an ambush by a mysterious alien species called the Collectors. Shepard is revived two years after the attack by an enigmatic organization called Cerberus, and is tasked with finding out more about the Collectors and why they are abducting entire human colonies. Shepard must build a team in order to accomplish what seems to be a suicide mission.', 'youtube' => 'Y2O-0-fQOOs', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1086], 'genres' => [1, 8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 188, 'game_title' => 'Teenage Mutant Ninja Turtles IV: Turtles In Time', 'release_date' => '1992-08-01', 'platform' => 6, 'overview' => "Sunday evening. You're sitting around the sewer watching your main reported, April O'Neil do a live remote from the Statue of Liberty. Then it happens. A humungoso flying android screams out of the sky and rips Lady Liberty from her foundation, sending hundreds of freaked out tourists into the harbor below. \"No way!\" cries Raphael. \"Way,\" replies Donatello. And the crazy quantum chase is on!\r\nJourney through ten levels of enormous arcade graphics, the largest and craziest talking Turtles ever with eons of bodacious battlegrounds, from prehistoric to futuristic galaxies. To prepare for the toughest Shred-heads you've ever seen, try the Versus mode, a Turtle-on-Turtle combat arena that finally proves who's the mightiest mutant of all. Also test your slice-em-up speed in the Time Trials mode to find out how fast you can clear three courses.\r\nGet ready for the 3-D jab and toss that sends enemies flying right in your face. Mondo body slams and pizza power bonuses make you more Turtle than ever before. You better believe you're going to need it. Shredder's out for Turtle hide. And he's got all the time in the world to get it.", 'youtube' => 'https://www.youtube.com/watch?v=NVLkssVwRbY', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [4765], 'genres' => [1], 'publishers' => [23], 'alternates' => ['Teenage Mutant Ninja Turtles 4', 'Teenage Mutant Hero Turtles: Turtles in Time', 'TMNT IV Turtles In Time'], 'uids' => nil, 'hashes' => nil }, { 'id' => 189, 'game_title' => 'Mario Bros.', 'release_date' => '1986-06-01', 'platform' => 7, 'overview' => "Mario and Luigi are doing some underground plumbing when all sorts of weird creatures come flying out of the pipes. Turtles, crabs - even fighterflies - attack the helpless Mario Bros. It's up to you to kick, punch, and knock out these sewer pests before time runs out! But beware. Just when you think you got rid of them, they come back for more! Play against the computer, or with a friend - either way, this is one underground classic you'll want to play time and time again!", 'youtube' => 'https://www.youtube.com/watch?v=ly8DofqCuOs', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [1, 15], 'publishers' => [3], 'alternates' => ['Mario Bros. Classic'], 'uids' => nil, 'hashes' => nil }, { 'id' => 190, 'game_title' => 'Batman: Arkham Asylum', 'release_date' => '2009-09-15', 'platform' => 1, 'overview' => "The Dark Knight takes on his greatest challenge yet when he becomes trapped with all of his most dangerous villains inside the insane asylum of Gotham City—Arkham Asylum! Batman: Arkham Asylum exposes you to a unique, dark and atmospheric adventure that takes you to the depths of Gotham's psychiatric hospital for the criminally insane. With amazing graphics and a moody, immersive setting, Batman: Arkham Asylum offers diverse gameplay options that push the envelope for all action, adventure, and superhero games.\r\n\r\nSuper villains: Confront Gotham's most notorious lunatics, including The Joker, Harley Quinn, Bane, Poison Ivy, and Killer Croc.\r\n\r\nBatman's arsenal: Utilize Batman's detective skills and cutting-edge forensic tech to gather evidence and clues.\r\n\r\nSilent killer: Move in the shadows and strike fear amongst your enemies.\r\n\r\nMelee combat: Unleash brutal combos with the innovative FreeFlow combat system.", 'youtube' => 'https://www.youtube.com/watch?v=dErlfFt1mUc', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7288], 'genres' => [1, 2], 'publishers' => [26], 'alternates' => ['Batman Arkham Asylum GOTY Edition'], 'uids' => nil, 'hashes' => nil }, { 'id' => 191, 'game_title' => 'Red Dead Redemption', 'release_date' => '2010-05-18', 'platform' => 15, 'overview' => "From the official webpage:\r\n\r\n\"America, early 1900's. The era of the cowboy is coming to an end.\r\n\r\nWhen federal agents threaten his family, former outlaw John Marston is sent across the American frontier to help bring the rule of law. Experience intense gun battles, dramatic train robberies, bounty hunting and duels during a time of violent change.\r\n\r\nRed Dead Redemption is an epic battle for survival in a beautiful open world as John Marston struggles to bury his blood-stained past, one man at a time.\"", 'youtube' => 'https://www.youtube.com/watch?v=3gBctl1h_2o', 'players' => 4, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [7273], 'genres' => [1, 2, 8, 12], 'publishers' => [17], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 192, 'game_title' => 'Warhammer 40,000: Dawn of War - Soulstorm', 'release_date' => '2008-03-04', 'platform' => 1, 'overview' => "The Kaurava conflict began after a sudden appearance of a Warp Storm near Kaurava IV. The nine races were drawn to investigate the system with their own fleets and conflicting intentions. However, the Warp Storm wreaked havoc on their navigation interfaces, stranding them on the four planets and three moons of the system. The nine factions are then forced to battle between planets to ultimately conquer the planetary system and discover the reason for the warp storm.\r\n\r\nThe reason for the Warp Storm, as explained after the conquest of Chaos Forces, began with an ignorant Imperial Guardsman with latent psyker genes who was whispered to by the Chaos Gods, telling him to prepare a ritual. His actions unknowingly summoned the Alpha Legion to the Kaurava System, thus starting the conflict.", 'youtube' => 'https://www.youtube.com/watch?v=Uh9W8QIei8A', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7131], 'genres' => [6], 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 193, 'game_title' => 'Halo 3: ODST', 'release_date' => '2009-09-22', 'platform' => 15, 'overview' => 'A UNSC Orbital Drop Shock Trooper must locate his missing squad members in New Mombasa following a devastating slip space rupture caused by a Covenant cruiser.', 'youtube' => 'https://www.youtube.com/watch?v=oyZHajCu8GU', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1389], 'genres' => [1], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 194, 'game_title' => "Tom Clancy's Ghost Recon Advanced Warfighter 2", 'release_date' => '2007-03-06', 'platform' => 15, 'overview' => "Tom Clancy's Ghost Recon Advanced Warfighter 2 (GRAW 2) is a tactical shooter video game released for Xbox 360, Microsoft Windows, PlayStation 3 and PlayStation Portable. It is the sequel to Tom Clancy's Ghost Recon Advanced Warfighter.\r\n\r\nThe game takes place in 2014, immediately after the events of Tom Clancy's Ghost Recon Advanced Warfighter (GRAW), just south of the Mexico-United States border, and deals with the conflict between a Mexican rebel group, Mexican loyalists, and the U.S. Army for a time span of 72 hours. A wide array of location types are included, featuring mountains, small towns, urban environments, and a large hydro-electric dam just north of the border.", 'youtube' => 'https://www.youtube.com/watch?v=_nKkrtrOYO0', 'players' => 16, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7097, 9147], 'genres' => [1, 8], 'publishers' => [4566], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 195, 'game_title' => 'Marvel vs. Capcom: Clash of Super Heroes', 'release_date' => '1999-03-25', 'platform' => 16, 'overview' => 'The game takes place within the Marvel comic continuity, as Professor Charles Xavier calls out for heroes to stop him before he merges with the consciousness of Magneto and becomes the being known as Onslaught, the final boss. While the gameplay was typical of the Marvel vs. Capcom series, Marvel vs. Capcom was distinguishable by two features: the ability to summon assist characters, and the Duo Team Attack.', 'youtube' => 'https://www.youtube.com/watch?v=JN1Lgh-EC4A', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 196, 'game_title' => 'Metal Gear Solid', 'release_date' => '1998-10-21', 'platform' => 10, 'overview' => 'Metal Gear Solid follows Solid Snake, a soldier who infiltrates a nuclear weapons facility to neutralize the terrorist threat from FOXHOUND, a renegade special forces unit. Snake must liberate two hostages, the head of DARPA and the president of a major arms manufacturer, confront the terrorists, and stop them from launching a nuclear strike.', 'youtube' => 'lt2K45vwTM4', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4765], 'genres' => [1], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 197, 'game_title' => 'Warhammer Online: Age of Reckoning', 'release_date' => '2008-09-16', 'platform' => 1, 'overview' => "Warhammer Online: Age of Reckoning features Mythic's Realm versus Realm (RvR) combat system, originally developed in Dark Age of Camelot. This takes place within three different racial pairings: Dwarfs vs. Greenskins, Empire vs. Chaos, and High Elves vs. Dark Elves. Although there are only two races per pairing, players may travel to either of the other two pairings to help fight with their friends and allies. There are four types of RvR combat: Skirmishes (random world encounters), Battlefields (objective-driven battles in RvR-specific areas), Scenarios (instanced, point-based battles against the opposing faction), and Campaigns (invading enemy lands and capital cities). RvR contribution includes both Player vs. Player (PvP) combat and (to a lesser extent) Player vs. Environment (PvE) quests so that you can assist your realm in their victory, regardless of preferred play-style.", 'youtube' => '-68bXPgH9Dk', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5784], 'genres' => [4], 'publishers' => [35], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 198, 'game_title' => 'Classic NES Series: Zelda II: The Adventure of Link', 'release_date' => '2004-10-25', 'platform' => 5, 'overview' => "The Adventure of Link bears little resemblance to the first game in the series. The Adventure of Link features side-scrolling areas within a larger world map rather than the bird's eye view of the previous title. The game incorporates a strategic combat system and more RPG elements, including an experience points (EXP) system, magic spells, and more interaction with non-player characters (NPCs). Link has extra lives; no other game in the series includes this feature.", 'youtube' => 'https://www.youtube.com/watch?v=5NloyMdr2iY', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6043], 'genres' => [4], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 200, 'game_title' => 'Ikaruga', 'release_date' => '2002-09-05', 'platform' => 16, 'overview' => "Several years ago in the small island nation of Horai, the leader of the nation, Tenro Horai, discovered the Ubusunagami Okinokai—the Power of the Gods. This energy emanated from an object she dug up from deep underground and granted her unimaginable powers. Soon after, Tenro and her followers, who called themselves \"The Divine Ones\", began conquering nations one after another. \"The Chosen People\" carried out these conquests in \"the name of peace\".\r\n\r\nMeanwhile, a freedom federation called Tenkaku emerged to challenge Horai. Using fighter planes called Hitekkai, they fought with the hope of freeing the world from the grips of the Horai - but all their efforts were in vain. They were no match for the Horai and were eventually almost completely wiped out. Miraculously, however, one young man survived. His name was Shinra (森羅?).\r\nShot down near a remote village called Ikaruga, inhabited by elderly people who had been exiled by the Horai's conquests, Shinra was dragged from the wreckage and nursed back to health. Shinra regained his health and pledged to defeat the Horai, and the villagers entrusted him with a fighter plane that they had built themselves, called the Ikaruga.\r\n\r\nThe Ikaruga was no ordinary plane, designed by former engineering genius Amanai (天内?) with the help of Kazamori (風守?) and the village leaders. Hidden in a secret underground bunker and launched via the transportation device called the \"Sword of Acala\", it is the first fighter built that integrates both energy polarities, and is capable of successfully switching between the two.", 'youtube' => 'https://www.youtube.com/watch?v=yQwiY56IHwk', 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9008], 'genres' => [8], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 201, 'game_title' => 'Uncharted 2: Among Thieves', 'release_date' => '2009-10-13', 'platform' => 12, 'overview' => 'Uncharted 2: Among Thieves is the story of Nathan Drake, a fortune-hunter with a shady reputation and an even shadier past who is lured back into the treacherous world of thieves and mercenary treasure-seekers. The tenth game by premier PlayStation 3 developer Naughty Dog, Uncharted 2: Among Thieves allows players to take control of Drake and embark on a journey that will push him to his physical, emotional and intellectual limits to discover the real truth behind the lost fleet of Marco Polo and the legendary Himalayan valley of Shambhala', 'youtube' => 'tlkkceDkT88', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5839], 'genres' => [1, 2], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 202, 'game_title' => '1942', 'release_date' => '1984-12-01', 'platform' => 23, 'overview' => '1942 is set in the Pacific theater of World War II. The goal is to reach Tokyo and destroy the entire Japanese air fleet. The player pilots a plane dubbed the "Super Ace" (but its appearance is clearly that of a Lockheed P-38 Lightning). The player has to shoot down enemy planes; to avoid enemy fire, the player can perform a roll or "loop-the-loop".', 'youtube' => 'q1kfbflDxpM', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [8], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 203, 'game_title' => 'Aero Fighters', 'release_date' => '1994-01-01', 'platform' => 6, 'overview' => "Aero Fighters (known as Sonic Wings in Japan) is a vertical-scrolling shoot 'em up (\"shmup\") arcade game released in 1992 by Video System, ported to the Super Famicom in 1993 and the Super Nintendo in 1994.\r\n\r\nThere are 8 stages in this game. The beginning stages consists of randomly chosen areas from nations of unselected fighters (assuming those fighters have nations). If Rabio or Lepus is chosen, all 4 rival nation stages become playable. After completing all rival nation stages, there are 4 more stages.", 'youtube' => '7GLM3Ui7Q6w', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9375], 'genres' => [8], 'publishers' => [24], 'alternates' => ['Sonic Wings'], 'uids' => nil, 'hashes' => nil }, { 'id' => 204, 'game_title' => 'Super Bubble Bobble MD', 'release_date' => '1986-01-01', 'platform' => 18, 'overview' => "Super Bubble Bobble MD is an unlicensed Sega Mega Drive game most likely developed by Gamtec. As the name suggests, it is an unlicensed attempt at mimicking the formula of Taito Bubble Bobble.\r\n\r\nThe game allows the user to play as Bub and Bob, as well as anime characters Crayon Shin-chan and Doraemon.", 'youtube' => 'P_KDc1JEfpE', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [3393], 'genres' => [1], 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 205, 'game_title' => 'BurgerTime', 'release_date' => '1987-01-01', 'platform' => 7, 'overview' => "You play as Chef Pepper and your goal is to make giant hamburgers while evil eggs, sausages and pickles chase you around the game area. \r\n\r\nTo properly make a hamburger you must assemble all of the ingredients together, dropping them from higher up onto the the burger area below. To actually do this you have to let Chef Pepper step all over the burger ingredients. As soon as an ingredient (a piece of lettuce for instance) has been stepped on, it will fall to the next level below. Falling food will squish any enemy following you and will also\"bump\" any other ingredient bellow it farther down. Also, as an emergency defense against the enemy food, you can collect pepper shakers which will allow you to puff out a small pepper cloud which will momentarily stun enemies, allowing you to walk past them.", 'youtube' => 'XGbhhqwRKAc', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2126], 'genres' => [5], 'publishers' => [55], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 206, 'game_title' => 'Commando', 'release_date' => '1988-05-04', 'platform' => 22, 'overview' => 'Super Joe is armed with a sub-machine gun (which has unlimited ammunition) as well as a limited supply of hand grenades. While Joe can fire his gun in any of the eight directions that he faces, his grenades can only be thrown vertically towards the top of the screen, irrespective of the direction Joe is facing. Unlike his SMG bullets, grenades can be thrown to clear obstacles, and explosions from well placed grenades can kill several enemies at once.', 'youtube' => '43rLg3mRX8g', 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [1436], 'genres' => [8], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 207, 'game_title' => 'DigDug', 'release_date' => '1982-01-01', 'platform' => 22, 'overview' => "The objective of Dig Dug is to eliminate underground-dwelling monsters. This can be done by inflating them until they pop or by dropping rocks on them. There are two kinds of enemies in the game: Pookas, round red monsters (said to be modeled after tomatoes) who wear yellow goggles, and Fygars, green dragons who can breathe fire. The player's character is Dig Dug, dressed in white and blue, and able to dig tunnels. Dig Dug is killed if he is caught by either Pooka or Fygar, burned by a Fygar's fire, or crushed by a rock.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [748], 'genres' => [5], 'publishers' => [70], 'alternates' => %w[Dig-Dug digdug], 'uids' => nil, 'hashes' => nil }, { 'id' => 208, 'game_title' => 'Double Dragon', 'release_date' => '1987-01-01', 'platform' => 7, 'overview' => 'Double Dragon is the story of Billy and Jimmy Lee, twin brothers who learned to fight on the cold, tough streets of the city. Their expert knowledge of the martial arts combined with their street smarts, has made them both formidable fighting machines. But now Billy is faced with his greatest challenge. Marian has been kidnapped by the Black Warriors, the savage street gang of the mysterious Shadow Boss! Using whatever weapons come to hand - knives, whips, bats, rocks, oil drums, even dynamite - Billy must pursue the gang through the slums, factories, and wooded outskirts of the city to reach the hideout for his final confrontation with the Shadow Boss... his brother Jimmy!', 'youtube' => 'Ex22iGhSTQ0', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [8607], 'genres' => [1], 'publishers' => [56], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 209, 'game_title' => 'Golden Axe', 'release_date' => '1989-05-01', 'platform' => 18, 'overview' => "The game takes place in the fictional land of Yuria, a Conan the Barbarian-style high fantasy medieval world. An evil entity known as Death Adder has captured the King and his daughter, and holds them captive in their castle. He also finds the Golden Axe, the magical emblem of Yuria, and threatens to destroy both the axe and the royal family unless the people of Yuria accept him as their ruler. The character of Death Adder and the stolen Golden Axe could well be traced to the historical event of the Acquisition of the True Cross during the Sassanid-Byzantine wars, as the Norse mythology is heavily influenced by Greek and Middle Eastern mythologies.\r\nThe player controls one of three Warriors. The first is a battle axe-wielding dwarf, Gilius Thunderhead, from the mines of Wolud, whose twin brother was killed by the soldiers of Death Adder. Another is a male barbarian, Ax Battler, wielding a two handed broadsword looking for revenge for the murder of his mother. The last is a long-sword-wielding Tyris Flare, an amazon, whose parents were both killed by Death Adder.", 'youtube' => 'hiHjrQlO2RQ', 'players' => 2, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [7549], 'genres' => [1], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 211, 'game_title' => 'Rad Racer', 'release_date' => '1987-08-17', 'platform' => 7, 'overview' => "This is no ordinary game pak. This is Rad Racer. Nintendo's thrilling 3-D video game Rad Racer comes action-packed with revolutionary 3-D technology and 3-D glasses (they're free inside) that will have you really believing you're in the middle of a cross-country rally race - cruising along at 200 miles per hour! Rad Racer takes you through 8 treacherous race courses including the Los Angeles Nightway, the San Francisco Highway and the Grand Canyon. Choose the Ferrari and you'll enter a Super Machine competition where you'll race against Corvettes and Lamborghinis. Select the F-1 Machine and you'll compete against incredibly fast cars. Whether it's Ferrari or F-1, 3-D or regular mode, Rad Racer's hairpin curves, daredevil turns and realistic action will bring home all the fun and excitement of real rally racing. Think you're up to it? Then drivers, start your engines. It's Rad Racer!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8096], 'genres' => [7], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 212, 'game_title' => 'Chubby Cherub', 'release_date' => '1985-01-01', 'platform' => 7, 'overview' => "Q-tarÅ's friends are kidnapped by several burglars. Q-tarÅ has to save them, however many dogs are in the way—Q-tarÅ's one fear as a ghost. Q-tarÅ the Ghost (Chubby Cherub in the English version) has to cross 12 levels, at the end of each, the protagonist will find his friends. Eating food maintains Chubby Cherub's flight. If the flying meter goes all the way down, the character will have to stay on ground. The character will bark at the dogs before they bark at the character; if a bark hits the character, the character may die.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8959], 'genres' => [1], 'publishers' => [57], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 213, 'game_title' => 'Excitebike', 'release_date' => '1984-11-30', 'platform' => 7, 'overview' => "Whether the player chooses to race solo or against computer-assisted riders, he/she races against a certain time limit. The goal is to qualify for the Excitebike (the championship) race by coming in at third place or above in the challenge race (preliminary race). The times to beat are located on the stadium walls (for first place) and in the lower left corner (for third place). In any race, the best time is 8 seconds ahead of third place. When the player places first, then they get a message: \"It's a new record!\" Additional points are earned by beating the previously-set record time.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6057], 'genres' => [7], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 215, 'game_title' => 'DoDonPachi', 'release_date' => '1997-02-05', 'platform' => 24, 'overview' => 'The player takes on the role of a squadron fighter facing a race of mechanized aliens that recently appeared and started causing havoc. There are three different ships to choose between, and each ship can be played in Laser or Shot mode.', 'youtube' => nil, 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [1510], 'genres' => [8], 'publishers' => [58], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 216, 'game_title' => 'Super Mario 64', 'release_date' => '1996-09-29', 'platform' => 3, 'overview' => "Mario is super in a whole new way! Combining the finest 3-D graphics ever developed for a video game and an explosive sound track, Super Mario 64 becomes a new standard for video games. It's packed with bruising battles, daunting obstacle courses and underwater adventures. Retrieve the Power Stars from their hidden locations and confront your arch nemesis - Bowser, King of the Koopas!", 'youtube' => 'cx78guiPMP8', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [1, 2, 5, 15], 'publishers' => [3], 'alternates' => ['Super Mario 64: Shindou Edition'], 'uids' => nil, 'hashes' => nil }, { 'id' => 217, 'game_title' => 'Command & Conquer', 'release_date' => '1995-08-31', 'platform' => 1, 'overview' => 'Command & Conquer was released in 1995 as the first installment of the identically named RTS series developed by Westwood Studios. Set in an alternate history 1995, Command & Conquer tells the story of two globalized factions: the Global Defense Initiative of the United Nations, and the ancient quasi-cult, quasi-state organization, the Brotherhood of Nod. These two factions become locked in a mortal struggle for control over a mysterious resource known as Tiberium that is slowly spreading and infecting the world.', 'youtube' => 'Aui392986EE', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9595], 'genres' => [6], 'publishers' => [48], 'alternates' => ['Command & Conquer - Tiberian Dawn'], 'uids' => nil, 'hashes' => nil }, { 'id' => 218, 'game_title' => 'Command & Conquer: Tiberian Sun', 'release_date' => '1999-08-27', 'platform' => 1, 'overview' => 'Tiberian Sun is the third part in the Command & Conquer series and was released by Westwood & EA in 1999. Tiberian Sun features three factions, each with its unique strengths and tactics; the Global Defense Initiative GDI, the Brotherhood of NOD and The Forgotten, a non-playable & neutral faction of mutants who have been physically and mentally affected by the Tiberium. The storyline follows the continuing struggle between the GDI and NOD, the latter of which is ready to launch a new set of surprise sneak attacks in an attempt to wipe the Global Defense Initiative off the face of the Earth.', 'youtube' => 'F38Me0tFaLc', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9595], 'genres' => [6], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 219, 'game_title' => 'Command & Conquer: Renegade', 'release_date' => '2002-02-26', 'platform' => 1, 'overview' => "Renegade's story takes place during the final days of the First Tiberium War originally depicted in Command & Conquer. GDI's top three Tiberium research specialists have been abducted by the Brotherhood of Nod. The player assumes the role of GDI commando Captain Nick \"Havoc\" Parker, who is assigned to rescue these experts. He conducts missions which take him all over the world in various countries and climates, both indoor and outdoor, and his actions greatly affect the current state of the war. As the game progresses it is revealed that the specialists have been forced into biochemistry research for the Brotherhood's top secret \"Project Re-Genesis,\" An attempt to create genetically enhanced super-soldiers with the aid of Tiberium.\r\nAs the player plays through a mission, the in-game EVA, or Electronic Video Assistance, periodically updates with mission objectives. EVA logs and updates all objectives and their current status. Objectives are categorized into three categories: primary, secondary and tertiary. The completion of primary objectives are crucial for that mission's success. Secondary objectives are not required for mission completion, but may assist in game play. Tertiary missions, which are usually hidden, do not assist much in game play, but will affect your final \"rank\" at the end of each mission.", 'youtube' => '7ErlZle6Gac', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9595], 'genres' => [8], 'publishers' => [35], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 220, 'game_title' => 'Command & Conquer: Red Alert', 'release_date' => '1996-10-31', 'platform' => 1, 'overview' => "Command & Conquer: Red Alert is the 2nd release in Westwoods Real-Time-Strategy series Command & Conquer and was published in 1996 by Virgin Interactive. Red Alert takes place during an unspecified period in the 1950s of a parallel universe, which was inadvertently created by Albert Einstein in a failed attempt to prevent the horrors of World War II.\r\nStarting off in 1946, at the Trinity site in New Mexico, the opening to Red Alert shows Albert Einstein as he is preparing to travel backwards through space and time. After his experimental \"Chronosphere\" device is activated, he finds himself in Landsberg, Germany, in the year 1924, where he meets a young Adolf Hitler just after the latter's release from Landsberg Prison. Following a brief conversation between the two, Einstein shakes Hitler's hand, and this somehow eliminates Hitler's existence from time and returns Einstein to his point of origin.\r\nWith the threat of Nazi Germany having been successfully removed from history, the Soviet Union began to grow increasingly powerful under the rule of Joseph Stalin. Had Adolf Hitler risen to power, Nazi Germany would have emerged as a force standing in the way of Stalin's own ambitions of conquest. Instead, left unweakened, the USSR proceeds by seizing lands from China and then begins invading Eastern Europe, in order to achieve Joseph Stalin's vision of a Soviet Union stretching across the entire Eurasian landmass. In response, the nations of Europe form into the Alliance, and start a grim and desperate guerrilla war against the invading Soviet army. Over the course of the game's story, the Allies and Soviets fight out a devastating conflict for control over the European mainland, in what has become an alternate World War II.", 'youtube' => 'bSXu_3qtsl4', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9595], 'genres' => [6], 'publishers' => [48], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 221, 'game_title' => 'Command & Conquer: Red Alert 2', 'release_date' => '2000-10-23', 'platform' => 1, 'overview' => "After the attempted conquest of Europe, the Soviet Union is in utter ruin. Joseph Stalin is dead, and the Soviet military has been all but destroyed. The Allies determine that a regime change would cause mass unrest in the Soviet Union, and in order to gain both support and stability in the region, the victorious Allies name Alexander Romanov, a distant relative of Czar Nicholas II, as the puppet Soviet Premier. Romanov acquiesces to the Allies' demands at first, though he builds up the Soviet military for \"defense purposes\" – a cover for an intended invasion of the United States of America.\r\nThe game's story line starts off with the American military being caught completely off guard by the sudden massive Soviet invasion of the USA, with Soviet aircraft, naval vessels, amphibian forces, and paratroopers coming in on both the East Coast and West Coast and with the majority of Soviet ground forces coming in through Mexico, which had recently voted in a communist government. The USA attempts to retaliate with the use of nuclear missiles, but Yuri, leader of the Soviet Psychic Corps and Premier Romanov's top advisor, uses his mind control to manipulate the personnel charged with launching the warheads and leaves them to explode in their silos. Within hours, the USA is overrun with Red Army troops. In response, the US President Michael Dugan establishes an emergency response team headed by General Carville and the Commander (the player).", 'youtube' => '2YlVumsPHx4', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9595], 'genres' => [6], 'publishers' => [35], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 222, 'game_title' => 'Metal Slug', 'release_date' => '1996-05-24', 'platform' => 24, 'overview' => "In 2028, General Donald Morden launches an all-out, global attack against the Regular Army. With superior numbers and equipment, the Rebellion overwhelms the unsuspecting Regular Army troops easily. \r\n\r\nThe attacks could have been countered effectively, or even prevented, should the high-ranking officials have listened to the Regular Army's intelligence community, which had been warning about all sorts of indications that the Rebellion could attack at any moment in decisive force. Unfortunately, the same officials decide to save their own skins and announce that it was the intelligence failure that led to such catastrophe, which the personnel serving in the intelligence community did not appreciate whatsoever. \r\n\r\nMeanwhile, Regular Army is pushed to near annihilation, with cities that it was suppose to be protecting in ruins. General Morden makes an announcement that all of the major cities around the world will be under his control within 170 hours, also adding that any resistance would be futile. \r\n\r\nThe announcement certainly did not discourage a band of Regular Army soldiers attempt to salvage whatever they had left. Shortly after, a group named \"Resistants\" are formed by surviving members of the Regular Army and its researchers, who began to covertly convert the Metal Slug tank prototypes into combat-ready status in a hidden factory, hoping to launch a counter-offensive to regain what they had lost to the Rebellion. Morden just as quickly learns of this fact and attacks the plant, crushing the Resistants and capturing the tanks, putting an end to the counterattack even before it could begin. The vehicles are then scattered to prevent any ragtag Regular Army troops reclaiming them and using them to launch attacks. \r\n\r\nSeeing the Regular Army panic and crumble, 1st Lieutenant Marco Rossi of the Regular Army Peregrine Falcons special forces unit quickly unites remaining Regular Army units and begins a commando operation to reclaim the tanks. Fighting alongside him is Second Lieutenant Tarma Roving from the same unit. Their main objectives were to engage the Rebellion and neutralize its leader, General Morden, while reclaiming the Metal Slug tanks to aid them in battles. If the tanks could not be recaptured, then they would have to destroy them to prevent them from being used by the Rebellion. \r\n\r\nThe player has to constantly shoot at a continual stream of enemies in order to reach the end of a level. At the end of each level, the player might confront a boss who is often considerably larger than regular enemies and takes many shots to defeat. On the way through the level, the player finds weapons upgrades and \"Metal Slug\" tanks that can be used not only as weapons but also as added defense.\r\nThe protagonists can perform melee attacks by using a knife and/or kicking. The player does not die for simply coming into contact with most enemies. Correspondingly, many of the enemy troops have melee attacks. Much of the game's scenery is destructible. Sometimes this reveals extra items or powerups, most of the time it simply results in collateral damage.\r\n\r\nDuring the course of a level, the player encounters prisoners of war. If they are freed, the player can receive bonuses in the form of random items or weapons. The player receives a score bonus for freeing POWs at the end of the level; at this point the game shows the name and rank for each of the prisoners freed. If the player dies before the end of the level, the tally of freed POWs is restarted.\r\nThere are a total of six levels, with themes ranging from forests, garrisoned cities, snowy mountain valleys, canyons, and military bases.", 'youtube' => '_UfHv7jksSo', 'players' => 2, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [5849], 'genres' => [1, 2, 8], 'publishers' => [60], 'alternates' => ['mslug'], 'uids' => nil, 'hashes' => nil }, { 'id' => 223, 'game_title' => 'Metal Slug 2', 'release_date' => '1998-04-02', 'platform' => 24, 'overview' => "General Morden, the antagonist from the first game is back once more with his army, bent on taking over the world. It is up to the Peregrine Falcon squad, who are now joined by two new characters: Eri Kasamoto and Fiolina Germi of the Sparrows Intelligence Unit, to save the day.\r\nAs the levels unfold, it turns out that Morden has allied with Martians to help facilitate his plans. In the final level of the game, the tables are turned when Morden comes under attack and is betrayed by his Martian allies and taken prisoner by them. An ad-hoc alliance is formed between the Peregrine Falcon squad and General Morden's army to combat the greater alien threat. After a long battle, they succeed in defeating the Martians' Mothership, driving them off the Earth. Morden seems to have fallen from the ship, strapped to a solid iron plate. While his soldiers celebrate, the plate loses its balance and crushes him.", 'youtube' => 'U1Tt3BQ6pi4', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7885], 'genres' => [1, 2, 8], 'publishers' => [60], 'alternates' => ['mslug2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 224, 'game_title' => 'Metal Slug 3', 'release_date' => '2000-06-01', 'platform' => 24, 'overview' => "The rebellion orchestrated by General Morden to bring about a new global regime is now ancient history, and order and peace has begun to return to the world. Morden, brought back into power, was attempting another coup d'état, but government forces got wind of the plot beforehand and pre-empted the impending assault.\r\nInstrumental in squashing Morden's rebel forces, Marco and Tarma of the Peregrine Falcon Strike Force are ordered to lead the team after their earlier requests for resignation were denied. Although General Morden has been written off as \"missing\" by his followers, they have hidden themselves throughout the world, and Marco and Tarma's abilities and experience are seen as a necessity to destroy remaining rebel strongholds, one by one. Throughout the furious fighting against the holdouts, Marco and Tarma cannot help but suspect Morden's involvement in this new evil plan for world domination.", 'youtube' => 'biFBCq5ouik', 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [7885], 'genres' => [1, 2, 8], 'publishers' => [60], 'alternates' => ['mslug3'], 'uids' => nil, 'hashes' => nil }, { 'id' => 225, 'game_title' => 'Metal Slug 4', 'release_date' => '2002-07-19', 'platform' => 24, 'overview' => "One year after the events of Metal Slug 3, the world is trembling under the new threat of a mysterious but deadly cyber virus that threatens to attack and destroy any nation's military computer system. With Tarma and Eri unable to help due to their own assignments in the matter, Marco and Fio are called in to investigate the situation and are joined by two newcomers, Nadia and Trevor. In their investigation, the group discovers that a terrorist organization known as Amadeus is behind the nefarious plot and that they head into battle against Amadeus' forces, hoping to destroy the cyber virus before it gets the chance to wipe out the entire world's military computer system.", 'youtube' => 'Xq3S8kwgURA', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5366], 'genres' => [1, 2, 8], 'publishers' => [61], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 226, 'game_title' => 'Metal Slug 5', 'release_date' => '2003-11-01', 'platform' => 24, 'overview' => 'A special disc that contains deep and intricate secrets about the Metal Slug project is stolen by a mysterious group called the Ptolemaic Army, whose specialty lies from within archaeological excavation and espionage. Marco and Tarma of the Peregrine Falcon Strike Force follow in hot pursuit against the group and in the process are joined by Eri and Fio of SPARROWS. Together once more, the quartet investigate the shrouded objective of the Ptolemaic Army.', 'youtube' => 'FiDEoycsd5A', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7885], 'genres' => [1, 2, 8], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 227, 'game_title' => 'Metal Slug 6', 'release_date' => '2006-02-24', 'platform' => 23, 'overview' => "Metal Slug 6 returns to the Rebel-Martian alliance featured in Metal Slugs 2, X, and 3, but on a much broader scale. Rather than repeating the previous games' events of the Martians breaking the alliance and the Rebels assisting the player in turn, the player now teams up with the Rebels and Martians to combat an even greater threat.\r\n\r\nMetal Slug 6 introduces a new play mechanic dubbed the 'Weapon Stock System'. Two gun power-ups can now be carried at the same time. Players can switch between the two weapons, or simply put them both away in favor of the default weapon. When obtaining a new weapon power-up, it will automatically occupy the inactive slot, or, if both are holstered, replace the less recent weapon of the two.\r\nThe score is now multiplied by powers of 2. The faster the speed at which enemies are killed, the higher the power, as a meter at the bottom of the screen shows. When it says \"Max\" enemies and destructible objects will drop coins for an extra high score.", 'youtube' => 'prOR8pSXC-U', 'players' => 2, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [7885], 'genres' => [1, 2, 8], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 228, 'game_title' => "Cruis'n USA", 'release_date' => '1996-12-18', 'platform' => 3, 'overview' => "Slam the pedal to the metal and hang on for a wild race across the highways of America. Catch tall the roadside scenery and famous landmarks from three different driving perspectives -- from San Francisco's Golden Gate Bridge, South Dakota's Mount Rushmore to the rolling hills of Appalachia.\r\n\r\nExperience the treacherous turns and famous landmarks as you drive across America!\r\n\r\nSelect one of five difficulty levels and even remove street traffic or rivel racers from the course.\r\n\r\nSelect one of ten short courses or go the distance on an textended 14-stage road race.\r\n\r\nA split screen perspective allows two players to share the action simultaneously.\r\n\r\nWith the N64 Controller as your steering wheel,you have the precision to make the tightest of turns and quickest maneuvers.\r\n\r\nThere's no better way to experience the excitement of cross-country racing!", 'youtube' => '8Dvw6TjwFyw', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5512], 'genres' => [7], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 229, 'game_title' => "Cruis'n World", 'release_date' => '1998-06-25', 'platform' => 3, 'overview' => "Wanna see the world the easy way? Cruise it! Race through the deserts of Australia, zip through the streets of Paris or blast through the roadways of China! Play the new Championship mode to earn power-ups and secret cars! Go it alone or challenge up to three friends to see who’s the fastest! Check your passport at the door. With Cruisin’ World, you’ve got the power!\r\n\r\nPlay the new Championship mode to earn power-ups and secret cars!\r\n\r\nTake in scenery from 14 courses around the world!\r\n\r\nChoose from 12 different cars!\r\n\r\nFour-player simultaneous racing!\r\n\r\nCompatible with the Rumble Pak’ accessory!", 'youtube' => '07JnqrE3Cv8', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5512], 'genres' => [7], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 230, 'game_title' => "Cruis'n Exotica", 'release_date' => '1998-01-01', 'platform' => 3, 'overview' => "GET EXOTIC! …from Atlantis to Mars and everywhere in between.\r\n\r\nRace in style! Cruis’n Exotica takes you to fantastic locales in even more fantastic vehicles. Race through steamy Jurassic jungles or on the ocean floor. Midair stunts keep the action nonstop! Valuable shortcuts and nitro boosts speed up the already fast-paced action! Fantastic driving excitement straight from the arcade!\r\n\r\n28 exotic cars to race!\r\n\r\n1 to 4 player non-stop racing action!\r\n\r\nTurbo boosts, stunts, nitros and more!\r\n\r\n60 tracks from around the world!\r\n\r\nThree modes of play to choose from!", 'youtube' => 'K9fZWB24YpA', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5512], 'genres' => [1, 7], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 231, 'game_title' => 'Star Wars: Shadows of the Empire', 'release_date' => '1996-12-03', 'platform' => 3, 'overview' => "A long time ago in a galaxy far, far away... As Luke Skywalker and the Rebel Alliance struggle to defeat Darth Vader and the Empire, a new threat arises. Dark Prince Xizor, head of the Black Sun crime syndicate, aspires to take Darth Vader's place at the Emperor's side. To do that, he must eliminate young Skywalker. As Dash Rendar, it's up to you to protect Luke and help the Alliance defeat the evil Xizor. Watch out for infamous bounty hunters and deadly stormtroopers! May the Force be with you!", 'youtube' => 'scmZKBDOYqM', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5068], 'genres' => [1], 'publishers' => [3], 'alternates' => ['STAR WARS TEIKOKU NO KAGE'], 'uids' => nil, 'hashes' => nil }, { 'id' => 232, 'game_title' => 'Super Mario RPG: Legend of the Seven Stars', 'release_date' => '1996-05-13', 'platform' => 6, 'overview' => "Mario returns in this incredible new role-playing adventure! His latest rival is Smithy, a menacing creature who causes fear and treachery in the Mushroom Kingdom. Mario must recover seven stars and repair the Star Road before he can make his way to Bowser's castle for a final confrontation with Smithy. Powerful weapons, sinister spells and other useful items help Mario to complete his harrowing journey. New friends and old allies support him along the way. Even Bowser lends a hand!", 'youtube' => '9HDQa3LAGO4', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8096], 'genres' => [4], 'publishers' => [3], 'alternates' => ['Super Mario', 'Mario RPG', 'Super Mario RPG', 'RPG'], 'uids' => nil, 'hashes' => nil }, { 'id' => 233, 'game_title' => 'Metroid Prime 3: Corruption', 'release_date' => '2007-08-27', 'platform' => 9, 'overview' => "Stop the unstoppable Dark Samus\r\n\r\nIf you think you knew what it felt like to be the bounty hunter behind the visor, think again. The Galactic Federation's network computer, Aurora Unit, is suddenly and completely corrupted with something like a virus. The Federation believes Space Pirates may be behind the problem and are soon attacked. Samus and other hunters leap to their defense only to find that the enemy they face is Dark Samus, armed with immense power that no one can withstand.\r\n\r\n-First-Person Perfect: Players control Samus by moving with the Nunchuk and aiming with the Wii Remote controller, allowing for a level of immersion unlike anything they have ever experienced. It's a quantum leap in first-person control.\r\n\r\n-Wonderful Weapons: Samus employs well-known power-ups like the Grapple Beam and Morph Ball, as well as new surprises, to help her survive. Using the Wii Remote and Nunchuk controllers, players will be able to grasp and pull things by using actual arm movements, as well as execute amazing feats like aiming and blasting in midair or at a full run.\r\n\r\n-Phazon's Powers: The game also incorporates a new system involving Phazon. If you fill Samus' Phazon supply to a certain level, Samus will temporarily go into hyper mode, a state in which she can pull off incredible feats. On the flip side, if she exceeds the maximum Phazon level, she'll perish. Also, for the first time in the Metroid series, Samus' ship will be used in active game play.", 'youtube' => 'lQLIwauAVNU', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7160], 'genres' => [1, 2, 8, 15], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 234, 'game_title' => 'Anno 1404', 'release_date' => '2009-06-23', 'platform' => 1, 'overview' => "In the fascinating world of ANNOâ„¢ the player will sink into a unique building strategy game, where he sets sail in a beautiful island world to master the tricks of trade, diplomacy and economy, building up his own monumental cities. Continuous careful and elaborate planning will help fulfil his citizen’s needs and let his empire flourish. The upcoming ANNO 1404â„¢ will bring this award-winning building strategy series to a new level:\r\n\r\nDiscover a strange and wondrous land in the uttermost East: the Orient! This highly civilized land will provide you with endless opportunities, and with the help of your new allies your occidental cities will prosper and become mighty metropolises!", 'youtube' => 'SKu76T0O_Ww', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1216, 7123], 'genres' => [3, 6], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 235, 'game_title' => 'Fallout', 'release_date' => '1997-09-30', 'platform' => 1, 'overview' => 'Gameplay in Fallout consists of traveling around the game world, visiting locations and interacting with the local inhabitants, and is typically in real-time. Occasionally, inhabitants will be immersed in dilemmas which the player may choose to solve in order to acquire karma and experience points. Alternately, the player may choose to ignore requests for help, in which case he or she has the option of acting on behalf of an opposing faction, or purely in self-interest. Experience points may still be rewarded if the player acts for an opposing interest or in self-interest. Ultimately, players will encounter hostile opponents (if such encounters are not avoided using stealth or diplomacy), in which case they and the player will engage in combat.', 'youtube' => 'M_10Zv3k4t0', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1143], 'genres' => [4], 'publishers' => [62], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 237, 'game_title' => '1080: TenEighty Snowboarding', 'release_date' => '1998-04-01', 'platform' => 3, 'overview' => "You’re taking a Tahoe 155 snowboard down a steep, bumpy incline at night and you’re about to top off an Indy Nosebone with a 360° Air, and you haven’t even left your living room! You’re Playing 1080° (Ten Eighty) Snowboarding, a game so intense you’ll be brushing the snow off your goggles. With five different boarders, eight different Lamar snowboards, more than 25 tricks, a Half-Pipe and six different courses, this is as close as you’ll get to the real thing without hopping on the next ski lift.\r\n\r\n• Six game modes and courses!\r\n• 2-Player simultaneous play!\r\n• Over 25 different tricks!\r\n• Compatible with Rumble Pak accessory.", 'youtube' => '8hAWCad3IS8', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6043], 'genres' => [11], 'publishers' => [3], 'alternates' => ['1080 Snowboarding'], 'uids' => nil, 'hashes' => nil }, { 'id' => 238, 'game_title' => '007: The World Is Not Enough', 'release_date' => '2000-10-17', 'platform' => 3, 'overview' => "Bond Is Back\r\n\r\nExperience the intensity of being the world's top secret agent. Equipped with a full arsenal of Q-Lab gadgets and weaponry, you must be suave, resourceful and lethal as you carry out action-packed missions based on the blockbuster movie. Are you cool under pressure? Deadly when necessary? Of course you are - you're Bond... James Bond \r\n\r\n• Bond's Best Missions! Battle through 14 dangerous levels with dynamic objectives based on your skill level.\r\n• Over 40 Q-Lab Gadgets and Weapons! Bond's P2K, X-Ray Glasses, Watch Stunner, and many more.\r\n• Action-packed Multiplayer! Customizable multiplayer modes for 1 to 4 players plus AI controlled bots.\r\n• Authentic Dialogue! Interact with you favorite characters and experience movie-like 3D cinematics with full speech.\r\n• Expansion Pak Support for enhanced graphics and visual effects.", 'youtube' => '-i9Pz6IzBgw', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2886], 'genres' => [1, 8], 'publishers' => [2], 'alternates' => ['World is Not Enough, The'], 'uids' => nil, 'hashes' => nil }, { 'id' => 239, 'game_title' => "A Bug's Life", 'release_date' => '1998-11-06', 'platform' => 3, 'overview' => "As hopeful hero Flik, you're the colony's last chance against the seed-grubbing grasshoppers. Run, fly, kick, squish, and slide through 15 challenging levels of 3-D animated gameplay. Outmaneuver 13 types of enemies, including The Bird and her deadly beak. Then, throw your weight around with tough antics like the Berry Attack and the Butt-Bounce. Because on this ride, you'll need more than just high hopes.\r\n\r\n• Search for power-ups, tokens and objects to use in the \"Living World.\"\r\n• Get a bug's-eye-view of a magical 3-D world.\r\n• Swing, fly, slide and navigate Flik through immense bug-infested levels.", 'youtube' => 'j0ITQ9h2o4c', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2383], 'genres' => [2], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 240, 'game_title' => "Army Men: Sarge's Heroes", 'release_date' => '2000-11-16', 'platform' => 3, 'overview' => 'CONFIDENTIAL. 0600 hours: Tan forces captured Bravo Company Commandos. General Plastro has new weapons of mass destruction: magnifying glass, M-80 firecrackers and the garbage disposal. This is a job for Sarge. Requisition M-60s, shotguns, bazookas, flame throwers, grenades, sniper rifles, mortars, mine sweepers and plenty of ammo. Good luck, soldier.', 'youtube' => 'V5IbVO1MUbc', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [77], 'genres' => [1, 8], 'publishers' => [63], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 241, 'game_title' => 'BattleTanx', 'release_date' => '1998-12-31', 'platform' => 3, 'overview' => "In the year 2001, a virus has killed 99.99% of the females on Earth. Various countries fight over each other's quarantine zones, and end up engaging in nuclear war, destroying much of civilization. The few remaining females are held by gangs who have taken over small pieces of the world. The main character, Griffin Spade, had his fiancee Madison taken away from Queens, New York by the U.S. Government. Griffin ends up separated from his fiancee, and New York City is destroyed. He claims a tank for his own and sets out to cross America and find her, battling gangs as he reaches his goal. After surviving the ruins of New York City, Griffin heads westward gaining recruits in the countryside, Chicago, Las Vegas, and San Francisco.", 'youtube' => 'qJbjhKCdwpU', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [77], 'genres' => [1], 'publishers' => [63], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 242, 'game_title' => 'BattleTanx: Global Assault', 'release_date' => '1999-10-12', 'platform' => 3, 'overview' => "On January 13, 2006, a Queenlord, Cassandra, is spying on Griffin Spade's family, telling her troops to kidnap Griffin's son Brandon and kill everyone else. Griffin and his army manage to push back the invaders, but Cassandra soon turns the tables by mind-controlling Griffin's own army. Griffin and Madison manage to escape San Francisco and begin chasing Cassandra across the United States, eventually cornering her in Washington, D.C.. Cassandra, however, escapes with Brandon to Great Britain; Griffin and Madison follow. They build a new army in Europe, and chase Cassandra through England, France and Germany. While in Paris, they discover Cassandra released the virus in 2001 to kill every female on Earth who didn't have the power of the Edge.", 'youtube' => 'CbFcc-_tWNQ', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [77], 'genres' => [1], 'publishers' => [63], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 243, 'game_title' => 'Blues Brothers 2000', 'release_date' => '2000-11-16', 'platform' => 3, 'overview' => 'Start out as Elwood in prison and get the band together for the battle of the bands, which is in less than two days. After saving the guitarist, Cab and defeating the warden, Mac and Buster are waiting to be found in Chicago to complete and reunite your crew!', 'youtube' => 'OneO7J5yGlE', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6683], 'genres' => [15, 17], 'publishers' => [64], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 244, 'game_title' => 'Body Harvest', 'release_date' => '1998-10-20', 'platform' => 3, 'overview' => "The year is 2016. Humanity has been reduced to a few survivors inhabiting the orbital space station Omega. Over the course of the history, aliens visited the Earth every twenty-five years, \"harvesting\" humans as an organic material. Eventually, they launch an assault on the last remnants of the human race. But Adam Drake, a genetically engineered soldier, comes into possession of a time-traveling device. He uses it to travel to the time periods of human history when aliens performed their deadly attacks. The fate of humanity is in his hands.\r\n\r\nBody Harvest is an action and driving game with a mission-based structure. The protagonist travels to various locations and eras (e.g. Greece during World War II, Siberia in the 1990s, etc.) with the goal of stopping alien invasions. Missions can be accessed by traveling to specified areas on the map. Adam can move on foot and use his weapons to kill aliens; however, vehicles usually prove to be a more reliable way of tackling most missions. Adam can use most of his weapons while in a vehicle; in addition, some vehicles are outfitted with their own weapons.", 'youtube' => 'bnocQS1maqg', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2404], 'genres' => [1, 8], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 245, 'game_title' => 'Bomberman Hero', 'release_date' => '1998-09-01', 'platform' => 3, 'overview' => "Bomberman's latest adventure takes him across the galaxy! Princess Millian has been kidnapped by the evil Garaden Empire and it's up to Bomberman to save the day. Travel through worlds of ice, fire and water. Use new abilities and get help from friends like Louie the rabbit and Pibol the robot. New vehicles like the Bomber Copter and Bomber Marine will come in handy in your quest to save the Princess and free the universe once again!", 'youtube' => 'HAeQZ3-vSYI', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3923], 'genres' => [1], 'publishers' => [3], 'alternates' => ['Bomberman Hero: Millian Ojosama wo Sukue'], 'uids' => nil, 'hashes' => nil }, { 'id' => 246, 'game_title' => 'Castlevania: Legacy of Darkness', 'release_date' => '1999-11-30', 'platform' => 3, 'overview' => "Before Reinhardt Schneider and Carrie Fernandez confronted Dracula, a magical warrior embarked on a quest that would ultimately lead him to Dracula's lair. Take control of Cornell, a powerful werewolf, who is seeking out the evil minions responsible for his sister's disappearance. Armed with the power to morph from human to werewolf, Cornell is destined to rescure his sister from a sinister plan and rid the world of Dracula once and for all. Will he succeed or fail? Will the past unravel the future? Discover the legacy in this exciting prequel.", 'youtube' => 'UnOHRdp1GgI', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [4765], 'genres' => [1, 15], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 247, 'game_title' => 'Chopper Attack', 'release_date' => '1998-06-17', 'platform' => 3, 'overview' => "Chopper Attack is a helicopter-based third-person shooter game released and published in 1997 by Midway.\r\nThe game features numerous missions in various locations; missions include bombing the enemy's bases, escorting Air Force One through dangerous jungle terrain and rescuing prisoners of war.", 'youtube' => 'BtO7JmcKCDY', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7625], 'genres' => [1, 8], 'publishers' => [41], 'alternates' => ['Wild Choppers'], 'uids' => nil, 'hashes' => nil }, { 'id' => 249, 'game_title' => "Conker's Bad Fur Day", 'release_date' => '2001-03-04', 'platform' => 3, 'overview' => "The day after his 21st birthday bash, Conker's sporting the worst hangover ever, and he just can't seem to find his way home. Prepare to stagger through randy, raunchy, raucous scenarios crammed full of bad manners, twisted humor, and graphic bodily functions. Unless you're a fan of violence, foul language, and racy innuendo, you'd best steer clear of this one.\r\n\r\nAlthough visually similar to Rare's family-oriented Nintendo 64 platform games Banjo-Kazooie and Donkey Kong 64, Conker's Bad Fur Day was designed for mature audiences and features graphic violence, alcohol and tobacco use, profanity, vulgar humor and pop culture references. It was developed over the course of four years and was originally intended for a family audience, but was ultimately retooled into its current form because previews were criticised for being both too cute and similar to Rare's earlier platform games.", 'youtube' => 'pfq44ETz92Y', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [6991], 'genres' => [15], 'publishers' => [51], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 250, 'game_title' => 'Donkey Kong 64', 'release_date' => '1999-11-24', 'platform' => 3, 'overview' => "K. Rool has kidnapped the Kongs! Can Donkey Kong rescue his friends, reclaim the Golden Bananas and save his homeland from certain doom? Take out some Kremlings with Chunky's Pineapple Launcher or Lanky's Trombone. Float through the air using Tiny's Ponytail Twirl. Even rocket to the sky with Diddy's Jetbarrel!", 'youtube' => 'W6mqRCsMKmE', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6991], 'genres' => [1, 2], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 251, 'game_title' => 'Doom 64', 'release_date' => '1997-03-31', 'platform' => 3, 'overview' => 'You killed the Demons once, they were all dead. Or so you thought... A single Demon Entity escaped detection. Systematically it altered decaying, dead carnage back into grotesque living tissue. The Demons have returned - stronger and more vicious than ever before. You mission is clear, there are no options: kill or be killed!', 'youtube' => 'MXgG8NmJUjI', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [5507], 'genres' => [8], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 252, 'game_title' => 'Fighter Destiny 2', 'release_date' => '2000-06-22', 'platform' => 3, 'overview' => "Enter the arena and do battle with the toughest, most skilled martial arts experts on the planet. As one of the international fighting elite, you'll vie to become the true authority of hand-to-hand combat. Your destiny awaits. Defeat any of your 11 opponents and gain their abilities. Launch 5 different modes of attack, from Training to Record Attack. Adjust scoring, ring sizes and difficulty settings. Compete in points-based martial arts tournaments. Force your opponent to relive defeat in instant replay. Gain new abilities and skills when you face the Master in the Fighter's Arena.", 'youtube' => '098-xkcuuko', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [4093], 'genres' => [10], 'publishers' => [67], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 253, 'game_title' => 'Fighting Force 64', 'release_date' => '1999-04-30', 'platform' => 3, 'overview' => "Fighting Force players control one of four characters. They move through urban and science fiction environments, battling waves of oncoming enemies with weapons ranging from fists and bottles to knives, chairs and guns. The player can make some choices as to which territory to travel through.\r\n\r\nThe four characters have various reasons for taking on Dr. Zeng, a criminal mastermind with an army at his command. The action starts with a police cordon around Zeng's office skyscraper, moving to such locales as a shopping mall, subway and Coast Guard base before finally ending at the top of Zeng's island headquarters.", 'youtube' => 'nEZ9D696Gew', 'players' => 2, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [1827], 'genres' => [10], 'publishers' => [68], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 254, 'game_title' => 'Forsaken 64', 'release_date' => '1998-04-30', 'platform' => 3, 'overview' => "Forsaken is a first-person shoot 'em up in which you have complete movement freedom in 3 dimensions, as you accelerate, swerve and strafe your craft, making for gameplay resembling Descent. Each level has a defined exit which must be reached within a tight time limit. The surrounding areas are collapsing around you, with spikes and turbine fans among your hazards. Be very aware of other craft out to take all you have, as they alter their approach based on your weaponry (from the 25 featured in the game) and past encounters.", 'youtube' => 'BxUxMMAElXo', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4065], 'genres' => [1, 8], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 255, 'game_title' => 'Gauntlet Legends', 'release_date' => '1999-08-31', 'platform' => 3, 'overview' => "In ages past, a corrupt mage named Garm used a set of Runestones to summon a demon named Skorne (It is not stated what Garm intended to use Skorne for; however, as Gauntlet Legends introduces Garm as a \"greedy young mage\", it can be assumed he wanted Skorne for his own personal gain.) However, Skorne crushed Garm and imprisoned his soul in the Underworld. Skorne, fearing the power of the Runestones, scattered them throughout the four realms, so that they could never be used against him. The player(s) must defeat the end bosses of each of the four realms to obtain the four golden keys which allow access to Skorne's temple. While traveling through each realm, he/she/they must also collect the Thirteen Runestones from where they have been scattered. The complete set of Runestones allows him/her/them to pursue Skorne to the Underworld in order to finally destroy him. The players must find 3 rune stones on each kingdom in order to defeat Skorne in the Underworld, and of course 1 from the battle grounds.", 'youtube' => 'iIR_6QL1CpI', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1], 'genres' => [1], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 256, 'game_title' => 'Hercules: The Legendary Journeys', 'release_date' => '2000-11-17', 'platform' => 3, 'overview' => "Take control of the legendary hero Hercules and his friends Iolaus and Serena as they attempt to stop Ares from completing his diabolical plans. Use each character's unique attributes: Hercules' legendary strength, Iolaus' nimble nature and Serena's accuracy to complete your quest. Travel through 12 unique fully 3D worlds, from the sunny seaside town of Porticus to the snowy mountains of Alpsius. Explore the bandit-overrun forrests of Traycus or heavenly Mount Olympus. Fight mythical terrifying monsters such as the Minotaur, Cyclops, and more!", 'youtube' => 'ONRe6kvHxIc', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6683], 'genres' => [1, 2], 'publishers' => [64], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 257, 'game_title' => 'Hey You, Pikachu!', 'release_date' => '2000-11-05', 'platform' => 3, 'overview' => "For the first time ever, you can actually talk to your favorite Pokemon. Tag along with Pikachu as it goes through its daily routines, taking field trips, going fishing and having picnics, becoming better friends with each passing day. Pikachu will hear and react to the words you say. The more you speak the closer friends you'll be!", 'youtube' => 'WKale4NAgT0', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [423], 'genres' => [9], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 258, 'game_title' => 'Hydro Thunder', 'release_date' => '1999-09-09', 'platform' => 3, 'overview' => 'The gameplay of Hydro Thunder consists of racing high-tech speedboats through treacherous environments, from the cold seas of the Arctic Circle, to a post-apocalyptic, flooded version of New York City.', 'youtube' => 'e59cRHwIX8A', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5512], 'genres' => [19], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 259, 'game_title' => 'Indiana Jones and the Infernal Machine', 'release_date' => '2000-12-15', 'platform' => 3, 'overview' => "1947. The nazis have been crushed, the Cold War has begun and Soviet agents are sniffing around an ancient ruin. Grab your whip and fedora and join Indy in a globespanning race to unearth the mysterious \"Infernal Machine\". Survive the challenges of unusual beasts, half the Red Army and more (including - oh no - snakes!) \r\n\r\nPuzzle your way through 17 chapters of an action-packed story. Travel the world to exotic locales, from the ruins of Babylon to Egyptian deserts. All the weapons you'll need, including firearms, explosives-and of course Indy's trusty whip and revolver.", 'youtube' => 'rRVHxKkeN8I', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5068], 'genres' => [1, 2], 'publishers' => [25], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 260, 'game_title' => 'Jet Force Gemini', 'release_date' => '1999-10-11', 'platform' => 3, 'overview' => "The insect invasion has begun.\r\n\r\nThe galaxy is being infested by the evil Mizar and his horde of Drones. Already, the planet of Goldwood has been subjugated and the peaceful Tribals enslaved. With an arsenal of mega-weapons at their disposal, the Jet Force Gemini team must travel in search of Mizar's lair - rescuing Tribals and splattering Drones along the way. But can Juno, Vela and their faithful dog, Lupus, exterminate the deadly threat before it's too late?\r\n\r\n+ \" The game also includes a multiplayer mode where two to four players can compete in traditional deathmatch games. \" -Wikipedia", 'youtube' => 'eHjwPulJdU4', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6991], 'genres' => [1, 2, 8], 'publishers' => [51], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 261, 'game_title' => 'Killer Instinct Gold', 'release_date' => '1996-11-25', 'platform' => 3, 'overview' => "Killer Instinct Gold rocks the gaming world with its earth-shattering moves and unbelievable graphics. Your battles unfold with lightning-fast action and fluid character animation at 60 frames per second. We faithfully duplicated all the features that made Killer Instinct 2 an arcade hit. We've even thrown in a complete training mode to school you on all the moves! The eye-popping graphics, the explosive hits and jaw-dropping combos make Killer Instinct Gold the only fighting game you'll ever want in your house!", 'youtube' => 'B8fph9nhq4k', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6991], 'genres' => [10], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 262, 'game_title' => 'Kirby 64: The Crystal Shards', 'release_date' => '2000-06-26', 'platform' => 3, 'overview' => "Kirby's first 3-D adventure is also his Nintendo 64 debut, and it finds the always-versatile hero battling a new enemy called Dark Matter. Dark Matter is after a distant land's powerful crystal, but a young fairy named Ribbon attempts to save it by escaping with the gem to Dream Land. Now the crystal has been broken, and it's scattered around the world. Take control of Kirby and help him journey across six worlds, battling a wide variety of enemies and challenging bosses, as he tries to collect all 100 pieces of the shattered crystal.", 'youtube' => 'Qf0pwsX73jw', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3694], 'genres' => [2], 'publishers' => [3], 'alternates' => ['Hoshi no Kirby 64'], 'uids' => nil, 'hashes' => nil }, { 'id' => 264, 'game_title' => 'Knockout Kings 2000', 'release_date' => '1999-10-03', 'platform' => 3, 'overview' => 'Get it on as or against 25 of the greatest boxers of all time! Includes Oscar De La Hoya, Sugar Ray Leonard, Evander Holyfield, and THE GREATEST, Muhammad Ali! Arcade-style Slugfest and Career modes. Super KO punches and hidden moves. Knockdown-dragout battles with the greatest boxers ever. Build a champion and fight to the top in Career mode. Pit current champs vs. legendary superstars, or challenge your created boxer against the greats.', 'youtube' => 'GmEyq6Hsijs', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1154], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 265, 'game_title' => 'Duck Dodgers Starring Daffy Duck', 'release_date' => '2000-12-16', 'platform' => 3, 'overview' => "Marvin The Martian has developed an ultimate weapon that will allow him to finally destroy Earth, which will ultimately allow him to take control of the universe. Upon the demonstration of the weapon, a slight snag hinders Marvin from completing his devious deed. The Weapon is out of Atoms, which it runs on, so he sends his minions (All of which are characters from the Looney Tune universe) to gather Atoms to fuel his weapon.\r\n\r\nDuck Dodgers is informed by his academy of Marvin's deeds and sets out to find the one-hundred Atoms before Marvin can. This ultimately has Dodgers and his sidekick, Cadet, trekking to four different planets, including a large pirate ship, to obtain the upper-hand over Marvin.", 'youtube' => 'nshkM25meWM', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6423], 'genres' => [15], 'publishers' => [72], 'alternates' => ['Duck Dodgers', 'Looney Tunes: Duck Dodgers'], 'uids' => nil, 'hashes' => nil }, { 'id' => 266, 'game_title' => 'Mario Kart 64', 'release_date' => '1997-02-10', 'platform' => 3, 'overview' => "Three… Two… One… GO! The signal light changes and you drop the pedal to the metal. Take on up to three friends in the split-screen VS games, or race solo in the Mario GP. Tell your friends to bring it on in the highly competitive Battle mode. Advanced features allow you to race with your “Ghostâ€. The driving data from your best run appears as a transparent character on the screen. No longer must you simply race against the clock -- you can actually race against yourself!\r\n\r\n* Save your hottest Ghost data to a portable N64 Controller Pak!\r\n* Collect multiple power-up items!\r\n* Twenty different courses -- 4 Cups with 4 courses each and 4 special Battle mode courses!\r\n* Everyone’s favorite characters are back and gorgeously rendered, including two new additions, Donkey Kong and Wario!", 'youtube' => 'gHE0QEi6Ldc', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [7], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 267, 'game_title' => 'Madden NFL 99', 'release_date' => '1998-09-01', 'platform' => 3, 'overview' => 'This is all-Madden football! Legendary gameplay. One-button simplicity. The ultimate NFL experience. New super hi-res polygon graphics. Monster hits - feel and hear the impact! 250 new motion captured NFL moves. New Arcade Mode - huge hits, more fun! Over 120 past and present NFL teams. Draft, trade, create, sign, and release players.', 'youtube' => 'KzvYTzX6yW8', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2724], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 268, 'game_title' => 'Madden NFL 2001', 'release_date' => '2000-09-05', 'platform' => 3, 'overview' => 'Madden NFL 2001 includes several customizable modes. Players have the ability to create a play, create a player, run a franchise, and collect Madden Cards, allowing players to perform certain actions during gameplay (for example, adding 5th downs, or limiting the CPU-controlled team to 3rd downs). The cards can also alter individual player ratings, unlock special stadiums, and unlock Hall of Fame and All-Madden teams.', 'youtube' => 'VutS-9ISO_M', 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2590], 'genres' => [11], 'publishers' => [35], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 269, 'game_title' => 'Madden NFL 2002', 'release_date' => '2001-09-12', 'platform' => 3, 'overview' => "#1 for a reason! Return to glory: Relive the golden days of 16-bit Madden gameplay in Madden Classic mode. Kick off the season with the newest NFL team: Take the field with all 32 NFL teams including the expansion Houston Texans. A game within a game: Run or defend an improved 2-Minute Drill, now featuring Head-To-Head Challenge. Bang-Boom-Pow: Perfect the X's and O's with the help of John Madden in Training mode.", 'youtube' => 'kDP24O7-lOw', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1361], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 270, 'game_title' => 'Mario Party 2', 'release_date' => '2000-01-24', 'platform' => 3, 'overview' => "Mario and the gang are back for another round of Bowser-bashin' party action! Watch as your favorite Nintendo characters don different duds for each of the five all-new Adventure Boards! A slew of new tricks and devices bring new levels of challenge and excitement to board game play. New board maps, new Mini-Games, new action and new surprises means a whole new batch of fun! Get ready to unleash your best Hip Drops, hammer swings and high-flying high junks for another round of frenzied multi-player action!", 'youtube' => 'gsfO3t6rJUE', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3923], 'genres' => [1, 2, 6, 11], 'publishers' => [3], 'alternates' => ['Mario Party 2 (JP)'], 'uids' => nil, 'hashes' => nil }, { 'id' => 271, 'game_title' => 'Major League Baseball Featuring Ken Griffey, Jr.', 'release_date' => '1998-05-31', 'platform' => 3, 'overview' => "Make your dreams of becoming a Major Leaguer a reality! Hit a grand slam, pitch a no-hitter, go for the cycle and steal home - all in the same game! If that's not enough, check out the real-time stat tracking in over 30 major categories. Improve your team by making the right trades and picking up the best free agents. Major League Baseball Featuring Ken Griffey Jr. is so real, every pitch counts!", 'youtube' => 'YdYT5TO4ZSY', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [503], 'genres' => [11], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 272, 'game_title' => "NBA In the Zone '99", 'release_date' => '1999-04-07', 'platform' => 3, 'overview' => 'The only place for hoops action on the Nintendo 64! All 29 NBA teams and over 300 real NBA players. Eight different camera angles with adjustable zoom. Create a player and customize over 30 different categories. All-new motion captured animations - the most realistic ever! Advanced play-calling techniques. Pin-point passing lets you play like the pros! Three-point shootout and slam dunk contest!', 'youtube' => 'WDIdjk1unmE', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4765], 'genres' => [11], 'publishers' => [23], 'alternates' => ['NBA Pro 99'], 'uids' => nil, 'hashes' => nil }, { 'id' => 273, 'game_title' => 'Air Cavalry', 'release_date' => '1995-06-20', 'platform' => 6, 'overview' => 'A standard helicopter war-game, featuring the Air Cavalry division. The game is played in a third person view using mode 7 graphics, with the cockpit displayed in splitscreen. There are three campaign areas to fly in: Middle East, Indonesia, and Central America. There are also 2 player versus and co-op split-screen modes.', 'youtube' => 'PzAMqksAmP0', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8399], 'genres' => [1], 'publishers' => [73], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 274, 'game_title' => 'Animaniacs', 'release_date' => '1994-11-01', 'platform' => 6, 'overview' => 'Animaniacs is a video game that is based on the hit animated series of the same name. Unlike regular platform games, the player usually runs from the enemies rather than fighting them. Characters include Yakko, Wakko, and Dot, Pinky and the Brain, most of the supporting cast, as well as Ralph, the Warner Brothers studio guard. Animaniacs was made into two games which bore no relation to each other in terms of gameplay, despite both being made by Konami. One was for the Super Nintendo Entertainment System and the other was for the Sega Mega Drive/Genesis and Game Boy. The SNES and Mega Drive/Genesis version were released in 1994, and the Game Boy version in 1995.', 'youtube' => 'amg49S5W2a0', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4765], 'genres' => [15], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 275, 'game_title' => 'Ardy Lightfoot', 'release_date' => '1993-11-26', 'platform' => 6, 'overview' => "The story of the game is that the sacred rainbow has shattered into seven pieces and it's up to Ardy to obtain them all again. Whoever collects all seven pieces will receive one wish. An evil king named Visconti has already gotten one piece and is searching for the others. To this end he sends out various creatures and henchmen such as Beecroft, Catry and others. These creatures form the opponents for Ardy during the game. Ardy is assisted by friends along the way like the elder (unknown name), Nina, and a mysterious adventurer named Don Jacoby.", 'youtube' => '5qUg1B5SrS0', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [696], 'genres' => [1, 2], 'publishers' => [64], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 276, 'game_title' => 'Battle Clash', 'release_date' => '1993-06-21', 'platform' => 6, 'overview' => 'Battle Clash is a game that uses the Super Scope light gun peripheral. In this game, you fight in a futuristic version of the world as a warrior named Michael Anderson, who takes part in a competition simply known as the "Battle Game". Contestants in the Battle Game fight using mobile Standing Tanks (or STs for short), that come with a variety of weapon systems and forms.', 'youtube' => '', 'players' => 2, 'coop' => 'Yes', 'rating' => 'Not Rated', 'developers' => [6037], 'genres' => [8], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 277, 'game_title' => 'Super Bomberman', 'release_date' => '1993-09-01', 'platform' => 6, 'overview' => 'Super Bomberman is the first video game in the Bomberman series to appear on the Super Nintendo Entertainment System. It is also the first four-player game to be released on the Super NES.', 'youtube' => 'QGfgf4HkNqM', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3923], 'genres' => [1, 6], 'publishers' => [74], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 278, 'game_title' => 'Bugs Bunny Rabbit Rampage', 'release_date' => '1994-02-05', 'platform' => 6, 'overview' => 'Bugs Bunny Rabbit Rampage is a side-scrolling platform game. The player, controlling Bugs Bunny, is able to jump (and squash), high-kick, throw cream pies and use ACME weapons. These weapons are scattered all over the landscape and include such cartoon favorites as bone-shaped dynamite sticks, anvils to drop on heads, Shrink Rays, portable holes and many more. Players will encounter a variety of familiar Looney Tunes characters as enemies and level bosses. At the end of each level (10 in all). players are given a rating based on their gameplay style, which includes how many of these ACME weapons they were willing to use.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9342], 'genres' => [15], 'publishers' => [75], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 279, 'game_title' => 'Cacoma Knight in Bizyland', 'release_date' => '1993-06-01', 'platform' => 6, 'overview' => 'Cacoma Knight is a hybrid of action and puzzle elements. Each level is a single screen. The first image that the player sees is a landscape, for example, a forest or a town. The image will then fade into a "corrupt" version of the landscape, for example, the trees become rotten and buildings become ruined. Each screen has a "Qualify" target that shows how much of the screen must be cleared before the game continues to the next level.', 'youtube' => '', 'players' => 1, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [7625], 'genres' => [1], 'publishers' => [76], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 280, 'game_title' => "Congo's Caper", 'release_date' => '1992-12-18', 'platform' => 6, 'overview' => "Congo the monkey and his girl, Congette, were in the jungle minding their own business when a magic ruby dropped out of the sky and turned them both into half-humans. To make matters worse, the ruby also spawned a demon-kid who grabbed Congette and took off. Now you've got to hunt down the kid and find your girl, while adapting to your new form. You'll make your way through ghost towns, pirate ships, ninja castles, and the belly of a Tyrannosaurus on your search. There are 35 levels of side-scrolling action in all, and you'll have your hands full with tons of wild animals that will try to stand in your way. As you run, jump, swim, attack, and dive your way through the game, keep your eyes open for special gems that will give you special powers and open secret levels.", 'youtube' => nil, 'players' => 1, 'coop' => nil, 'rating' => 'E - Everyone', 'developers' => [2126], 'genres' => [1], 'publishers' => [55], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 281, 'game_title' => '3 Ninjas Kick Back', 'release_date' => '1994-06-19', 'platform' => 6, 'overview' => 'You first saw Rocky, Colt and Tum Tum on the silver screen when their martial arts skills and extreme exploits saved the honor of Grandfather Mori and defeated an evil arms dealer. Now, it’s up to you! In this action-packed adventure, you become any one of the 3 Ninjas. And that’s when the fun begins. Wild animals and even wilder ninjas attack! A trio of spaced-out heavy metal rockers join forces with the evil Koga in an all-out effort to do you dirty. But if you rescue Grandfather Mori and his ceremonial dagger, you’ll have the last laugh… and unlock a secret room filled with more gold than Fort Knox!', 'youtube' => '18Hcd8P61Wc', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5215], 'genres' => [1], 'publishers' => [77], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 282, 'game_title' => 'The 7th Saga', 'release_date' => '1993-08-03', 'platform' => 6, 'overview' => "THIS IS NOT YOUR ORDINARY RPG!\r\n\r\nThe graphics are eye-popping, breath-taking, stunning and unbelievable, not to mention incredible. This is no hack-and-slash, rip-your guts-out fighter! This is the future of RPGs, right here in your hands! With music this good, you won’t turn the sound off-you’ll turn it up!\r\n\r\nNo more small elves leading your team! This game contains real, believable figures. You won’t be embarrassed to use your own name; you’ll be proud. It’s just you against six other characters in search of the 7 Sacred Runes. Whoever finds them... Rules the World. It’s that simple, that easy. The only problem is you have some enemies, and I don’t mean a few. I mean an army of things you’ve never seen before ready to raise the hair on the back of your neck and take you out with one swing. This is one powerful RPG. Can you handle it?!", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [6797], 'genres' => [4], 'publishers' => [78], 'alternates' => ['Elnard', 'The 7th Saga'], 'uids' => nil, 'hashes' => nil }, { 'id' => 283, 'game_title' => 'Daffy Duck: The Marvin Missions', 'release_date' => '1993-10-01', 'platform' => 6, 'overview' => "In this game, Duck Dodgers sets out to stop Marvin the Martian from performing various notorious deeds, including destroying his beloved home-planet, Earth. There seems to be only one way to stop Marvin - and that's to destroy all five of his deadly machines!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4023], 'genres' => [1, 2], 'publishers' => [75], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 284, 'game_title' => 'Advanced Dungeons & Dragons: Eye of the Beholder', 'release_date' => '1994-03-18', 'platform' => 6, 'overview' => 'Something evil is lurking below the city of Waterdeep. The Lords of Waterdeep summon a group of heroes to investigate, but someone or something has been watching the proceedings. After the heroes enter the sewers, the ceiling collapses behind them. The only way out is the way down, into a dungeon filled with monsters, traps and puzzles.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [9596], 'genres' => [4], 'publishers' => [79], 'alternates' => ['Eye of the Beholder', 'AD&D: Eye of the Beholder'], 'uids' => nil, 'hashes' => nil }, { 'id' => 285, 'game_title' => 'Jeopardy!', 'release_date' => '1992-12-01', 'platform' => 6, 'overview' => 'Jeopardy! is an American quiz show featuring trivia in history, literature, the arts, pop culture, science, sports, geography, wordplay, and more. The show has a unique answer-and-question format in which contestants are presented with clues in the form of answers, and must phrase their responses in question form.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [4107], 'genres' => [5], 'publishers' => [80], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 286, 'game_title' => 'John Madden Football', 'release_date' => '1990-01-01', 'platform' => 18, 'overview' => "Game modes are the usual pre-season, regular season, sudden death and playoffs. A special playoff mode for the 8 greatest teams is also available.\r\n\r\nThe Genesis version features John Madden's digitized commentary speech and a battery-backed RAM for saving playoff results and player stats.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [2724], 'genres' => [11], 'publishers' => [2], 'alternates' => ['Pro Football', 'John Madden American Football'], 'uids' => nil, 'hashes' => nil }, { 'id' => 287, 'game_title' => 'Judge Dredd', 'release_date' => '1995-10-27', 'platform' => 6, 'overview' => 'Judge Dredd is a platform action game based on the British comic book character of the same name and the 1995 movie that tarnished that name. The game was a multi system release so it fits the standard console jump/shoot/duck formula although it does add some unique twists such as wounding enemies so that they surrender and can be arrested.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [196], 'genres' => [1], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 288, 'game_title' => 'Ka-Blooey', 'release_date' => '1992-01-01', 'platform' => 6, 'overview' => 'Bombuzal is a computer puzzle game produced by Antony Crowther. The game was released in 1988 for the Amiga, Atari ST and Commodore 64. It was also released in 1989 for MS-DOS and 1990 for the Super NES, with the American version renamed as Kablooey. Among its notable features was the ability to play using either an overhead or isometric view. To complete each level the avatar has to destroy all bombs on a level. Bombs come in different sizes and it is only possible to ignite the smallest kind without dying. The bombs have to be set off using a chain reaction to prevent the avatar being killed in the explosion.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [4641], 'genres' => [6], 'publishers' => [81], 'alternates' => ['Bombuzal'], 'uids' => nil, 'hashes' => nil }, { 'id' => 289, 'game_title' => "Krusty's Super Fun House", 'release_date' => '1992-06-01', 'platform' => 6, 'overview' => "Krusty the Clown's Fun House has been overrun by rats. You must help him to herd the rats into trap machines to clear them out. In order to do so, Krusty must manipulate his environment to set up pathways so that the rats are headed in the right direction. Objects that Krusty move around include blocks, fans, and pipe pieces.\r\n\r\nThe trap machines are operated by other recognizable Simpson's characters: Bart, Homer, Sideshow Mel, and Corporal Punishment.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [806], 'genres' => [15], 'publishers' => [28], 'alternates' => ['Krusty World'], 'uids' => nil, 'hashes' => nil }, { 'id' => 290, 'game_title' => 'Madden NFL 96', 'release_date' => '1995-11-30', 'platform' => 6, 'overview' => "Madden NFL '96 is a football video game designed for the 1995 NFL season, licensed by the NFL. It features John Madden on the cover. The AI has been boosted and can now hurry in two-minute drill situations, spike the ball, and cover the receivers with better efficiency. Among the innovations in Madden 96, the Create-a-Player feature was added, which included many position specific mini-games that would determine the ability of the player. The game also was the first in the Madden series to include secret \"classic\" teams, which were unlocked by playing any of the 28 pre-expansion NFL franchises in the playoffs and by winning Super Bowl XXX with that team (a rather easy feat as the playoff tournament system allows a player to abort the game while in the lead and still win). The 28 pre-expansion teams were each represented by a classic era equivalent, which ranged from 1960 (Philadelphia Eagles) to 1986 (New York Giants), although all players identified as number-only. Jacksonville Jaguars and Carolina Panthers, having debuted in 1995, did not have a secret classic team revealed in this manner, nor did the All-Madden team. However, Carolina was attached to the blank slate NFLPA team used for Create-a-Player, and Jacksonville and All-Madden hid the \"superteams\" with players named after the developers; these teams were accessed using unstated cheat codes.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8822], 'genres' => [11], 'publishers' => [82], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 291, 'game_title' => 'Madden NFL 97', 'release_date' => '1996-10-01', 'platform' => 6, 'overview' => "Welcome to Madden NFL 97, the game that captures the excitement of a 30 yard touchdown pass, the strategy of a well executed scoring drive, and the atmosphere of a crisp autumn afternoon in the stadium. Madden NFL 97 delivers state of the art graphics and sound -- and with modem and network support, it's ready to put your competitive skills to the test.", 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [2724], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 292, 'game_title' => 'Mega Man 7', 'release_date' => '1995-03-24', 'platform' => 6, 'overview' => "Dr. Wily's crusade to rule the world ends abruptly at the hands of Mega Man, so what's a villain to do? Create a diversion and break out of prison! Mega Man has his hands full as 4 gigantic machines exit Dr. Wily's lab to ravage the city, but... who is behind this new plot as Wily sits behind bars?\r\n\r\nDr. Wily knew his diabolical deeds would end an failure one day. So as hiss robots attack by remote control, the sinister doctor breaks out of prison and flies off in his spaceship. The Titanium Titan is tricked!\r\n\r\nWith the help of Rush, Roll and Dr. Light, can Mega Man put the slippery Dr. Wily back in prison where he belongs? The future of the world hangs on Mega Man's every move.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => ['Mega Man VII', 'RockMan VII: Showdown of Destiny!', 'ロックマン7 宿命ã®å¯¾æ±º!', 'Rockman 7: Shukumei no Taiketsu!'], 'uids' => nil, 'hashes' => nil }, { 'id' => 293, 'game_title' => 'NBA Live 95', 'release_date' => '1994-12-03', 'platform' => 6, 'overview' => "The first of the NBA Live titles on the PC, NBA Live 95 includes all of the basketball players from the '94 - '95 season as well as the All-Star teams from the East and West.\r\n\r\nManage over 300 players using the General Manager feature, new in this edition. Statistics for each player and team are saved. View players and teams side-by-side to compare stats and other information. You can trade any player in the league.\r\n\r\nMultiple in-game settings let you choose the mode of play, the style, and even the length of a quarter or session. Full motion videos bring your plays to life onscreen. Listen to the crowd roar, the noises of the court and hoop, and voices of the players. There is also a soundtrack of modern music.", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => nil, 'developers' => [3867], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 294, 'game_title' => 'NFL Quarterback Club 96', 'release_date' => '1995-11-01', 'platform' => 6, 'overview' => "This game is the next-gen update of NFL Quarterback Club.\r\n\r\nEvery team from the 1996 NFL season is shown here, with real player numbers and stats. 32 offensive plays and 16 defensive plays are available as you play. Options include setting quarter lengths, from one to 15 minutes, and selecting your mode of play: Preseason, Playoffs, or a full Season, in which you play 18 games towards the goal of the Super Bowl.", 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [4065], 'genres' => [11], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 297, 'game_title' => 'Scooby-Doo Mystery', 'release_date' => '1995-01-01', 'platform' => 6, 'overview' => "This version is different from it's Genesis counterpart. While the gameplay is similar (exploring levels to collect clues and solve the mystery), there are four different episodes for this version. While visiting the Drabwell Ranch, ghost's interrupt the festivities and the gang must find out who is behind the hauntings and why. Another adventure takes the gang to Deadman's Cove where a ghostly pirate has been scaring off tourists and it is up to Scooby and the Gang to bring it to a halt. The other two mysteries take place at a fun fair and a haunted mansion.\r\n\r\nPlayers can use Scooby's unique sniffing ability to find clues. Scooby also consume Scooby Snacks to reduce the fright meter. Additionally there are a series of mini-games that player can participate in such as \"Wac-A-Monster\" or \"Make a Scooby Sandwich\". The graphics are faithfully recreated to resemble the long-running Hanna Barbara series.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [8329], 'genres' => [2], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 298, 'game_title' => 'SkulJagger: Revolt of the Westicans', 'release_date' => '1992-10-01', 'platform' => 6, 'overview' => "Sküljagger: Revolt of the Westicans is a sidescrolling platform game. Players select between a 1 player game, an alternating turn 2 player game or Bubblegum Practice. The player controls Storm Jaxon who is able to run left and right, jump and swing Sküljagger's magic sword. Storm must reach the end of each level before time runs out or risk losing a life. Under normal circumstances, touching an enemy or projectile will cause him to die, though the sword is often able to destroy projectiles. By collecting red jewels, Storm is able to both augment the sword with a projectile attack and be protected from one enemy attack. Green jewels will also protect from one enemy attack, however collecting 25 of them will grant an extra life. Blue jewels add additional time for Storm to complete each level. Finding a mask will make Storm invulnerable for a short time. These power-ups are either floating in the air of each level or hidden away in chests, boxes, rocks and coconuts. However these items which may hide items can also be picked up and thrown at enemies.", 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [7050], 'genres' => [15], 'publishers' => [83], 'alternates' => ['Sküljagger: Revolt of the Westicans', 'SkulJagger'], 'uids' => nil, 'hashes' => nil }, { 'id' => 299, 'game_title' => 'Super Metroid', 'release_date' => '1994-04-18', 'platform' => 6, 'overview' => "Take on a legion of Space Pirates and a new Metroid force as you forge into the covert underworld of Planet Zebes! It’s up to you and Samus to recapture the long-surviving Metroid hatchling before evil hands unleash its energy.\r\n\r\nAn army of ominous creatures are poised for battle at every turn of Zebes’ twisted, threatening passageways… including the menacing Ridley and the great lizard Kraid. Knock down enemies with a killer somersault and swing on an electric beam through narrow passageways! They’re no match for you and Samus… but wait! It seems the Mother Brain has returned…", 'youtube' => 'yu9GiZjFejE', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4248], 'genres' => [1, 2], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 300, 'game_title' => 'Super Probotector: Alien Rebels', 'release_date' => '1992-04-06', 'platform' => 6, 'overview' => "The hideous Red Falcon, thought to have been destroyed long ago by the Earth's greatest commandos, Mad Dog and Scorpian, has risen again, this time pissed off and thirsty for revenge. His armies are marching through the cities, across the lands, and with the intention of exterminating the human race like a bad case of fleas. Two new commandos, Jimbo and Sully, have come forth now to kick Red Falcon's ass and save what remains of the world from his hideous plans!", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [4765], 'genres' => [1], 'publishers' => [23], 'alternates' => ['Contra III The Alien Wars'], 'uids' => nil, 'hashes' => nil }, { 'id' => 301, 'game_title' => 'The Great Circus Mystery Starring Mickey & Minnie', 'release_date' => '1994-06-02', 'platform' => 18, 'overview' => "The Great Circus Mystery Starring Mickey and Minnie, later titled Disney's Magical Quest 2 Starring Mickey & Minnie, was released for the Super Nintendo Entertainment System and Sega Genesis/Mega Drive in 1994 and for the Game Boy Advance in 2003. The game features Mickey Mouse and Minnie Mouse trying to figure out why everyone in the circus has disappeared, and includes four different types of outfits and six different levels. While the SNES and Genesis/Mega Drive versions were practically identical, the GBA re-release in 2003 included some new features. As its predecessor, it received praise for its graphics and outfit system and was criticized for not being challenging enough and short. Notably, it was the first game with Minnie Mouse in a video game role.", 'youtube' => '_7Iu_GOxsE0', 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [15], 'publishers' => [9], 'alternates' => ['Mickey to Minnie: Magical Adventure 2', 'The Great Circus Mystery'], 'uids' => nil, 'hashes' => nil }, { 'id' => 302, 'game_title' => 'The Itchy & Scratchy Game', 'release_date' => '1995-03-01', 'platform' => 18, 'overview' => "Itchy & Scratchy is a single player platform side-scroller. The player controls Itchy, the mouse, and must defeat Scratchy, the cat, with a variety of weapons. Itchy caries a default mallet, but can pick up additional weapons on particular levels. Each of the seven levels takes place in a different fictional location and is designed as a maze of doors and platforms. After defeating Scratchy, he usually will return with a special contraption to attack Itchy, and must therefore be defeated again. The game was developed for the Genesis but it was never commercially released. It was planned to be released on 1995 along with the \r\n Super NES and Sega Game Gear versions.", 'youtube' => 'https://www.youtube.com/watch?v=1DBlVpgauuY', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1098], 'genres' => [1], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 303, 'game_title' => '90 Minutes: European Prime Goal', 'release_date' => '1995-08-04', 'platform' => 6, 'overview' => "90 Minutes: European Prime Goal is a Super Nintendo Entertainment System soccer video game. The player(s) get to play in either exhibition, tournament, or in the all-star mode. The view is from a left-right perspective and the national flags of several European countries are used in the game. In the game mode \"You're a Hero,\" the player must make miracle plays that either win and/or change the game. The kick-off is doing using 3D graphics with the camera showing the spectators in the grandstand.\r\n\r\nThis game is a sequel to J.League Soccer Prime Goal 2 and J.League Soccer Prime Goal, which were both developed by Namco.", 'youtube' => 'AZnG1FOj_7w', 'players' => 2, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [5804], 'genres' => [11], 'publishers' => [39], 'alternates' => ['J.League Soccer: Prime Goal 3'], 'uids' => nil, 'hashes' => nil }, { 'id' => 304, 'game_title' => '2020 Super Baseball', 'release_date' => '1993-03-12', 'platform' => 6, 'overview' => "Welcome to the year 2020, where baseball has evolved into a contest between human and machine! Enter the futuristic Cyber Egg Stadium and test your skill in 2 world-class leagues with a total of 12 different teams! Step up to the plate and play the most mind-blowing baseball game ever seen:\r\n\r\n* Collect money for great plays and use it to boost your player armor or energize your robots!\r\n* Use your Rocket Pack to jump 50 feet into the air and catch that homerun ball!\r\n* Test your batting skill against an eye-popping 200 mph curveball!\r\n* Check out the awesome graphics, exciting sound and realistic gameplay for 1 or 2 players!\r\n* Use the password feature and resume playing at any point during the season! Follow the computer as it tracks all player stats!\r\n\r\nSuper Baseball 2020: You're traveling into the future of baseball and you won’t want to come back!", 'youtube' => 'LZOu7l3kSy8', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7885], 'genres' => [11], 'publishers' => [60], 'alternates' => ['Super Baseball 2020', '2020 Toshi no Super Baseball'], 'uids' => nil, 'hashes' => nil }, { 'id' => 305, 'game_title' => 'A.S.P. - Air Strike Patrol', 'release_date' => '1995-01-01', 'platform' => 6, 'overview' => 'Zarak has invaded Sweit! You, as Air Force commander, MUST marshall all your resources and defeat them. Using hi-tech intelligence, locate your targets, load your plane, and destroy... chemical weapon plants, radar sites, enemy vehicles, and more. So strap yourself into a cockpit and fly into the challenge of a lifetime.', 'youtube' => '8ivLHu0j_aU', 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [7624], 'genres' => [8], 'publishers' => [76], 'alternates' => ['Desert Fighter'], 'uids' => nil, 'hashes' => nil }, { 'id' => 306, 'game_title' => 'AAAHH!!! Real Monsters', 'release_date' => '1995-08-15', 'platform' => 6, 'overview' => 'In this game, based on popular Nickelodeon comics, you control three monsters: Ickis, Oblina, and Krumm. The Gromble, a headmaster in monster school, needs you to perform the final test - monster Midterm Exam - in order to prove yourselves to be real monsters. You should collect trash, throw it on people, and scare them!', 'youtube' => 'r7oH7-t0EHI', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7050], 'genres' => [1, 2], 'publishers' => [86], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 308, 'game_title' => 'Dead Space 2', 'release_date' => '2011-01-25', 'platform' => 1, 'overview' => 'Engineer Isaac Clarke returns for another blood-curdling adventure in Dead Space 2, the sequel to the critically acclaimed horror adventure. After waking from a coma on a massive space city known as "The Sprawl," the lone survivor of a horrific alien infestation finds himself confronting a catastrophic new nightmare. Battling dementia, hunted by the government and haunted by visions of his dead girlfriend, Isaac will do whatever it takes to save himself and rid the city of the gruesome, relentless Necromorphs. Equipped with a new arsenal of tools to dismember the Necromorphs, Isaac will face the challenge head-on.', 'youtube' => 'https://www.youtube.com/watch?v=z7Qy_4sWs3I', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9428], 'genres' => [8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 309, 'game_title' => 'Crysis Warhead', 'release_date' => '2008-09-12', 'platform' => 1, 'overview' => "Crysis Warhead, like the original Crysis, is set in 2020, when an ancient alien spacecraft is uncovered on the fictional Lingshan Islands, east of the Philippines. The singleplayer campaign has the player assume the role of a member of Raptor Team, a squad of mostly American soldiers outfitted with cutting-edge technology. Specifically, they play the role of former Delta Force operator Sergeant Michael Sykes, referred to in-game by his callsign, \"Psycho\". \r\nPsycho was a supporting character in Crysis, in which players played one of his Raptor Team squadmates, Jake \"Nomad\" Dunn. Psycho's arsenal of futuristic weapons builds on those showcased in Crysis, with the introduction of Mini-SMGs which can be dual-wielded, a six-shot grenade launcher equipped with EMP grenades, and the destructive, short ranged Plasma Accumulator Cannon (PAX). The highly versatile Nanosuit, which confers various superhuman abilities upon its wearer, returns. In Crysis Warhead, the player follows a \"secret mission\" Psycho was sent on roughly halfway through the original game, to retrieve a mysterious cargo container held by the North Koreans, believed to contain a nuclear warhead. During this mission, Psycho fights North Korean and extraterrestrial enemies in many different locations, such as a tropical island jungle, inside an \"Ice Sphere\", an underground mining complex, and finally, to an airfield.", 'youtube' => 'https://www.youtube.com/watch?v=P3WTQ4_N2mA', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1970], 'genres' => [1, 8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 310, 'game_title' => 'Aliens vs. Predator', 'release_date' => '2010-02-16', 'platform' => 1, 'overview' => "In the all-new Aliens vs. Predator for PC players will have the chance to take the role of the three infamous species; the Colonial Marine, the Predator and the Alien. Each of the three species has its very own distinct story-driven single-player campaign mode that interweaves with the campaigns of the other two species. Aliens vs. Predator on PC will also feature unique 3-way online multiplayer, allowing gamers to pit the three species against each other in the ultimate battle for survival and for the right to be crowned the deadliest species.\r\n\r\nAliens vs Predator for PC features:\r\n\r\n * On planet BG-386 a colonist mining group discovers an ancient pyramid containing a dark and horrible secret. Across the stars a race of warriors is alerted to the discovery of their pyramid and a hunting party is dispatched to ensure that it remains sealed at all costs, whilst deep inside the ruined pyramid a malevolent intelligence awakes from centuries of dormancy.\r\n\r\n * The Marine's story is an incredible fight against the odds, and the horrors lurking in the dark. Beset on all sides yet armed to the teeth, the Colonial Marine represents humanity's last stand with the firepower to fight back.\r\n\r\n * As the Alien, players will discover what it's like to be the most murderous and lethal creature in the universe, with the ability to traverse any surface with awesome agility in order to get close enough to unleash its deadly teeth and claws.\r\n\r\n * A master of the hunt, the Predator grants the player a suite of exotic weaponry and equipment with which to stalk its unknowing prey. Earn the greatest honour by ambushing prey up-close and butchering them for a gory trophy kill.", 'youtube' => 'https://www.youtube.com/watch?v=12GOiCWuiNs', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7061], 'genres' => [1, 8], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 311, 'game_title' => 'Fallout: New Vegas', 'release_date' => '2010-10-19', 'platform' => 1, 'overview' => "Experience all the sights and sounds of fabulous New Vegas, brought to you by Vault-Tec, America's First Choice in Post-Nuclear Simulation. Explore the treacherous wastes of the Great Southwest from the safety and comfort of your very own vault: Meet new people, confront terrifying creatures, and arm yourself with the latest high-tech weaponry as you make a name for yourself on a thrilling new journey across the Mojave wasteland. A word of warning, however - while Vault-Tec engineers have prepared for every contingency, in Vegas, fortunes can change in an instant. Enjoy your stay.", 'youtube' => 'l-x-1fm2cq8', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [6195], 'genres' => [1, 2, 4, 8], 'publishers' => [34], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 313, 'game_title' => 'Warhammer 40,000: Dawn of War II - Chaos Rising', 'release_date' => '2010-03-11', 'platform' => 1, 'overview' => "Your Blood Ravens have saved the sector, but can they save themselves? In THQ Inc. and Relic Entertainment's sequel to the acclaimed Dawn of War II real time strategy franchise, you return to sub sector Aurelia where a long lost frozen ice planet has reappeared from the Warp, bringing with it new secrets to uncover and foes to face. In Dawn of War II: Chaos Rising you will take command of the Blood Ravens and defend the sector against the Chaos Space Marines of the Black Legion. Purge the chaos filth and hold the chapter together as traitorous forces work from within to try bring down the Blood Ravens. Upgrade your squads with new legendary wargear and unlock new special abilities, as your squads advance to level 30. Will you remain steadfast to the Emperor or risk heresy to gain new dark and destructive powers? In multiplayer swear loyalty to the Chaos Gods and pit your bloodthirsty warband of Chaos Space Marines against the new units and reinforced armies of the Space Marines, Orks, Eldar, and Tyranids.", 'youtube' => 'https://www.youtube.com/watch?v=U99KPnZd0CA', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7131], 'genres' => [6, 10], 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 314, 'game_title' => 'Super Spike V-Ball & Nintendo World Cup', 'release_date' => '1990-02-01', 'platform' => 7, 'overview' => "2 in 1 game. Super Spike V'Ball / Nintendo World Cup was a pack-in game included with the Nintendo Entertainment System Sports Set. The package included a standard NES console, four game controllers, and the Four Score Multiplayer Adapter. The cart included two games developed by Technos: # Super Spike V'Ball, a two-on-two beach volleyball game where you played on a tournament, ending with the world championship. The game supported up to four players on one match at a time; # Nintendo World Cup, a soccer game where you (and a friend) chose to represent a team and played several matches until you won the World Cup. The game featured little to no rules, which means that you could hit your opponents as much as you want, without fear of the Ref getting in the way. Both games were compatible with the included Four Score NES multiplayer adapter.", 'youtube' => 'unbaUXyVymA', 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8606], 'genres' => [11], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 315, 'game_title' => '3-D WorldRunner', 'release_date' => '1987-09-12', 'platform' => 7, 'overview' => "The battle of a lifetime comes alive in 3-D! The wildest of the space cowboys is out looking for adventure. Now he's got it and he needs your help. A strange world terrorized by Grax, the Alien Serpentbeast, has asked you, Worldrunner, for help. Knowing you can outrun, outjump and outblast anyone or anything, you race into battle. But this is no ordinary fight. These battles will carry you to eight strange planets filled with bottomless pits, shooting stars, and poisonous aliens, all sworn to defend their Serpent King. And each new world is ruled by an Alien Serpentbeast more terrifying and more powerful than anything you've ever seen before. Are you ready, Worldrunner? They're waiting for you!", 'youtube' => 'ETXonCYjSuM', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8096], 'genres' => [8], 'publishers' => [28], 'alternates' => ['The 3-D Battles of WorldRunner', 'Tobidase Daisakusen'], 'uids' => nil, 'hashes' => nil }, { 'id' => 316, 'game_title' => '8 Eyes', 'release_date' => '1990-01-01', 'platform' => 7, 'overview' => "CONTROL MAN AND BIRD IN A FIGHT FOR THE EIGHT JEWELS OF POWER!\r\n\r\nAfter hundreds of years of chaos, mankind has finally emerged from the ruins of nuclear war. This world of the distant future has once again fluorished under the guidance of the Great King, who harnessed the power of the 8 Eyes to rebuild the planet.\r\n\r\nThese strange jewels of power were formed at the eyes, or centers, of the eight nuclear explosions which nearly destroyed the Earth. In the wrong hands, the 8 Eyes could cause untold destruction...And now, they have been seized by the Great King's eight Dukes, in a desperate bid to gain control of the world for themselves. They have banished the King to the nuclear wastelands, and already their squabbling threatens to plunge the world into war once again!\r\n\r\nThe task of retrieving the 8 Eyes falls to you, Orin the Falconer, the bravest and mightiest of the King's Guardsmen. With your fighting falcon, Cutrus, you must penetrate each of the eight Dukes' castles. There you will face the Dukes' soldiers, and battle strange nuclear mutants such as living skeletons, giant wasps, and mud men. You must defeat the monstrous Boss of each castle to retrieve the Jewel of Power he guards.\r\n\r\nThen, to complete your quest, return the 8 Eyes to the Altar of Peace to await the return on the Great King, so that he may finish the rebuilding of Earth. Your reward will be the the eternal gratitude of all mankind!", 'youtube' => 'Y-jxDeo5JPc', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [8787], 'genres' => [2], 'publishers' => [87], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 317, 'game_title' => '10-Yard Fight', 'release_date' => '1985-10-18', 'platform' => 7, 'overview' => 'The game is viewed in a top-down perspective and is vertical scrolling. The player does not select plays for either offense or defense. On offense, the player simply receives the ball upon the snap and either attempt to run with the quarterback, toss the ball to one of two running backs, or throw the ball to the one long distance receiver - basically the option offense. On defense, the player chooses one of two players to control, and the computer manipulates the others. The ball can also be punted or a field goal can be attempted.', 'youtube' => '90PSN3lEuGY', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [11], 'publishers' => [3], 'alternates' => ['10ヤードファイト'], 'uids' => nil, 'hashes' => nil }, { 'id' => 318, 'game_title' => "Assassin's Creed II", 'release_date' => '2009-11-17', 'platform' => 1, 'overview' => "Betrayed by the ruling families of Italy, a young man embarks upon an epic quest for vengeance. To eradicate corruption and restore his family's honor, he will study the secrets of an ancient Codex, written by Altair. To his allies, he will become a force for change - fighting for freedom and justice. To his enemies, he will become a dark knight - dedicated to the destruction of the tyrants abusing the people of Italy. His name is Ezio Auditore di Firenze. He is an Assassin.", 'youtube' => 'R20-MOOZPpY', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9149], 'genres' => [1, 2], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 319, 'game_title' => 'Heavy Rain', 'release_date' => '2010-02-23', 'platform' => 12, 'overview' => 'Experience a gripping psychological crime thriller filled with innumerable twists and turns, where even the smallest actions and choices can cause dramatic consequences. The hunt is on for the Origami Killer, named after his calling card of leaving folded paper shapes on victims. Four characters, each with their own motives, take part in a desperate attempt to stop the killer from claiming a new victim.', 'youtube' => 'XsGJOmATjKM', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [6898], 'genres' => [2], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 320, 'game_title' => 'Minecraft', 'release_date' => '2011-11-18', 'platform' => 1, 'overview' => 'Minecraft is a sandbox building video game which allows players to build constructions out of textured cubes in a 3D world. The gameplay is inspired by Dwarf Fortress, Roller Coaster Tycoon, Dungeon Keeper, and Infiniminer.', 'youtube' => 'm_yqOoUMHPg&hd=1', 'players' => 4, 'coop' => 'Yes', 'rating' => 'E10+ - Everyone 10+', 'developers' => [5658], 'genres' => [1, 2, 3, 12], 'publishers' => [88], 'alternates' => ['MC'], 'uids' => nil, 'hashes' => nil }, { 'id' => 321, 'game_title' => 'Wrecking Crew', 'release_date' => '1985-06-18', 'platform' => 7, 'overview' => "The player controls Mario and attempts to destroy all of a certain set of objects with a large hammer on each of 100 levels. Mario cannot jump because of the hammer's weight. Each level takes place on a playfield divided into an invisible grid, each space of which can contain one object. Objects include destructible walls, pillars, and ladders, indestructible barrels and ladders, bombs that destroy all connected destructible objects, and various enemies that Mario must avoid. Doors may also exist, which can be opened to cause enemies to move harmlessly into the background.", 'youtube' => 'https://www.youtube.com/watch?v=XClZDdTzo-E', 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [6037], 'genres' => [1, 5], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 322, 'game_title' => 'Wrath of the Black Manta', 'release_date' => '1990-04-02', 'platform' => 7, 'overview' => "Big Apple crime is rotten to the core. Now, there's only one way to keep the peace. The way of the Ninja! Introducing the deadliest fighting skills the game world has ever seen! Ten awesome powers, including: Art of Invisibility. Disappear and become invulnerable to attack. Art of Fire Ring: incinerate enemies caught in your deadly ring of fire. Art of Teleportation: Freeze time to reposition yourself and surprise attackers.", 'youtube' => 'https://www.youtube.com/watch?v=7DZLNepMAxw', 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [296], 'genres' => [1], 'publishers' => [56], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 323, 'game_title' => 'Wolverine', 'release_date' => '1991-10-10', 'platform' => 7, 'overview' => "Stranded on a remote, deserted island by his arch enemies, Sabretooth and Magneto, Marvel Comics' Wolverine must fight the battle of his life. Super-human powers, including regenerative healing abilities, an indestructible Adamantium skeleton and retractable razor sharp claws that slice through anything, make Wolverine a terrifying adversary... but has he finally met his match? Lead Wolverine in this world-class struggle against Sabretooth and the evil genius, Magneto. In the heat of battle, fellow X-Men Havok, Jubilee and Psylocke come to your side helping even out the score. To survive, you must complete 9 missions, including The Battle for the Skies, Trial by Fire, Trial by Water, The Dungeon of Traps, and The Land of Nightmares, until, at long last, you face your ultimate foes. Prepare for the most exciting and unpredictable X-Men adventure of them all!", 'youtube' => 'https://www.youtube.com/watch?v=WN8DnJR5UD8', 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [7940], 'genres' => [1, 15], 'publishers' => [89], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 324, 'game_title' => 'Track & Field II', 'release_date' => '1989-06-01', 'platform' => 7, 'overview' => "The greatest athletes from around the world have gathered for the grandest sporting spectacle since the golden age of Greece. This pressure-packed competition is as fierce as a starved lion. Surviving is a matter of sweat and concentration in Taekwondo, pole vaulting, canoeing, skeet shooting, hammer throwing, high diving, archery, hurdles, gymnastics, hang gliding, pistol firing, arm wrestling, fencing, triple jumping and swimming... Whew! Wears you out just to read them all. The odds in Vegas say you don't have enough strength, stamina or skill, but you know better. And as long as you win, you're the crowd favorite. But lose, and you might as well turn in your jockstrap and joystick.", 'youtube' => 'https://www.youtube.com/watch?v=BRayDY9xFRc', 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [4765], 'genres' => [11], 'publishers' => [23], 'alternates' => ['Track and Field 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 325, 'game_title' => 'Track & Field', 'release_date' => '1987-04-20', 'platform' => 7, 'overview' => "This ain't no 20-minute workout. It's the ultimate in head-to-head competition, in 8 grueling events. 100 meter dash. Long jump. Hurdles. Javelin. Skeet shooting. Triple jump. Archery. And the high jump. No timeouts, no breathers, no water boys. Just you and your own exhaustion. So get psyched. Pick your level of competition and the opening event. Then block out the roar of the crowd and take a deep breath. Because it's not whether you win or lose. It's whether you survive!", 'youtube' => 'https://www.youtube.com/watch?v=Jm0AoAJ3TF0', 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [4765], 'genres' => [11], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 326, 'game_title' => '720 Degrees', 'release_date' => '1986-12-19', 'platform' => 7, 'overview' => "Hop on and hang ten as you crash around corners, swerve on sidewalks, and leap over the locals at Skate City, a skateboarder's fantasy world where virtually every surface is skateable. Flip and twist around the street fighters, Frisbee throwers, hard bodies and killer bees that jam city streets. Polish your skills and take your act to the skate parks where you'll vie for medals and cash in downhill, jump, ramp, and slalom competition. Shoot the tubes, \"catch air\" as you fly off ramps - master all of the moves including the dangerous 720. You'll need every edge as you try to become champion of the skating world!", 'youtube' => 'MgMCDBQnSlE', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1], 'genres' => [11], 'publishers' => [90], 'alternates' => ['720°'], 'uids' => nil, 'hashes' => nil }, { 'id' => 327, 'game_title' => 'The Adventures of Bayou Billy', 'release_date' => '1988-08-12', 'platform' => 7, 'overview' => "The player takes control of the title character, Billy West, who must fight save to his girlfriend Annabelle Lane from the gang of Godfather Gordon. There are a total of ten stages in all: six side-scrolling beat-em-up stages (or street fighting stages, as the game actually dubs them), two light gun shooting (shoot-'em-up) stages, and two action driving stages.", 'youtube' => 'CUZcbojyLBs', 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [4765], 'genres' => [1, 7, 8], 'publishers' => [23], 'alternates' => ['Mad City', 'マッド・シティ'], 'uids' => nil, 'hashes' => nil }, { 'id' => 328, 'game_title' => 'Adventures of Lolo', 'release_date' => '1989-04-20', 'platform' => 7, 'overview' => "Prince Lolo of Gentryland visited Eden, a country of love and peace, and enjoyed many pleasant days with Princess Lala of Eden. But one day, Egger, the King of Darkness, who had an evil plot to conquer Eden, spirited the Princess away before Lolo's eyes.\r\nAfter a long and difficult journey, Lolo has come to the evil Castle of the Labyrinth. The castle is guarded by an army of evil monsters led by Egger, the King of Darkness.\r\n\r\nCan Lolo solve the seemingly endless series of mazes and save Lala? Lolo is not gifted with strength or agility, but has great courage and patience. Now the battle of wits begins. Good luck, Lolo!", 'youtube' => 'Jsfkf8l3XnA', 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [3694], 'genres' => [1, 5], 'publishers' => [91], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 329, 'game_title' => 'Airwolf', 'release_date' => '1989-06-19', 'platform' => 7, 'overview' => "Deep within enemy territory, your fellow countrymen are imprisoned. Only one man in the free world would dare attempt to save them. You, Stringfellow Hawke, commander of Airwolf. And yet, as you strap yourself into the cockpit of your supersonic jet copter, you know this is the most dangerous assignment you have ever flown.\r\n\r\nYour mission is mapped out. Airwolf's heat-seeking missiles and superpowered machine guns are fired up, ready to blow the terrorists away. But can you evade enemy radar time after time? Can you sneak behind the enemy lines, find the captives and bring them to safety before you crash land or worse?\r\n\r\nHeadquarters knows that you have the skill and firepower it takes. You say you've got the guts... now prove it!", 'youtube' => 'https://www.youtube.com/watch?v=WqjGPqU70tw', 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [194], 'genres' => [1, 8, 13], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 330, 'game_title' => 'Asterix', 'release_date' => '1993-01-01', 'platform' => 7, 'overview' => "OBELIX has disappeared...\r\n\r\nThe peace and quiet of the small village of indomitable Gauls is broken by a disturbing piece of news: Obelix has failed to return from his wild boar hunt. The village council convenes and Asterix decides to set off to find his friend.\r\n\r\nLeave with him and travel throughout Gaul, across the Roman Empire, taking your search as far afield as the Egyptian Pyramids...\r\n\r\nAnd as you battle with the Roman armies and avoid the traps set by Caesar's spies, perhaps you will find Obelix.\r\n\r\nMagic potion, Romans, fights, punches, catapults, wild boar, not forgetting that fish that's not quite \"fresh\"...\r\n\r\nRELIVE THE ADVENTURES OF ASTERIX THE GAUL!", 'youtube' => 'A1GeF2LBn7s', 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [1097], 'genres' => [15], 'publishers' => [72], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 331, 'game_title' => 'Back to the Future Part II & III', 'release_date' => '1990-12-31', 'platform' => 7, 'overview' => "Get ready for a wild romp through time, Marty McFly, 'cause you're about to take off on a double mission to save the past, present and future! Better load up on pizza and soda as you rocket to the year 2015 in Doc's supercharged time machine. Hang on to your hi-speed hoverboard as you teach Biff Tannen a thing or two about stealing your Sports Almanac, and locate the special objects he's hidden throughout time. Then, if your flux capacitor isn't on the fritz, it's off to the Wild West, where sharp shootin' gunslingers want you out of town by sundown. The fate of the world -- not to mention generations of McFly's -- is in your hands... and you're out of time!", 'youtube' => 'https://www.youtube.com/watch?v=IO8ela7UbXQ', 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [67], 'genres' => [1, 2, 5], 'publishers' => [89], 'alternates' => ['Back to the Future II & III', 'Back to the Future 2 & 3', 'Back to the Future Part 2 & 3'], 'uids' => nil, 'hashes' => nil }, { 'id' => 332, 'game_title' => 'Bad Dudes', 'release_date' => '1989-07-14', 'platform' => 7, 'overview' => 'The game starts in New York City, where President Ronnie (based on former U.S. President Ronald Reagan) has been kidnapped by the nefarious DragonNinja. The intro says: "Rampant ninja related crimes these days... Whitehouse is not the exception...". As soon as that occurs, a Secret Service agent (who resembles Arnold Schwarzenegger as he appears in The Terminator) asks two street-smart brawlers, named Blade and Striker: "President Ronnie has been kidnapped by the ninjas. Are you a bad enough dude to rescue Ronnie?", which this quote became an infamous meme and is often lampooned on the Internet. In the Japanese version, however, the words are completely different. After they heard that, the Bad Dudes confirmed it by pursuing the DragonNinja through the city streets, highway, sewers, transport train, forest, cave and into the secret ninja base, in order to save President Ronnie.', 'youtube' => 'https://www.youtube.com/watch?v=gPYJsxeQOMc', 'players' => 2, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [2126], 'genres' => [10], 'publishers' => [39], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 333, 'game_title' => 'Balloon Fight', 'release_date' => '1985-01-02', 'platform' => 7, 'overview' => "The player controls the unnamed Balloon Fighter with two balloons attached to his back. Repeatedly pressing the A or B buttons causes the Balloon Fighter to flap his arms and rise into the air. If a balloon is popped, the player's flotation is decreased, making it harder to rise. A life is lost if both balloons are popped by enemy Balloon Fighters, if the player falls in the water, gets eaten by the large fish near the surface of the water, or is hit by lightning.", 'youtube' => 'lAuwf_JiIo4', 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [6037], 'genres' => [1], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 334, 'game_title' => "The Bard's Tale", 'release_date' => '1991-11-01', 'platform' => 7, 'overview' => 'Long ago, when magic still prevailed, the evil wizard Mangar the Dark threatened a small but harmonious country town called Skara Brae. Evil creatures oozed into Skara Brae and joined his shadow domain. Mangar froze the surrounding lands with a spell of Eternal Winter, totally isolating Skara Brae from any possible help. Then, one night the town militiamen all disappeared. The future of Skara Brae hung in the balance. And who was left to resist? Only a handful of unproven young Warriors, junior Magic Users, a couple of Bards barely old enough to drink, and some out of work Rogues. You are there. You are the leader of this ragtag group of freedom fighters. Luckily you have a Bard with you to sing your glories, if you survive. For this is the stuff of legends. And so the story begins...', 'youtube' => 'R6EkbfgXqWg', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [4287], 'genres' => [4], 'publishers' => [2, 3282], 'alternates' => ["The Bard's Tale - Tales of the Unknown"], 'uids' => nil, 'hashes' => nil }, { 'id' => 335, 'game_title' => 'Baseball', 'release_date' => '1983-12-07', 'platform' => 7, 'overview' => "Baseball is a simple baseball video game made by Nintendo in 1983 for the Nintendo Family Computer, making it one of the first games released for the Famicom. It was later one of the NES's 18 launch titles when it was released in 1985 in the United States. As in real baseball, the object of the game is to score the most runs. Up to two players are supported. Each player can select from one of six teams. Although there is no difference between them other than uniform color, they are meant to represent the six members of the Japanese Central League.", 'youtube' => '3RxgAJ4qtgY', 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [6037], 'genres' => [11], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 336, 'game_title' => 'Bases Loaded II: Second Season', 'release_date' => '1989-01-01', 'platform' => 7, 'overview' => "The game is the second installment of the Bases Loaded series. The series spanned three generations of consoles and eight total installments. The original Bases Loaded title was an arcade game that Jalelco ported to the NES. Only the original Bases Loaded was an acrade game; the rest of the series were exclusive to their particular consoles. There are four video games in the Bases Loaded NES series, Bases Loaded II: Second Season, Bases Loaded 3 and Bases Loaded 4. There was also a Game Boy version of Bases Loaded. The series continued onto the SNES platform with Super Bases Loaded, Super Bases Loaded 2, and Super Bases Loaded 3. The final entry to the series was Bases Loaded '96: Double Header, released for the fifth generation consoles Sega Saturn and PlayStation.", 'youtube' => 'FaUk0DCgBI4', 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [8959], 'genres' => [11], 'publishers' => [94], 'alternates' => ['Bases Loaded 2 Second Season', 'Bases Loaded 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 337, 'game_title' => 'Batman: The Video Game', 'release_date' => '1990-02-01', 'platform' => 7, 'overview' => "He's totally new. Totally tough. And he'll stop at nothing to make sure justice prevails! From the dark streets of GOTHAM CITY to the deepest corners of the criminal underworld comes the CAPED CRUSADER as you've never seen him before. Incredibly strong. Armed to the teeth. And ready to put his life on the line for the sake of all, on a search-and-destroy mission to end the Joker's reign of terror. He leaps, he flies, he dodges enemy fire and delivers it right back... with a vengeance. This is no kid stuff. This is as real as video gaming gets. If you liked what you saw in the movie, you're gonna love what you see here. Because this time around, BATMAN is all business, and he won't let anything stand in his way!", 'youtube' => 'https://www.youtube.com/watch?v=SLV9RHXnceg', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8329], 'genres' => [1], 'publishers' => [75], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 338, 'game_title' => "Castlevania II: Simon's Quest", 'release_date' => '1988-12-01', 'platform' => 7, 'overview' => "Castlevania was a cakewalk compared to this bloody curse. You thought you had the Prince of Darkness defanged - eh, Simon Belmont? Well think again, 'cause according to a damsel in distress, evil Count Dracula has left a horrifying curse in his wake. And the only hope you have of ending the terror is to destroy his missing body parts! Talk about your frightening quest, searching a maze of mansions, graveyards and dark, eerie forests - each guarded by man-eating werewolves, fire-throwing zombies and other devilish demons. Your grim chances are kept alive in Transylvania, where cowardly villagers offer clues to the whereabouts of Dracula's remains. And where you'll purchase magic weapons, including silver knives and flame whips. But beware the night. For when the sun disappears, Dracula's curse grows deadlier. And your chances grow dimmer and dimmer.", 'youtube' => 'KK9Im7YtDz8', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4765], 'genres' => [1, 2, 15], 'publishers' => [23], 'alternates' => ['Castlevania 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 339, 'game_title' => "Castlevania III: Dracula's Curse", 'release_date' => '1990-09-01', 'platform' => 7, 'overview' => "Led by the immortal Count Dracula, the greatest army of evil ever assembled is poised to bury mankind in a Tomb of Terror. Destroying this legion of Swamp Dragons, Slasher Skeletons and Forces of the Undead will be the supreme challenge for the mightiest of warriors. Your place in history is 100 years before Simon Belmont's birth. Dracula is young at heart, and it will take more than a stake to penetrate his evil. Luckily, you command the role of Trevor - Simon's forefather and the origin of the Belmont Warlord Chromosomes. Trevor has a power never before seen by human eyes - the power to transform into three different spirits: Grant DaNasty, the ferocious Ghost Pirate. Sypha, the Mystic Warlord. And Alucard, Dracula's forgotten son. You must perfectly time Trevor's body transformations to match up his different fighting spirits against Ultimate Evils. Trevor also has the strength and wisdom to command the Battle Axe, Invisibility Potion and Mystic Whip. But the most important weapon Trevor has is your cunning to choose the correct Paths of Fate and your bravery to lead him past 17 possible levels of never-ending doom, including the Haunted Ship of Fools, the Sunken City of Poltergeists, the Clock Tower of Untimely Death and Curse Castle. Never before have so many dangers confronted you at one time. And if by some miracle you triumph, you'll no longer be a mere mortal. You'll be a legend who'll live forever!", 'youtube' => 'Bw7D2YKg1T4', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4765], 'genres' => [1, 2, 15], 'publishers' => [23], 'alternates' => ['Castlevania 3', '悪魔城ä¼èª¬ AkumajÅ Densetsu', 'Legend of the Demon Castle', 'AkumajÅ Densetsu'], 'uids' => nil, 'hashes' => nil }, { 'id' => 340, 'game_title' => 'Clu Clu Land', 'release_date' => '1984-11-22', 'platform' => 7, 'overview' => "Clu Clu Land's story starts with a type of Sea Urchin, the Unira, stealing all of the treasures in the underwater kingdom of Clu Clu Land. Bubbles, the hero, sets out to retrieve the treasure. The object of the game is to uncover all the gold bars in each stage while avoiding the Unira and Black Holes.", 'youtube' => 'https://www.youtube.com/watch?v=SE2BOjengNc', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [5], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 341, 'game_title' => 'Crystalis', 'release_date' => '1990-04-13', 'platform' => 7, 'overview' => "You must save the world from evil magic by finding the four powerful swords that form Crystalis.\r\n\r\nAfter the apocalypse, magic returns to Earth.\r\n\r\nA blessed group of good-intentioned sorcerers have used their new magical powers to rebuild the Earth, but an evil sorcerer named Dragonia has combined his supernatural forces with man-made technology to devastate the rebuilt Earth. It is your mission to recover four mystical swords, and combine them to form the ultimate blade: the Sword of Crystalis. This legendary weapon is the only tool which can put an end to Dragonia's black reign.", 'youtube' => 'https://www.youtube.com/watch?v=8DWu_BVeg5E', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7885], 'genres' => [1, 2, 4], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 342, 'game_title' => 'Double Dragon II: The Revenge', 'release_date' => '1988-12-01', 'platform' => 7, 'overview' => "The Double Dragons - Billy and Jimmy Lee - are back to avenge the loss of Marion! In their quest to defeat the evil Shadow Warriors, the martial arts duo are challenged in 9 incredible missions, facing ruthless street gangs, nunchaku-toting ninja and giant mutant warriors! The non-stop action winds its way through construction sites, alleyways and underwater hideouts complete with secret elevator shafts, spiked ceilings and razor-sharp mechanical claws! And in a bonus mission, never before seen, the duo's worst fear becomes reality as they fight the ultimate battle between good and evil. A battle where not only their lives are at stake, but the fate of the entire world!", 'youtube' => 'https://www.youtube.com/watch?v=NkuB2PWJssY', 'players' => 2, 'coop' => 'Yes', 'rating' => nil, 'developers' => [8607], 'genres' => [1], 'publishers' => [95], 'alternates' => ['Double Dragon 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 343, 'game_title' => 'Double Dribble', 'release_date' => '1987-09-01', 'platform' => 7, 'overview' => "Finally, it's here! The basketball game you've dreamed of. The first home game with 5 on 5, full court, board-banging action. A contest with graphics so real, they'll knock your high-tops off. Ready to captain your team to the title, you bolt into the arena with electricity in your fingers and ice in your veins. Intensity builds. The crowd roars. The game is yours to win or lose. But to win you'll need speed in the lane, touch for three-pointers, muscle to power past picks, and the skill to crash the glass. And, if you break free underneath - watch out! Because now you can power home a rim-rockin' slam! So pull up your shorts and take a deep breath. It's crunch time. Time to show your stuff!", 'youtube' => 'v-PUj1H52ko', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4765], 'genres' => [11], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 344, 'game_title' => 'Dr. Mario', 'release_date' => '1990-10-14', 'platform' => 7, 'overview' => 'A puzzle game similar to Tetris, Dr. Mario features Nintendo mascot Mario as a doctor. Gameplay consists of dropping two-sided vitamin capsules into a playing field 8 blocks wide by 16 blocks high resembling a medicine bottle, populated by viruses of three colors', 'youtube' => 'rSYfo8PwLQU', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6051], 'genres' => [5], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 345, 'game_title' => 'Dragon Warrior', 'release_date' => '1989-08-01', 'platform' => 7, 'overview' => "Dragon Warrior uses console role-playing game mechanics which were described by Kurt Kalata of Gamasutra as archaic in 2008. The player takes the role of a namable Hero. The Hero's name has an effect on his statistical growth over the course of the game. Battles are fought in a turn-based format and experience points and gold are awarded after every battle, allowing the Hero to level-up in ability and allows them to buy better weapons, armor, and items. Progression consists of traveling over an overworld map and through dungeons, fighting monsters encountered via random battles along the journey.\r\n\r\n\" As a whole, Dragon Warrior has been credited with establishing the basic template for the Japanese console RPGs that followed. \" -Wikipedia", 'youtube' => '1qL5_3EhqK8', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1637], 'genres' => [2, 4], 'publishers' => [3], 'alternates' => ['Dragon Quest (JP)'], 'uids' => nil, 'hashes' => nil }, { 'id' => 346, 'game_title' => 'Duck Hunt', 'release_date' => '1984-04-21', 'platform' => 7, 'overview' => 'In Duck Hunt, players use the Nintendo Zapper Light Gun and attempt to shoot down either ducks or clay pigeons in mid-flight.', 'youtube' => '-1NyIsZXeqU', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [8], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 347, 'game_title' => 'Dynowarz: Destruction of Spondylus', 'release_date' => '1989-04-01', 'platform' => 7, 'overview' => "Something was terribly wrong in the distant man-made Spondylus Solar System. One by one the planet's central life support computers had been infected with a life threatening virus while the planet surfaces had been overrun with computerized dinosaurs known as Robosaurs. Under attack in his laboratory on Alpha Planet, Professor Proteus, the mastermind of the Spondylus System and the founder of the Robosaur project suddenly realized that this deadly sabotage could only be the work of his former partner, the deranged Dr. Brainius.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [900], 'genres' => [1, 2], 'publishers' => [57], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 348, 'game_title' => 'Elevator Action', 'release_date' => '1987-08-01', 'platform' => 7, 'overview' => 'The player assumes the role of a spy who infiltrates a building filled with elevators. He must collect secret documents from the building and traverse the 30 levels of the building using an increasingly complex series of elevators. The player is pursued by enemy agents who appear from behind closed doors. The player must outwit them via force or evasion. Successful completion of a level involves collecting all the secret documents and traversing the building from top to bottom. In the lower floors of the building, the elevator systems are so complex that some puzzle-solving skills are needed.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [8449], 'genres' => [1], 'publishers' => [56], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 349, 'game_title' => "Ghosts 'n Goblins", 'release_date' => '1986-09-19', 'platform' => 7, 'overview' => "The beautiful princess is kidnapped. Her lover, the Knight in shining armor, armed with five different weapons to fight the enemy, sets out to rescue the beautiful princess. The Knight, aided by your skill, must pass through seven different guarded gates, fighting and destroying demons, dragons, giants and zombies. There are hidden characters, too! Some friends, some foes. Ghosts 'N Goblins is exciting... challenging you and the Knight to rescue the princess, amid great danger, escaping Hades, land of the enemies!", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [2], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 350, 'game_title' => 'Golf', 'release_date' => '1984-05-01', 'platform' => 7, 'overview' => "Nintendo GOLF lets you choose your clubs, change your stance, control your swings - even select the angle of impact! You'll view the hole from both close up and far away, judge the changing conditions of the green, and measure the wind velocity. But watch out! When the wind changes, so does the flight of your ball. With Nintendo's state-of-the-art graphics and realistic game play, you'll really believe you're on the fairways. So play Nintendo GOLF, because there's not a video golf game on par with it anywhere!", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [11], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 351, 'game_title' => 'Gumshoe', 'release_date' => '1986-06-06', 'platform' => 7, 'overview' => "Jennifer's been kidnapped! Now's your chance to prove you're a sharp-shooting detective by helping Jennifer's father find the five diamonds that will pay her ransom. You'll use your Zapper light gun to blow away anything that gets in your way. But even with the Zapper, this case will be hard to crack. Because not only are the diamonds hard to find, but you only have 24 hours to find them! What's more, you'll have to think fast and shoot even faster, because ferocious monsters, diving airplanes and hungry man-eating sharks will stop at nothing to prevent you from getting to the diamonds. Think you're a sharp-shooting detective? Well, you better be. Because if you're not, it's curtains for you in this quick-on-the-trigger Nintendo Light Gun game!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [6037], 'genres' => [1], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 352, 'game_title' => 'Heavy Barrel', 'release_date' => '1990-03-02', 'platform' => 7, 'overview' => 'Heavy Barrel is a shooter with a top-down view similar to Commando and Ikari Warriors. Terrorists have seized the underground control complex of a nuclear missile site. It is up to the player to infiltrate the installation and eliminate the leader of the terrorist army before they can launch the missiles. To stop the terrorists you will need the powerful weapon Heavy Barrel. The problem is that the weapon still is in the installation. Before the fortress fell the weapon was taken apart and locked in six different storage lockers. To defeat the terrorists you must collect all keys and reassemble the weapon. The game supports co-op for two players.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2126], 'genres' => [6], 'publishers' => [55], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 353, 'game_title' => 'Hudson Hawk', 'release_date' => '1992-02-01', 'platform' => 7, 'overview' => 'The player assumes the role of Hudson Hawk, a cat burglar. He is sent on a mission to steal three Da Vinci artifacts. Walking through various levels in this platform game, the player must avoid sounding alarms. In addition, security guards and dogs show up to hamper the mission. Hudson Hawk can pacify the enemies by punching them or throwing a "ball" at them.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8039], 'genres' => [1], 'publishers' => [43], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 354, 'game_title' => 'Jackal', 'release_date' => '1986-06-27', 'platform' => 7, 'overview' => 'The Jackal squad, a four-man team composed of Colonel Decker, Lieutenant Bob, Sergeant Quint and Corporal Grey, is sent to rescue soldiers kept as hostages by the enemy. One or two players control the teams in an armed jeep, which must venture through several enemy strongholds to rescue comrades imprisoned by the enemy. In each of the six levels, the goal is to rescue POWs from various buildings and then transfer them to helicopter dust-off locations. Once the soldiers are secure, the player(s) must then proceed to defeat the boss at the end of each level. In the last level, there are two bosses that must be defeated.', 'youtube' => 'https://www.youtube.com/watch?v=DADsaTZPwmA', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4765], 'genres' => [8], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 355, 'game_title' => "King's Knight", 'release_date' => '1986-09-18', 'platform' => 7, 'overview' => 'Four brave warriors have set out into the Kingdom of Izander to rescue Princess Claire from the grip of a fiendish Dragon. Through five thrilling, fast-action stages, our gallant heroes, a Knight, a Wizard, a Monster, and a Thief, will take on incredible enemies. Join in and help this tough team reach their goal!', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [8096], 'genres' => [1], 'publishers' => [11], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 356, 'game_title' => 'Low G Man: The Low Gravity Man', 'release_date' => '1990-09-01', 'platform' => 7, 'overview' => 'You are the Low Gravity Man! When powered up, you can jump one and three quarters screens high. Capture and use enemy vehicles, including the spider vehicle which can crawl on ceilings. Catch and power up enemy weapons, and much, much more. Your mission is to take back the robot-producing exploration planet from the evil aliens before they reprogram all of the robots for the destruction of the human race. Includes password, infinite continue, and multiple quests for long-term enjoyment!', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [8529], 'genres' => [15], 'publishers' => [87], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 357, 'game_title' => 'Lunar Pool', 'release_date' => '1985-12-05', 'platform' => 7, 'overview' => 'Lunar Pool is the first advanced home video billiards game ever. Never before has the player been able to choose among 60 different "tables." Jump around to your favorite, or master each stage consecutively. Your score is kept automatically. You set up the electronic cue stick, aim the cue ball, choose the power you need and shoot! Then watch the ball ricochet around the "table" and land in the pocket. Learn to be a "hustler" by mastering all 60 stages!', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [1785], 'genres' => [11], 'publishers' => [96], 'alternates' => ['Lunar Ball'], 'uids' => nil, 'hashes' => nil }, { 'id' => 358, 'game_title' => 'Mach Rider', 'release_date' => '1985-10-18', 'platform' => 7, 'overview' => "Grip the handles of your futuristic motorcycle. Feel the freezing wind crack against your cheeks. Suddenly you're off! Riding at speeds up to 500 miles per hour in a desperate attempt to save the planet. You'll love every hair pin curve because you've created this daredevil course yourself. Along the way you'll be challenged by an endless array of ruthless villains who will do everything in their power to destroy you and your planet. You'll defend yourself with a specially mounted Power Blaster. But watch out! The action is fast. The danger is imminent. Design your own course or ride one of ours, in this lightning fast Nintendo Programmable game!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [6053], 'genres' => [7], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 359, 'game_title' => 'Marble Madness', 'release_date' => '1989-03-01', 'platform' => 7, 'overview' => "The idea is deceptively simple: Guide a marble down a path without hitting any obstacles or straying off the course. The game is viewed from an isometric perspective, which makes it harder to stay focused on the direction the ball is to follow. There are tight corridors to follow and enemies to avoid. There is a 2-player mode in which players must race to the finish; otherwise you're racing against the clock.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [6991], 'genres' => [5], 'publishers' => [97], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 360, 'game_title' => 'Mega Man', 'release_date' => '1987-12-17', 'platform' => 7, 'overview' => "It's MEGA MAN versus the powerful leaders and fighting forces of Monsteropolis - that strange multi-layered land of robot-like humanoids created by the wrongly-performed experiments with human beings by Dr. Wily. Mega Man - the chosen defender of the human race. For he dares to single-handedly penetrate Monsteropolis' seven separate societies to stop the rapid expansion of strange misrepresentations of humans.\r\n\r\nMega Man's goal is monumental. He must infiltrate seven separate heavily-guarded empires. By himself, he must break down and destroy the following empire leaders: Cutman, Gutsman, Iceman, Bombman, Fireman, Elecman, and Dr. Wily. The action involves Mega Man armed only with laser beam weapons, encountering strangely-configured humanoids. They're atop, in and out of fortified prison-like structures strengthened with thick walls. Hidden amid gun turrets embedded in concrete uprights, even in subterranean passages below icefields. WOW!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => %w[Rockman Megaman], 'uids' => nil, 'hashes' => nil }, { 'id' => 361, 'game_title' => 'Mega Man 2', 'release_date' => '1988-11-24', 'platform' => 7, 'overview' => "He's Back! And this time the evil Dr. Wily (once the supreme power in the universe) has created even more sinister robots to mount his attack. But as MegaMan, you've also grown in power and ability. Can you save mankind from the evil desires of Dr. Wily? Each of the eight empires is ruled by a different super-robot. You must defeat each enemy on his own turf, building up weapons as you go. Only after all are destroyed will you go head-on with the mastermind himself, the evil Dr. Wily.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => ['Rock Man 2', 'Megaman 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 362, 'game_title' => 'Mega Man 3', 'release_date' => '1990-09-28', 'platform' => 7, 'overview' => "It's robot rebellion, and nobody's safe! Least of all, Mega Man! This time the superpowerful cyborg takes on a horde of metal maniacs who've had it with being obedient! And they use every android-annihilator ever invented to make you believe it! Mega Man goes berserk, blasting through a galaxy of mining stations in search of energy crystals. But it takes more than guts to battle the phenomenal robot masters who control these worlds. It's a wrenching job, the worst - and the best - that Mega Man's faced so far!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => ['Rock Man 3', 'Megaman 3'], 'uids' => nil, 'hashes' => nil }, { 'id' => 363, 'game_title' => 'Mega Man 4', 'release_date' => '1991-12-06', 'platform' => 7, 'overview' => "For a year the city has been quiet, but a new robotic terror has gripped the city! That scheming scientist, Dr. Cossack has arrived in town with eight new metal maniacs who are bigger and badder than anything Dr. Wily dreamed of. It's going to be a cybernetic showdown as the streets of the city erupt with the sizzling sounds of molten metal! Armed with the new Mega Buster, Mega Man runs, jumps and dodges his way through mazes of metallic munchkins on his way to the Siberian citadel of Dr. Cossack for the final cataclysmic clash!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => ['Rockman 4: Aratanaru Yabou!!', 'Megaman 4'], 'uids' => nil, 'hashes' => nil }, { 'id' => 364, 'game_title' => 'Mega Man 6', 'release_date' => '1992-10-06', 'platform' => 7, 'overview' => "From the United States, Canada and Japan they came. The world's premier designers and their finest robotic warriors traveled to do battle in the First Annual Robot Tournament. But what began as a game suddenly took a terrifying twist! On the eve of the Grand Championship, the sponsor of the event announced that the entire tournament was just an elaborate scheme to get his hands on the world's most powerful robots! Now faced with an army of metallic mercenaries, Mega Man must fight a ferocious new foe - The Mysterious Mr. X!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => ['Rockman 6: Shijou Saidai no Tatakai!!', 'Megaman 6'], 'uids' => nil, 'hashes' => nil }, { 'id' => 365, 'game_title' => 'Metal Gear', 'release_date' => '1987-07-07', 'platform' => 7, 'overview' => "Outer Heaven leader CaTaffy has activated the ultimate super weapon: Metal Gear! Responding to the crisis, covert unit \"Fox Hound\" is called into action, and that's where you come into play. Trained in hand-to-hand combat and skilled in every weapon known to man, you're Fox Hound's lethal fighting machine, code named \"Solid Snake\". But on this mission you better be sly as well, to surprise heavily-armed enemies, busting 'em up quietly and rescuing their hostages before alarms are triggered. Plus you gotta maintain radio contact with Commander South, who'll feed you crucial info on Metal Gear's whereabouts. To survive, capture sub-machine guns, Barettas, grenade launchers, and plastic explosives, until you find and destroy Metal Gear, ending CaTaffy's reign of terror!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [4765], 'genres' => [1, 6], 'publishers' => [98], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 366, 'game_title' => "Snake's Revenge", 'release_date' => '1990-04-13', 'platform' => 7, 'overview' => "After his ironclad plan to rule the world rusted away, crazed Colonel Vermon CaTaffy went psycho. Unfortunately, your two best friends took the brunt of his frenzy and lost their fight to live. As nutty as ever, CaTaffy has sought asylum from the world's premiere bad guy - Higharolla Kockamamie. Grateful to this 'Rolla Radical, the Colonel has donated the biggest, baddest Ultra-Sheik Nuclear Attack Tank to his fellow madman's world dominating cause. \r\n\r\nNow your mission is to not only save Earth, but to inflict revenge. It's a job you'll definitely take personally as you infiltrate a nation of armed lunatics. Blow up a battleship. Hijack a train. Locate dozens of weapons and a truth serum that'll force enemy commanders to spill their guts. Then, destroy Vermon, Higharolla and the Earth Threatening Device with one lethal blow. All this, while staying in radio contact with a foxy spy named Jennifer and a Stealth copter pilot who'll be hovering nearby. So whaddaya think, Snake - are you commando enough to handle this Kockamamie scheme?", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [4765], 'genres' => [1], 'publishers' => [98], 'alternates' => ["Metal Gear: Snake's Revenge"], 'uids' => nil, 'hashes' => nil }, { 'id' => 367, 'game_title' => 'Mission: Impossible', 'release_date' => '1990-09-01', 'platform' => 7, 'overview' => "Need we say more?\r\nUltra® Dares you to defy the impossible. But if you accept, be forewarned. You and your trio of Impossible Mission Force agents will infiltrate a six level maze of unthinkable danger. A fortress of international evil designed to sap every ounce of your brains and brawn. At each turn you must fend off snipers and fire bomb maniacs. Elude spy cameras and robot sentries. Escape from countless enemies in hot pursuit. All in your desperate search for booby-trapped clues, secret ID cards and life-saving switches.\r\n Any why? Because the worldwide terrors known as the Sinister Seven have kidnapped Dr. \"O,\" his nuclear military defense system and IMF agent Shannon Reed, and now they threaten to wreak planetary chaos.\r\n Luckly, your agents are well schooled in the art of espionage and possess their own favored firepower, from rifles to remote control cluster bombs. But that's no guarantee you'll make it past brutes like Slash Stiletto, Blitz Blizzardski and the Iron Claw. If by chance you do, there's always the hyper speedboat chases through Venice, hand grenade ski runs down the Swiss Alps, and prison camps in the Pyrenees mountains.\r\n Remember, should you choose to accept this mission and fail, you, your Nintendo®, and the world will self-destruct in five seconds.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [4765], 'genres' => [1, 2, 8], 'publishers' => [98], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 368, 'game_title' => 'MULE', 'release_date' => '1990-09-01', 'platform' => 7, 'overview' => 'IRATA. A New World rich with opportunity. For wealth. And power. And you can become the richest, most powerful inhabitant of the newly discovered planet by owning the most land, mining the most precious metal, and supplying the most food and energy to all the peasants - otherwise known as your opponents. To win you need MULEs (Multiple Use Labor Elements), kind of mechanical donkeys which do your dirty work: growing food, mining, and producing energy. MULEs are critical, so you want to get as many as possible as cheaply as possible. And by the way, treachery is acceptable. So use it when needed. Then sit back and enjoy your wealth and power, OH MIGHTY RULER!', 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => nil, 'developers' => [6350], 'genres' => [6], 'publishers' => [90], 'alternates' => ['M.U.L.E.'], 'uids' => nil, 'hashes' => nil }, { 'id' => 370, 'game_title' => 'Ninja Gaiden II: The Dark Sword of Chaos', 'release_date' => '1990-05-01', 'platform' => 7, 'overview' => 'Dynamic action scenes! Split your body into three, destroy all enemies with the Invincible Fire Wheel and other new Ninja fighting techniques! Ninja Gaiden II gives you the feel of real Ninjutsu! Exciting cinema display format! Ninja Gaiden II uses the same Cinema Display Format as the original. The fiendish plot unfolds in a movie-like sequence. Action, drama, revenge. Just wait till you get to the end!', 'youtube' => '7itFTOXi278', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [8614], 'genres' => [1, 15], 'publishers' => [24], 'alternates' => ['Ninja RyÅ«kenden II: Ankoku no Jashin Ken (JP)', 'Legend of the Ninja Dragon Sword II: The Demonic Sword of Darkness (JP)', 'Shadow Warriors II: The Dark Sword of Chaos (EU)', 'Shadow Warriors 2', 'Ninja Gaiden Episode II: The Dark Sword of Chaos'], 'uids' => nil, 'hashes' => nil }, { 'id' => 371, 'game_title' => 'Paperboy', 'release_date' => '1988-12-01', 'platform' => 7, 'overview' => 'Hop on your bike for a free-wheeling ride up the avenues of not-so-typical suburbia. There are papers to be delivered, robbers to be foiled, and fame and fortune to be won as you brave the mean streets. Avoid motorcycles, tricycles, traffic, tires, gratings, curbs, dogs, skateboarders, breakdancers, bad guys, and other hazards as you deliver to your customers. Earn bonus points by hitting targets along the obstacle course at the end of your route. With superb animation and sound effects, Paperboy brings home all the thrills, spills, challenge, and excitement you loved in the arcades.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [8654], 'genres' => [1], 'publishers' => [90], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 372, 'game_title' => 'Pinball', 'release_date' => '1985-10-01', 'platform' => 7, 'overview' => "Be a pinball wizard, right in your own home!\r\n Bank off bumpers, flip double flippers - even win a bonus round - in Nintendo's lightning-fast PINBALL! You'll have the time of your life as you flip from upper to lower game screens, rack up points to beat your opponent, and, if you're lucky, progress to the bonus round where you'll save the falling maiden in this video version of the real thing!", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [6037], 'genres' => [1], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 373, 'game_title' => 'Pinball Quest', 'release_date' => '1990-06-30', 'platform' => 7, 'overview' => "Don't let the name fool you - Pinball Quest is much more than video pinball. In fact, it's the first-ever multi-screen fantasy in a pinball format! Every move you make tells a story; every shot takes you another step closer in your quest to rescue the captive princess of the castle. Along the way you'll meet ghosts, goblins, witches and demons, in an endless labyrinth of treacherous passages and deadly doorways. It takes a fearless heart and a fast mind to conquer Pinball Quest. It also takes the skills of a true pinball wizard... which you can hone on the three other video pinball games included on this cartridge! So before you pour any more money into your NES library, get the one title that's a library all by itself! No matter how hard you try, you can't get enough of Pinball Quest!", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => nil, 'developers' => [4411], 'genres' => [1], 'publishers' => [94], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 374, 'game_title' => 'Predator', 'release_date' => '1989-04-01', 'platform' => 7, 'overview' => "Predator is a side-scrolling platformer which uses the imagery and characters from the classic Arnie movie of the same name. The game is not a faithfully conversion of the movie however - your unit has already been killed off when the game starts and you will battle scorpions, enemy soldiers and dodge obstacles etc, before facing the Predator itself a number of times.\r\n\r\nThe game is a fairly standard run-jump-shoot platformer, except that you start with no weapons at all and must collect them as the game goes on.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [234], 'genres' => [1], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 375, 'game_title' => 'RoboCop', 'release_date' => '1989-08-25', 'platform' => 7, 'overview' => "A sadistic crime wave is sweeping through old Detroit. The situation is explosive - in fact, it is so bad, a private corporation, O.C.P., has assumed control of the police force. Then, a research team creates an unstoppable, indestructible law enforcement cyborg - named RoboCop. Using a wild assortment of weapons, including RoboCop's Special Issue Auto-9, you must stop every sleazeball criminal you encounter with deadly, piercing accuracy. But beware, there are forces on the street - and within O.C.P. - that will stop at nothing to see RoboCop eliminated. Make your way past 6 levels of street thugs, Boddicker and the powerful ED-209 to your final battle with Dick Jones. Prepare yourself for non-stop action in one of the most explosive games you will ever play. It's going to take more than a cop to clean up the scum of old Detroit - it's going to take RoboCop. \"Your move, creep.\"", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [10_213, 10_214, 10_215], 'genres' => [8], 'publishers' => [55], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 376, 'game_title' => "Rush'n Attack", 'release_date' => '1989-06-08', 'platform' => 7, 'overview' => "Up for a little guerilla warfare? You asked for it. You're behind enemy lines, armed with only a knife and a mission: to free dozens of POWs hidden in an isolated, well-armored camp. If you're good, you'll pick off the heavily-armed enemy guerillas, one by one, and grab their bazookas and hand grenades. If you're great, you'll turn their weapons against them, to blow away a pack of attack dogs, a fleet of choppers, and a whole battalion of guards. But make one mistake, and it's all over. For you, our POWs... the future of the Free World!", 'youtube' => 'https://www.youtube.com/watch?v=AudtO3Dp8z0', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4765], 'genres' => [15], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 378, 'game_title' => 'Skykid', 'release_date' => '1986-01-01', 'platform' => 7, 'overview' => "You are the legendary Red Baron, flying a plane through a horizontal side-scrolling scenery set during World War I. To complete a mission, you simply need to get to the landing spot on the other side without being shot down, but you can gain extra points by destroying enemy vehicles and planes. For huge points, pick up a bomb hidden in the level (you will be warned by a sound when approaching it) and drop it on a large structure. If you fail to land on the landing strip, you run out of fuel and crash.\r\n\r\nYou can only shoot horizontally and diagonally by tilting the plane's nose. When in trouble, perform an aerial loop with the secondary button, this often destroys other planes and avoids bullets. There is a co-op mode with the character Max as well.", 'youtube' => nil, 'players' => 2, 'coop' => 'Yes', 'rating' => nil, 'developers' => [5804], 'genres' => [13], 'publishers' => [75], 'alternates' => ['Sky Kid'], 'uids' => nil, 'hashes' => nil }, { 'id' => 379, 'game_title' => 'Slalom', 'release_date' => '1987-01-01', 'platform' => 7, 'overview' => 'In Slalom you need to ski down different trails and beat the clock to move on to the next of the 24 trails. Other skiers, trees, snowmen, sledders, and moguls will get in your way and slow you down if you crash into them. Slalom flags are located throughout the trails, and skiing on the wrong side of these will cause your player to snowplow momentarily and lose speed, so to get the best times you need to make sure none of the flags are missed.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [6991], 'genres' => [11], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 380, 'game_title' => 'Spider-Man: Return of the Sinister Six', 'release_date' => '1992-10-15', 'platform' => 7, 'overview' => 'Doctor Octopus is plotting the crowning caper of his criminal career... to rule the world. He has reunited the Sinister Six and with these super-villains together again, nothing stands in their way - except Spider-Man!', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [1120], 'genres' => [1], 'publishers' => [89], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 381, 'game_title' => 'Star Wars', 'release_date' => '1991-11-15', 'platform' => 7, 'overview' => 'Only the people who made the movie could bring you this much action and adventure... Control your favorite Star Wars heroes - Luke Skywalker, Han Solo, Princess Leia. Enlist the help of Obi-Wan Kenobi, C-3PO, and R2-D2. Outfight and outsmart the intergalactic bad guys - stormtroopers, jawas, Banthas, bounty hunters, sinister droids, and more. Explore the spectacular worlds of Star Wars - from the Tatooine Desert to the Mos Eisley Spaceport to inside the Death Star. And if you get very, very good... destroy the Death Star and save the Rebel Alliance from Darth Vader!', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [67], 'genres' => [1], 'publishers' => [243, 8192], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 382, 'game_title' => 'Super Spy Hunter', 'release_date' => '1991-01-01', 'platform' => 7, 'overview' => "The Super Spy Hunter has a super spy car. It's actually a well-armed car that can turn into a boat or a plane at opportune times. The action is fast vertical scrolling as the vehicle faces all manner of powerful vehicle threats from a well-funded terrorist enemy -- cars, trucks, helicopters, etc. Luckily, there are many powerups to collect along the way, both defensive and offensive.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [8903], 'genres' => [1], 'publishers' => [104], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 383, 'game_title' => 'Teenage Mutant Ninja Turtles', 'release_date' => '1989-12-31', 'platform' => 7, 'overview' => "Carnivorous robots chow-down in China Town, while brutal Ninjitsu Warriors, blood descendants of the deadly \"Foot\" Clan, bust-up bystanders from the Bronx to Broadway. Police SWAT Teams can't stop them, but the Teenage Mutant Ninja Turtles can! 'Cause, powered by slices of pizza, they're always ready to rumble - with nunchukus, Katana Blades, and a party bus loaded with Anti-Foot Clan Missiles. So team up with the turtles, Raphael, Leonardo, Michaelangelo and Donatello, then switch on the tortoise radar, following your map and sixth sense past savage traps and secret sewage passages. Knock heads with the nasty Ninjitsu and either splatter them senseless or get yourself turned into turtle soup!", 'youtube' => 'https://www.youtube.com/watch?v=IS1TFKuSuzQ', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4765], 'genres' => [1, 2], 'publishers' => [98], 'alternates' => ['Teenage Mutant Hero Turtles'], 'uids' => nil, 'hashes' => nil }, { 'id' => 384, 'game_title' => 'Tennis', 'release_date' => '1985-10-01', 'platform' => 7, 'overview' => "Whether it's singles or doubles you'll love the non-stop action of this amazingly real tennis game!\r\n\r\n Slam a serve, fire a blazing backhand, smash a forehand volley - you call the shots in Nintendo TENNIS! Nintendo lets you choose an opponent from five different skill levels. So as your game improves, so does your playing partner! Plus, you can actually gauge the speed of your serve! The better your timing, the faster it moves across the net. You'll have hours of fun rushing the net, playing the baseline or roaming the court. With Nintendo's state-of-the-art graphics and realistic game play, you'll really believe you're at center court!", 'youtube' => nil, 'players' => 2, 'coop' => 'Yes', 'rating' => nil, 'developers' => [6037], 'genres' => [11], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 385, 'game_title' => 'The Battle of Olympus', 'release_date' => '1990-03-28', 'platform' => 7, 'overview' => "This is an ancient story - a time when men and gods lived together. The peaceful village of Elis was the home of the fairest maiden and a gentle yet brave young man named Orpheus. Helene and Orpheus swore eternal love to each other. But alas, one day, Helene fell victim to the fangs of a venomous serpent and was turned to stone. Your adventure will take you through ancient Greece on a classic mythological quest. It may be easy to defeat the snakes and centaurs that inhabit most of the cities but how will you defeat Hydra? Or the terrible three-headed dog, Cerberus? You'll need to use all of your adventuring skills to find the magic items that will allow you to rescue your beloved Helene.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [4185], 'genres' => [1, 2], 'publishers' => [105], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 386, 'game_title' => 'The Punisher', 'release_date' => '1994-01-01', 'platform' => 18, 'overview' => "Join Frank Castle's crusade for justice and revenge in this port of the arcade beat 'em up. Based on the Marvel comic of the same name, you play as the cold blooded vigilante or his pal Nick Fury (from S.H.I.E.L.D.) with your mission being to tear through the many rackets and underground criminal hotspots to cripple the Kingpin's criminal empire, and finally take down the man himself and bring peace to New York.\r\n\r\nThe game plays as a standard side-scrolling beat 'em up with your objective being to clear all stages of enemies by attacking them with your arsenal of attacks or whatever weapons you can find. Features single and 2-player cooperative gameplay.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 387, 'game_title' => 'Tiger-Heli', 'release_date' => '1987-10-01', 'platform' => 7, 'overview' => "Tiger Heli is the name of your helicopter, according to the box the result of a billion-dollar defense project and forged from ebony metal and glistening chrome. Your goal is to defeat the country of Cantun, which is run by terrorists and has become completely power hungry with an aim to take over the whole world.\r\n\r\nYou're shooting tanks, ships, aircraft carriers and trains while flying towards the impenetrable military base. You shoot crates to get pickups. If you shoot the crate when it is green you get a bomb pickup, if you shoot it when it is red you get a mini helicopter that attaches to one of your sides shooting sideways, and if you shoot it when it is white you get a mini helicopter shooting forward. If you shoot 10 crates with a yellow diamond shape you get an extra life.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [6749], 'genres' => [8], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 388, 'game_title' => 'Time Lord', 'release_date' => '1990-09-01', 'platform' => 7, 'overview' => 'It is the year 2999, and warriors from the planet Drakkon are launching a savage attack on Earth. Their weapon: a powerful time travel device. Their objective: to control us by changing the course of our history. To win this war, we must meet the Drakkons on a unique and dangerous battleground: our own past! You are a fearless fortune-hunter, hired by desperate scientists for an experimental journey into the 4th dimension. Your code name is Time Lord. Your mission: blast into the past to save the present from certain doom! Battle the aliens in four historical time zones. Search for weapons sent back by the scientists - and decide when to use them. Solve puzzles to collect the mysterious Orbs that hold the secret of time travel. Be cautious yet quick, Time Lord. You have one short year to free history or be history! And the evil Drakkons have all the time in the world...', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [6991], 'genres' => [1], 'publishers' => [97], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 389, 'game_title' => 'Top Gun', 'release_date' => '1987-11-01', 'platform' => 7, 'overview' => "The sun shimmers on the horizon as your armed-to-the-teeth Navy fighter screams from the carrier deck, accelerating into the danger zone. High above hostile waters your mission is to defend the task force from enemy attack. Suddenly, bogeys flash onto your radar. They're everywhere, diving toward you at Mach 2. Only a second to react, you go to guns and arm missiles. Your heart pounds and palms sweat as you blast into the dogfight with cannons blazing. Tracers zip past your engines. Shells shatter your senses. Now it's just you against them. And to survive you'll need more than speed and firepower. You'll need guts and instinct. You'll need to be a \"TOP GUN\" pilot!", 'youtube' => 'https://youtu.be/rNCxV1ByNgQ', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [4765], 'genres' => [13], 'publishers' => [23], 'alternates' => ['Top Gun (Konami)', 'TOPGUN'], 'uids' => nil, 'hashes' => nil }, { 'id' => 390, 'game_title' => 'Pokémon Snap', 'release_date' => '1999-06-30', 'platform' => 3, 'overview' => "Professor Oak needs your help!\r\n\r\nThe Professor has asked you to capture the Wild Pokémon of Pokémon Island… on film! Tour the island in your ZERO-ONE vehicle and snap pictures of Pokémon in their natural habitat. Wild Pokémon are often camera-shy, so you’ll have to use special items to bring them out in the open. Only the best shots will do for the Professor’s Pokémon Report, so sharpen your photography skills and get ready to SNAP!\r\n\r\n* The first-ever N64 game to feature the world-famous Pokémon--fully rendered in 3-D!\r\n* Explore the many environments of Pokémon Island, like the sunny beach, the mysterious caves, and even a red-hot volcano!\r\n* Many different types of Pokémon inhabit the island. See how many you can catch on film!", 'youtube' => '8B1yFwl0Efw', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3694, 6487], 'genres' => [8, 9], 'publishers' => [3], 'alternates' => ['Pokemon Snap Station - Kiosk'], 'uids' => nil, 'hashes' => nil }, { 'id' => 391, 'game_title' => 'Pokémon Stadium', 'release_date' => '2000-02-29', 'platform' => 3, 'overview' => "The ultimate Pokémon battle is about to begin... At long last, all of your favorite Pokémon are ready to go head-to-head on the N64! Whether you're battling a friend, a Gym Leader or a tournament contestant, you're about to witness some of the most spectacular battle scenes in Pokémon history! Select a team from a huge stable of \"rental\" battlers, or use the included N64 Transfer Pak to upload your own team of Pokémon Red, Blue or Yellow! This Stadium is packed and ready to rock!\r\n\r\n• Awesome 3-D animation on the N64 makes all 151 Pokémon larger than life!\r\n• Use the N64 Transfer Pak to battle using your Pokémon from Red, Blue or Yellow.\r\n• Battle your way to the top of the championships, or have a free-for-all with up to four players!\r\n• Nine Mini-Games add to the multi-player fun!\r\n• Use the power of the Transfer Pak and the N64 to play the Pokémon Game Boy game on your television!", 'youtube' => 'RVfC6ZtDCOA', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6043], 'genres' => [6], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 392, 'game_title' => 'Pokémon Stadium 2', 'release_date' => '2001-03-28', 'platform' => 3, 'overview' => "Hundreds of Pokémon in Three-mendous 3-D! What's sweeter than victory in a Pokémon battle? Victory in a 3-D arena on the N64! Set your strategy, then stand back while your Pokémon battle it out. You can even see the Pokémon you've trained—fully rendered in 3-D and ready for battle!\r\n\r\n• Nearly 250 Pokémon! Transfer Pokémon from the Red, Blue, Yellow - even Silver and Gold--versions of Pokémon for Game Boy. Or play with Rental Pokémon included int he game.\r\n• See them all in glorious 3-D! Ho-oh, Lugia, Entei and Pichu against all-time favorites, like Mewtwo, Charizard, Blastoise and Pikachu.\r\n• Become the Stadium Champion! Take on 21 Pokémon Trainers in the Gym Leader Castle to try to win it all!\r\n• 12 all-new mini-games! Try to bump other Hitmontop out of the arena in Topsy-Turvy--or charge up more energy than anyone else in Pichu's Power Plant.", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3694, 6043], 'genres' => [6], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 393, 'game_title' => 'Quake II', 'release_date' => '1999-05-31', 'platform' => 1, 'overview' => "Quake II takes place in a science fiction environment. In the single-player game, the player assumes the role of a Marine named Bitterman taking part in \"Operation Alien Overlord\", a desperate attempt to protect Earth from alien invasion by launching a counter-attack on the home planet of the hostile cybernetic Strogg civilization. Most of the other soldiers are captured or killed almost as soon as they enter the planet's atmosphere, so it falls upon Bitterman to penetrate the Strogg capital city alone and ultimately to assassinate the Strogg leader, Makron.", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3993], 'genres' => [8], 'publishers' => [33], 'alternates' => ['Quake 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 394, 'game_title' => 'Rampage: World Tour', 'release_date' => '1998-03-30', 'platform' => 3, 'overview' => "A wild smash-'em-up romp with universal appeal! Simple enough for any player. Plenty of depth and challenge to appeal to serious gamers as well. Bring a friend or two on a non-stop RAMPAGE while you inflict some major damage and destruction. Demolish buildings, swat down aircraft, eat people and rack up points, while destroying entire cities! More than 130 standard levels, 14 bonus levels, 4 grudge match levels and many hidden levels! Special bosses and some tasty humans give Lizzy, George or Ralph a major health boost.", 'youtube' => nil, 'players' => 3, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7381], 'genres' => [1], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 395, 'game_title' => 'Rayman 2: The Great Escape', 'release_date' => '1999-10-29', 'platform' => 3, 'overview' => "Rayman 2 takes place in a world called The Glade of Dreams. An army of Robot Pirates, led by Admiral Razorbeard, invades this world and destroys the Heart of the World, the world core. This greatly weakens the resistance's power and disables Rayman's powers, leading to his capture.\r\n\r\nGlobox, a friend of Rayman, is later also captured and put in the same cell as Rayman aboard the Pirates' prison ship. Globox restores one of his powers through a silver lum given to him by Ly, a fairy. Rayman escapes the prison ship, and is separated from Globox again. He learns that in order to stand a chance against the Pirates, he needs to find 4 ancient, magic masks to awaken Polokus, the spirit of the world.[10] He travels through the Glade of Dreams via the Hall of Doors, a magical place linked to various locations in the world, controlled by the ancient Teensies.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9150], 'genres' => [15], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 396, 'game_title' => 'Ready 2 Rumble Boxing', 'release_date' => '1999-10-31', 'platform' => 3, 'overview' => "Ready 2 Rumble Boxing is a boxing game for the Dreamcast, PlayStation, Game Boy Color, and Nintendo 64 and it was released in 1999 by Midway. The success of the Dreamcast version led to it becoming one of the few Sega All Stars titles.\r\n\r\nLike Nintendo's Punch-Out!! series it features many characters with colorful personalities (i.e. Afro Thunder, Boris \"The Bear\" Knokimov, etc.); however, unlike the Punch-Out!! series, Ready 2 Rumble Boxing is in 3D, thus allowing for more control over your character in the ring, and also enables the players to choose whichever fighters they want.\r\n\r\nThroughout the fights in the game, there is a special RUMBLE meter which fills up, one letter at a time, until the word \"RUMBLE\" is spelled at the bottom of the screen. Letters can be obtained by successfully landing hard blows or taunting the opponent. Once the meter is full, the player can power himself up, enabling access to a special move called \"Rumble Flurry\", which might as well instantly knock the opposite player out cold.\r\n\r\nOne unique graphic feature of the game is the gradual bruises gained by players as the fight progresses (like hematomas and swellings), present in all fifth-generation versions. While this is not necessarily a new feature to games (it had been implemented before in SNK's 1992 game Art of Fighting), it garnered much appraisal from reviewers, because of the added fun factor this element supply to the game", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5507], 'genres' => [10, 11], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 397, 'game_title' => 'Resident Evil 2', 'release_date' => '1998-01-21', 'platform' => 3, 'overview' => "Ready or not, the terror of Resident Evil 2 is here. In chapter one, the case of the disastrous T-virus outbreak--a mutagenic toxin designed for biological weapons--was eventually closed but the experiments were far from over. Control the destiny of Leon Kennedy or Claire Redfield as their nightmare begins when a biotech terror runs rampant in Raccoon City. Relentless zombies and hideous monsters are all out for a taste of your blood. If the suspense doesn't kill you, something else will.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1436], 'genres' => [1, 2], 'publishers' => [9], 'alternates' => ['Biohazard 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 398, 'game_title' => 'San Francisco Rush 2049', 'release_date' => '2000-09-06', 'platform' => 3, 'overview' => "San Francisco Rush 2049 is the third game in the Rush series, sequel to San Francisco Rush and Rush 2: Extreme Racing USA.\r\nThe game features a futuristic representation of San Francisco and an arcade-style physics engine. It also features a multiplayer mode for up to four players and Rumble Pak support on the Nintendo 64 port. A major difference in game play compared to predecessors in the series is the ability to extend wings from the cars in midair and glide. As with previous titles in the franchise, Rush 2049 features a stunt mode in which the player scores points for complex mid-air maneuvers and successful landings. There is also a multiplayer deathmatch battle mode. There are six race tracks, four stunt arenas, eight battle arenas, and one unlockable obstacle course named The Gauntlet. The single player race mode places emphasis on outlandish and death-defying shortcuts in each track. The game has a soundtrack mostly comprising techno music.", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5507], 'genres' => [7], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 399, 'game_title' => 'South Park Rally', 'release_date' => '2000-03-01', 'platform' => 3, 'overview' => "Choose your character from the cast of the popular 'mature' cartoon South Park, and tear through the streets in this racing game. Your character's vehicle may be a little cart, trike, or box, for example. Weapons include rockets, Salty Balls, Cheesy Poofs, the beloved Cow and even an Anal probe. All of the voices are also included, making it feel more like the real cartoon than a rally game. You can also play an all-on-all 4 player mode.", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [8497], 'genres' => [7], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 400, 'game_title' => "South Park: Chef's Luv Shack", 'release_date' => '1999-11-20', 'platform' => 3, 'overview' => "South Park: Chef's Luv Shack is a 2D game-show style video game based on the television show South Park. It gained its popularity by having mini games and the ability to play against friends in a challenge for the most points. It also involves trivia questions about South Park and other topics.\r\nThe game intermittently switches between questions and minigames, with a minigame proceeding every three questions. Players score points by answering questions first (correctly) and based on minigame ranking. Players lose points for questions answered incorrectly. The game is exclusively multiplayer, as when played by one player, there is no AI, so that player always wins, even with a negative score", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [194], 'genres' => [5], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 401, 'game_title' => 'Star Wars: Episode I - Battle for Naboo', 'release_date' => '2000-12-18', 'platform' => 3, 'overview' => "Attention defenders of Naboo! The Trade Federation must be stopped! Storm through more than 15 missions over land, sea and space as your freedom fighters rally against the droid armies. Take control of 7 vehicles: the Naboo starfighter, Gian speeder, and new craft like the heavy STAP, Trade Federation gunboat and more. More than 15 missions: escape from Theed, search & destroy, sabotage, reconnaissance, convoy. Battle against Trade Federation droid starfighters, AATs, destroyer droids, battle droids.\r\nChange vehicles mid-mission through specially designated hangars.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2976], 'genres' => [1], 'publishers' => [3, 25], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 402, 'game_title' => 'Star Wars Episode I: Racer', 'release_date' => '1999-05-18', 'platform' => 3, 'overview' => 'Join Jedi-to-be Anakin Skywalker in the Star Wars race of your life! Relive all the thrills and excitement of the Podracer sequence from Star Wars: Episode I. Hang on tight - with afterburners on, Podracers max out at a simulated 600 mph! Race in furious competition against more than 21 opponents! Take on over 21 tracks in 8 unique worlds. Avoid hazards such as methane lakes, meteor showers and Tusken Raiders! Featuring spectacular 3D environments!', 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5068], 'genres' => [7], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 403, 'game_title' => 'Star Wars: Rogue Squadron', 'release_date' => '1998-12-03', 'platform' => 3, 'overview' => "Fly against the evil Empire! As Luke Skywalker, co-founder of the Rebel Alliance's elite Rogue Squadron, you must combat the evil Galactic Empire! Engage in intense, fast-paced planetary air-to-ground and air-to-air missions - dogfights, search and destroy, reconnaissance, bombing runs, rescue assignments and more! Pilot X-wings, Y-wings, A-wings, V-wings and Snowspeeders with powerful weapons in over 15 missions battling TIE fighters, TIE bombers, Imperial shuttles, AT-AT walkers, AT-STs and other challenging foes.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2976], 'genres' => [1, 8], 'publishers' => [25], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 404, 'game_title' => 'Super Smash Bros.', 'release_date' => '1999-04-26', 'platform' => 3, 'overview' => "It's a Bumpin', Bruisin', Brawlin' Bash! The many worlds of Nintendo collide in the ultimate showdown of strength and skill! Up to four players can choose their favorite characters - complete with signature attacks - and go at it in Team Battles and Free-For-Alls. Or venture out on your own to conquer the 14 stages in single-player mode. Either way, Super Smash Bros. is a no-holds-barred action-fest that will keep you coming back for more!", 'youtube' => 'K783SDTBKmg', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3694], 'genres' => [10], 'publishers' => [3], 'alternates' => ['Super Smash Bros. 64', 'Nintendo All Star! DairantÅ Smash Brothers'], 'uids' => nil, 'hashes' => nil }, { 'id' => 405, 'game_title' => 'Tetrisphere', 'release_date' => '1997-08-11', 'platform' => 3, 'overview' => "Tetrisphere is a variant on Tetris in which various shapes are shifted across a wrapped three-dimensional grid resembling a sphere, and then destroyed. The objective of the game changes depending on the mode, but generally consists of removing layers of shapes to reach the playing field's core. Despite very little domestic advertising, Tetrisphere enjoyed moderately good sales and a mostly favorable critical reception. Reviewers praised the game's originality and the musical score composed by Neil D. Voss.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3682], 'genres' => [5], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 406, 'game_title' => "Tony Hawk's Pro Skater", 'release_date' => '2000-03-29', 'platform' => 3, 'overview' => 'Go Big, Go Pro! Skate as legendary Tony Hawk, or as one of nine top pros. Work your way up the ranks by landing suicidal tricks in brutal competitions to become the highest ranked skate champ! Great features such as: Signature Pro Moves, fully skateable worlds, head-to-head competition, and Instant Replay Mode.', 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2658], 'genres' => [11], 'publishers' => [33], 'alternates' => ["Tony Hawk's Skateboarding"], 'uids' => nil, 'hashes' => nil }, { 'id' => 407, 'game_title' => 'Turok 2: Seeds of Evil', 'release_date' => '1998-10-21', 'platform' => 3, 'overview' => "Turok 2: Seeds of Evil is a first-person shooter video game originally released for the Nintendo 64 in late 1998. A port was released for Windows OS shortly afterwards, in 1999. It is the sequel to the successful Turok: Dinosaur Hunter and was followed by the 2000 entry in the series, Turok 3: Shadow of Oblivion. It is one of the first Nintendo 64 games to allow use with the RAM Expansion Pak and it was known as Violence Killer: Turok New Generation in Japan. A separate game, also titled Turok 2: Seeds of Evil, was released for the Game Boy Color in December 1998. Although set in the same fictional universe, it follows a different storyline.\r\n \r\nThe game was well received, garnering an 89% from the review collator Game Rankings for the Nintendo 64 version and labeled as a \"must-buy\" from GameSpot.", 'youtube' => 'xYUmLGDelRE', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4065], 'genres' => [1, 8], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 408, 'game_title' => 'Turok: Rage Wars', 'release_date' => '1999-10-31', 'platform' => 3, 'overview' => 'The Lost Land is an unholy world, born from the death of the universe; a strange world where "time has no meaning". If the Lost Land falls, all the universe falls. Since the dawn of time, the Turok have maintained the balance between good and evil, order and chaos. The Turok control The Light Burden, a sacred vessel that holds the last remnants of the pure energy source that created The Lost Land. Whoever controls The Light Burden controls the power of creation. Fierce Battles waged in an effort to wrestle control of The Light Burden from the line of Turok, and thus conquer the Lost Land. A number of fierce warriors have been selected to participate to fight and win the Rage Wars...', 'youtube' => 'CTfJGdOKtMk', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [194], 'genres' => [8], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 409, 'game_title' => 'Vigilante 8: 2nd Offense', 'release_date' => '1999-10-31', 'platform' => 3, 'overview' => "The story of Vigilante 8: 2nd Offense centers on the international meddlings of an oil conglomerate from the future known as OMAR (Oil Monopoly Alliance Regime).\r\nAfter finding an electronic armband in a service station bathroom, former Vigilante Slick Clyde rose to be controlled by OMAR. Working up through the ranks of command he soon came to be the CEO of OMAR itself and made a complete monopoly on all oil trades with the sole exception of the United States.\r\nWith the help of his student and hitman, Obake, he steals the technology to allow him to travel through time. Taking with him Obake and his cybernetic assassin, Dallas 13, he makes the jump back to 1970s to cripple the United States and bring OMAR to total domination.\r\nAppearing in 1970s, the three vehicles encounter Convoy, the former leader of the Vigilantes. Upon seeing him, the three cars open fire.", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5102], 'genres' => [1, 8, 19], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 410, 'game_title' => 'Waialae Country Club', 'release_date' => '1998-07-29', 'platform' => 3, 'overview' => "One of the most beautiful golf courses in the world is now one of the most beautiful N64 games. The true physics of golf take the starring role in this ultra-realistic venture into the popular sport. You can customize the characteristics of up to 10 different golfers, including power, putting, recovery, and ability against the wind. Plan your approach, pick a club, get your stance just right, read the wind, decide whether you're going for spin, draw or fade, read the meter to get your power where you want it then swing! The six modes of play at your disposal are Waialae Open, Tournament, Stroke, Skins, Match, and Practice. A truly comprehensive game, WAIALAE COUNTRY CLUB will even calculate your handicap for you for use in later play. Up to four players can have a go in each game, with all stats and results saved to the game's memory. The graphics and player animations are outstanding, the play is seamless and intuitive, and the location just can't be beat. Spend your next vacation in Waialae, golf fans. Just don't expect it to be easy.", 'youtube' => '', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8429], 'genres' => [11], 'publishers' => [3], 'alternates' => ['Waialae Country Club: True Golf Classics'], 'uids' => nil, 'hashes' => nil }, { 'id' => 411, 'game_title' => 'Wave Race 64', 'release_date' => '1996-09-27', 'platform' => 3, 'overview' => "Wave Race 64 is sure to provide some of the most exciting racing you've ever experienced. Feel the pounding and crashing of the waves as you accelerate into straight-aways, whip around the marker buoys and go airborne on the jump ramps. Don't race alone - challenge a friend! Take control in three different modes of play - Championship, Time Trials and Stunt Mode. Nine challenging courses set in exotic locales - race conditions change and the wave action responds to the way both you and your opponents race!", 'youtube' => '4XPjy2ljErU', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [7], 'publishers' => [3], 'alternates' => ['Wave Race 64: Shindou Edition'], 'uids' => nil, 'hashes' => nil }, { 'id' => 412, 'game_title' => 'WCW Backstage Assault', 'release_date' => '2000-12-12', 'platform' => 3, 'overview' => 'No-Holds-Barred Brawling! Over 50 WCW superstars, including the women of the WCW! 14 playable Backstage Areas, including the new Semi-Trailer Area. Destroy your enemy faster with power-ups! New - First Blood Mode and Torch matches! Use your environment as a weapon!', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2724], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 413, 'game_title' => 'WinBack: Covert Operations', 'release_date' => '1999-10-20', 'platform' => 3, 'overview' => "A terrorist group calling itself the Crying Lions is about to take over the world with its mighty satellite and Jean-Luc Cougar is the only one who can stop it. As Jean-Luc, a covert operative working for the Strategic Covert Actions Team, you are responsible for taking back a Lions-controlled base and regaining power of the satellite. Some of the weapons you'll have to acquire and use to defeat the terrorists are handguns, shotguns, and machine guns, though you'll also need to access such materials as explosives, detectors, flashlights and medical kits in order to succeed. A refreshing take on the traditional action game, WINBACK requires as much stealth and strategy as it does reflexes and use of weaponry. The game features six different multiplayer modes, supporting up to four players: Death Match, Lethal Tag, Quick Draw, Cube Hunt, Team Battle, and Point Match. You select your difficulty level and you can even start off in a Tutorial mode to get the controls down.", 'youtube' => nil, 'players' => 1, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [6242], 'genres' => [8], 'publishers' => [50], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 414, 'game_title' => 'World Driver Championship', 'release_date' => '1999-06-16', 'platform' => 3, 'overview' => 'One of the last racing simulations to be released for Nintendo 64, this graphically intensive title used custom microcode optimization and high polygon count modelling. The development team was able to optimize the usage of the various processors within the N64 to allow far draw distance (reducing the need for fog or pop-up), high detail texturing and models, Doppler effect audio, and advanced lighting and fog effects for realistic weather conditions. Impressively the game has a high resolution 640x480 mode that does not require the add-on N64 RAM Expansion Pak. Additionally, unlike many other games of its type on the platform, the game runs high resolution at a sufficiently playable pace, undoubtedly due to the use of a reduced screen area letterbox mode that lessens the number of pixels needing to be displayed.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1292], 'genres' => [7], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 415, 'game_title' => 'WWF Attitude', 'release_date' => '1999-07-31', 'platform' => 3, 'overview' => "Now featuring over 40 of your favorite WWF superstars! Customize your own wrestler's move sets and costumes. Over 20 game modes including all-new specialty matches. Real-life WWF entrances and theme songs. Wrestle your way to the title in an all-new career mode. First ever Create-Your-Own Pay-Per-View Mode! Two-man commentary featuring Shane McMahon and Jerry \"The King\" Lawler.", 'youtube' => 'dh3AhZUuRDM', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [4065], 'genres' => [10, 11], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 416, 'game_title' => 'WWF No Mercy', 'release_date' => '2000-11-17', 'platform' => 3, 'overview' => 'Jump into the ring with the biggest, baddest jambronis around and experience brutal WWF action never before seen in a console game! Over 65 WWF superstars, all-new Ladder matches, and all-new Double-Team moves, like the Dudley 3D Deathdrop! Take on the entire Federation in Survival Mode. Take the action out of the ring in 10 different backstage areas!', 'youtube' => 'LhdU0KoXGTk', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [314], 'genres' => [11], 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 417, 'game_title' => 'WWF WrestleMania 2000', 'release_date' => '1999-10-31', 'platform' => 3, 'overview' => 'The greatest wrestling game ever created! Tons of game modes, including Cage Match, Road to Wrestlemania, Create a PPV, and more! Create and bet WWF Championship belts with your friends. Over 50 of the top WWF superstars, more than any other WWF game! Thousands of signature moves, taunts, and mannerisms. New Create a Wrestler, with custom moves, costumes, and fighting styles!', 'youtube' => 'hcSx-ABjaMU', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [314], 'genres' => [11], 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 418, 'game_title' => 'Xena: Warrior Princess - The Talisman of Fate', 'release_date' => '1998-12-14', 'platform' => 3, 'overview' => "Xena shall choose the defenders of the world. We have seen them in the memories of her exploits. So come together, Earth's greatest heroes and villains. Choose your weapons wisely and let the battles begin! Just remember, each victory only brings you closer to challenging the embodiment of darkness... Despair himself! Each of Xena's 10 characters possess their own unique weapons, attitudes and fighting techniques. Exclusive multi-player feature includes a roster mode, plus team and single battles.", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7381], 'genres' => [10], 'publishers' => [64], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 419, 'game_title' => "Yoshi's Story", 'release_date' => '1998-03-01', 'platform' => 3, 'overview' => "Baby Bowser has taken the Super Happy Tree and cast a spell on Yoshi's world, turning it into the pages of a picture book. The only Yoshis not affected by the spell were six hatchlings that were still protected by their shells. It's up to them to reclaim the Super Happy Tree and restore happiness to the world. That is the only thing that can break Baby Bowser's Spell!", 'youtube' => 'byuavpfovHY', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [1, 2], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 420, 'game_title' => 'Dino Crisis', 'release_date' => '2000-11-14', 'platform' => 16, 'overview' => "Dino Crisis is a survival horror video game by Capcom, released in 2000 for Microsoft Windows. It was directed and produced by Resident Evil creator Shinji Mikami, and developed by a team of staff members that would later become part of Capcom Production Studio.\r\n\r\nIn the game, a special forces team must find a way to survive in a secret government facility that has been infested with dinosaurs. It features survival horror gameplay similar to the Resident Evil series and was promoted by Capcom as \"panic horror\".", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1436], 'genres' => [8, 18], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 421, 'game_title' => 'Dynamite Cop', 'release_date' => '1999-11-03', 'platform' => 16, 'overview' => "Pirates have kidnapped the President's daughter and are holding her on a hijacked cruise ship. Now it's up to an elite police force to get them back, using whatever means necessary. The action takes place on both the cruise ship and the pirate's island hideaway.\r\n\r\nYou play as one of three cops, in this beat-em up fighting game from Sega. Dynamite Cop features similar gameplay to Die Hard Arcade. As your character enters an area, you have to beat up everyone there. Once they are gone, you continue to the next area. To help you there are many weapons, such as guns, knives, pepper spray, chairs, and bread. Bread? Yes, you can use pretty much anything as a weapon.", 'youtube' => nil, 'players' => 2, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [7549], 'genres' => [1], 'publishers' => [15], 'alternates' => ['Dynamite Cop!'], 'uids' => nil, 'hashes' => nil }, { 'id' => 423, 'game_title' => 'Jet Grind Radio', 'release_date' => '2000-11-01', 'platform' => 16, 'overview' => "Tokyo-to, a city not unlike Tokyo, somewhere in Asia, in the near future. This is the story about the GG's, one of three rival teenage gangs who ride motorised inline skates and are tagging the streets with graffiti. There is a turf war going on between the gangs GG's, the Poison Jam, and the high-tech freaks, the Noise Tanks. The evil Rokkaku Corporation has the corrupt police in their grasp, and, headed by Captain Onishima, the cops are hell-bent on subduing the unruly teen protagonists. But there is light in the darkness: the underground DJ, \"Professor K,\" and his Jet Set Radio station keep tabs on what is happening on the streets of Tokyo-to, and soon our teens will have something much darker than the police to worry about.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7871], 'genres' => [1], 'publishers' => [15], 'alternates' => ['Jet Set Radio', 'JetSet Radio'], 'uids' => nil, 'hashes' => nil }, { 'id' => 424, 'game_title' => 'KISS: Psycho Circus - The Nightmare Child', 'release_date' => '2000-10-29', 'platform' => 16, 'overview' => "Wicked Jester, a band of four, are headed for a Friday night gig at The Coventry, a rundown dive outside of town. They arrive only to find the parking lot deserted, the club seemingly dead. The band's members: Pablo Ramirez, Andy Chang, Gabriel Gordo and Patrick Scott, stepping from their van, are startled by a voice from the shadows. She offers them four tickets to a circus -- tonight's the grand finale! Having nothing better to do, the four accept and the nightmare begins.\r\n\r\nBased on characters from comic book author Todd McFarlane, KISS Psycho Circus: The Nightmare Child brings the horror and carnage of the Psycho Circus to the PC in a shooter format. There are two-dozen creatures to battle with and three classes of weapons to use, each with four specific types: melee (beast claws, thornblade, twister and punisher), common (zero cannon, magma cannon, windblade and scourge) and ultimate (stargaze, galaxion, spirit lance and draco). In addition to the weaponry, temporary power-ups and instant items such as health, attack and defense powers are available.", 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9018], 'genres' => [1, 8, 18], 'publishers' => [123], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 425, 'game_title' => 'NBA 2K1', 'release_date' => '2000-11-01', 'platform' => 16, 'overview' => 'NBA 2K1 (also known as Sega Sports: NBA 2K1 or NBA2K1) is a basketball video game. It is the second installment in the NBA 2K series of video games. It was developed by Visual Concepts and published by Sega (as Sega Sports). It was the first NBA 2K game to feature online multiplayer and the first game to feature street courses instead of playing a game inside the arena in the first game, famous street courts such as The Cage, Rucker Park, Franklin Park, and Goat Park. It was released on November 1, 2000 in North America with the Dreamcast. Rapper Redman (rapper) appears in the video game', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => nil, 'genres' => [11], 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 426, 'game_title' => 'Phantasy Star Online', 'release_date' => '2001-01-29', 'platform' => 16, 'overview' => "Pioneer 2 finally completed it's long voyage to the new home world. But as the ship entered orbit, an enormous explosion shook the entire planet, and all contact with the thousands of people already there was lost. Now, in the first worldwide online console RPG, players from around the globe must unite to discover what has happened. Phantasy Star Online continues in the tradition of one of the most popular series of all time, and becomes a revolutionary and truly global gaming experience in an online, persistent world.", 'youtube' => nil, 'players' => 4, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [7979], 'genres' => [1, 2, 4, 14], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 427, 'game_title' => 'Quake III Arena', 'release_date' => '1999-12-02', 'platform' => 1, 'overview' => "Unlike its predecessors, Q3A does not have a plot-based single-player campaign. Instead, it simulates the multiplayer experience with computer controlled players known as bots. The game's story is brief - 'the greatest warriors of all time fight for the amusement of a race called the Vadrigar in the Arena Eternal.'\r\n\r\nThe introduction video shows the abduction of such a warrior, Sarge, while making a last stand. Continuity with prior games in the Quake series and even Doom is maintained by the inclusion of player models related to those earlier games as well as biographical information included on characters in the manual, a familiar mixture of gothic and technological map architecture and specific equipment; for example, the Quad Damage power-up, the infamous rocket launcher and the BFG super-weapon.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3993], 'genres' => [8], 'publishers' => [33], 'alternates' => ['Quake 3 Arena'], 'uids' => nil, 'hashes' => nil }, { 'id' => 428, 'game_title' => 'Resident Evil Code: Veronica', 'release_date' => '2000-02-29', 'platform' => 16, 'overview' => "The game begins with Claire Redfield raiding an Umbrella Corporation facility in Paris in search of her brother, Chris Redfield. During the infiltration she is captured and imprisoned on Rockfort Island. Soon after arriving, a man named Rodrigo Juan Raval releases her from her cell, since she is not much of a threat considering the outbreak of the T-virus on Rockfort. Trying to escape from the contaminated island, Claire teams up with inmate Steve Burnside, at the same time being confronted with the island's commander Alfred Ashford. Meanwhile, Albert Wesker is on a mission of his own to retrieve a sample of the T-Veronica virus developed by Alfred's twin sister Alexia. His unit is also responsible for the outbreak of the T-virus on Rockfort Island.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1436], 'genres' => [1, 2, 5], 'publishers' => [9], 'alternates' => ['BIOHAZARD CODE: Veronica'], 'uids' => nil, 'hashes' => nil }, { 'id' => 429, 'game_title' => 'Samba de Amigo', 'release_date' => '2000-10-16', 'platform' => 16, 'overview' => "Samba De Amigo is a highly unique game: a maracas simulation. Game play is based around a special maracas controller that you use to interact with the music. The controller senses which region in space out of a possible 6 that the maracas are in. It also senses when the player shakes the maracas. As the music plays, the player must shake the maracas in the appropriate region with proper timing to progress. A standard controller can also be used if you do not have the maracas controller, which is sold separately.\r\n\r\nThe music in the game comes from a wide variety of sources. Some of the songs are traditional samba music, while others are recognizable pop tunes, like \"Macarena\" and \"Tequila.\"", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7979], 'genres' => [17], 'publishers' => [15], 'alternates' => ['Samba de Amigo 2000'], 'uids' => nil, 'hashes' => nil }, { 'id' => 430, 'game_title' => 'Shenmue', 'release_date' => '2000-11-06', 'platform' => 16, 'overview' => "The first chapter of Yu Suzuki's epic saga is at hand. Shenmue is an adventure game that transports you to Japan, circa 1986. You are Ryo, a young man trying to solve the mystery of his father's death. Along the way, you'll be treated to the most richly-detailed game world ever conceived. Shenmue offers a true living world, where characters exist on their own timelines and almost all objects can be manipulated and used. Over the course of the adventure, you will learn new hand-to-hand fighting techniques, presented in breathtaking motion-captured animations. You'll also interact with literally hundreds of characters and solve a myriad of puzzles. It's epic storytelling at its best, and it's only on Dreamcast.\r\n\r\nA massive, highly-detailed 3D world featuring hundreds of interactive characters and objects to interact with. Real-time fighting and action scenes with motion capture by real budo experts. In-game arcade features Sega classics such as Hang-On and Space Harrier. \"Magic Weather\" technology brings the world to life with changes to landscapes, climate, and vegetation. Created by Yu Suzuki, the mastermind of arcade hits such as Virtua Fighter.", 'youtube' => 'cf-MK4599A8', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [411], 'genres' => [2, 4], 'publishers' => [15], 'alternates' => ['Shenmue シェンムー', 'シェンムー'], 'uids' => nil, 'hashes' => nil }, { 'id' => 431, 'game_title' => 'Skies of Arcadia', 'release_date' => '2000-11-13', 'platform' => 16, 'overview' => "The story opens with a young Silvite woman named Fina sailing through the night skies in her tiny Silver airship. Not far behind her, Valuan Admiral Alfonso is in hot pursuit under orders from Lord Galcian to capture her. Alfonso opens fire on and disables Fina's ship long enough to capture her before it plummets into Deep Sky, but just as she is being brought onboard his warship, a Blue Rogue vessel arrives with the intent of robbing the Valuan vessel. Vyse and Aika of the Blue Rogues jump from the Albatross onto Alfonso's flagship and fight their way to the rear cargo hold, prompting Alfonso to flee on a lifeboat while leaving Fina behind along with the war beast Antonio, who is quickly defeated by the Rogues. Vyse and Aika bring Fina back to their clan's ship, which Vyse pilots back to their secret hideout, Pirate Island (disguised as a small village).", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'T - Teen', 'developers' => [6334], 'genres' => [1, 2, 4], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 432, 'game_title' => 'Sonic Adventure 2', 'release_date' => '2001-06-19', 'platform' => 16, 'overview' => 'After discovering the existence of a secret weapon mentioned in the diary of his grandfather, Gerald Robotnik, Dr. Eggman infiltrates a high-security G.U.N. facility in search of it. This "weapon", a black hedgehog named Shadow who claims that he is the "Ultimate Life Form", offers to help Eggman take over the world, telling him to rendezvous with him at the abandoned Space Colony ARK with more Chaos Emeralds. Shadow proceeds in stealing one of the emeralds, and G.U.N. officials mistake him for Sonic. Sonic is apprehended shortly after he confronts Shadow, who demonstrates to Sonic the Chaos Control technique.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7979], 'genres' => [15], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 433, 'game_title' => 'Space Channel 5', 'release_date' => '2000-06-04', 'platform' => 16, 'overview' => "Space Channel 5 (スペースãƒãƒ£ãƒ³ãƒãƒ«5) is a video game for the Sega Dreamcast released in Japan on the 16th of December, 1999, North America on the 6th of June, 2000 and in Europe on the 8th of October, 2000. It was the first game to be developed by the newly opened United Game Artists studio within Sega, spearheadded by Tetsuya Mizuguchi, although the UGA name had not yet been adopted by the original Japanese release.\r\n\r\nThe game stars Space Channel 5 reporter Ulala, tasked with upping the ratings of the channel, and stopping the \"evil\" Morolians, who are forcing the galaxy to dance.\r\n\r\nSpace Channel 5 is a rhythm game built similarly in nature to electronic memorisation games such Simon, and video games such as PaRappa the Rapper. Throughout the game the computer shows a sequence of moves—dance steps in this case—and the player must copy them successfully to advance. Repeated failure will force the show to be cancelled, effectively triggering a game over.", 'youtube' => 'VsMftkM18Yw', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9229], 'genres' => [1, 17], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 434, 'game_title' => 'Street Fighter Alpha 3', 'release_date' => '2000-05-31', 'platform' => 16, 'overview' => "Street Fighter Alpha 3, the third game in the Alpha series, has a total of 31 fighters, the most in the series so far. New characters include old favorites E. Honda, Blanka, Vega, Cammy, T. Hawk, Dee Jay, Juni and Juli. Some of the newest fighters on the block include a former Final Fight character (Cody, who has been in jail since the last Final Fight game, or so his clothing suggests), Karin Kanzuki and Rainbow Mika.\r\n\r\nThe major difference between this Alpha and the last two are the new play modes World Tour, Arcade, VS, Training and Entry.", 'youtube' => '', 'players' => 3, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1436], 'genres' => [10], 'publishers' => [9], 'alternates' => ['Street Fighter Zero 3: Saikyo-ryu Dojo'], 'uids' => nil, 'hashes' => nil }, { 'id' => 435, 'game_title' => 'Super Magnetic Neo', 'release_date' => '2000-06-12', 'platform' => 16, 'overview' => "In Super Magnetic Neo, a gang lead by evil, foul-mouthed baby Pinki has taken over Pao Pao Park. The professor must stop her, so her sends Super Magnetic Neo, a little boy robot with a powerful electromagnet on his head.\r\n\r\nYou must use all these skills to make it through all four sections of Pao Pao Park and defeat Pinki.", 'youtube' => 'vFUa5zbqngw', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3451], 'genres' => [1], 'publishers' => [109], 'alternates' => ['Super Magnetic NiuNiu'], 'uids' => nil, 'hashes' => nil }, { 'id' => 436, 'game_title' => 'Virtua Fighter 3tb', 'release_date' => '1999-10-18', 'platform' => 16, 'overview' => "Look out -- Wham! Bam! And a full-body Slam! This Dreamcast version of Sega's revolutionary fighting game packs a one-two-three punch. As one of 12 fierce characters, you have a single deadly goal: to kick some 3D ass 'til you win the World Fighting Tournament. Incredible 3D environments, fluid gameplay, and lifelike graphics enhance the smooth fighting moves you're used to in the mega-hit arcade original. An exclusive feature of the Dreamcast version is Team Battle Mode, in which your custom three-person team goes head-to-head with an opponent's custom team. Virtua Fighter 3tb is so realistic that characters actually watch their opponents' every life-like move, like when they fall forward FROM behind or lose their balance when pushed. Focus your razor-sharp reflexes and take lethal aim as you deliver bone-crunching blows to your reeling opponents. When the dust settles, you'll still be standing.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [411], 'genres' => [10], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 437, 'game_title' => 'Fallen Earth: Welcome to the Apocalypse', 'release_date' => '2009-09-22', 'platform' => 1, 'overview' => "Fallen Earth is a free-to-play MMO developed by Reloaded Productions (formerly by North Carolina-based Icarus Studios and Fallen Earth).[2] The game takes place in a post-apocalyptic wasteland located around the American Grand Canyon. Fallen Earth's gameplay features FPS/RPG hybridization, first-person/third person views, hundreds of items, including improvised equipment and weapons, a variety of functional vehicles, a real-time, in-depth crafting system (which includes vehicles), various skills and abilities, factions and tactical PvP, all existing within 1000 square kilometers of usable terrain based on real-world topographical maps of the area. The game was released on September 22, 2009. Two years later, GamesFirst purchased the intellectual property and made the game free to play.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => nil, 'genres' => [4, 14], 'publishers' => nil, 'alternates' => ['Fallen Earth: Welcome to the Apocalypse', 'Fallen Earth: Blood Sports'], 'uids' => nil, 'hashes' => nil }, { 'id' => 438, 'game_title' => "Mario & Luigi: Bowser's Inside Story", 'release_date' => '2009-09-14', 'platform' => 8, 'overview' => "Mario & Luigi: Bowser's Inside Story is the third game in the Mario & Luigi series of games. Players control Mario and Luigi simultaneously in the side-scrolling platform environment of Bowser's body, while also controlling the Koopa King himself in the top-down world of the Mushroom Kingdom. Similar to games like Earthbound, enemy encounters are seen as actual enemies that players can avoid or attempt to strike early. The actual battles are a combination of turn-based menu attacks, and timed reactions to enemies during battle. By watching the way an enemy reacts, you can anticipate their attack and avoid it or counterattack.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [389], 'genres' => [4], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 439, 'game_title' => 'Mighty Morphin Power Rangers', 'release_date' => '1995-01-01', 'platform' => 21, 'overview' => "This take on the Power Rangers franchise is different from the many other Power Ranger games as it features FMV with real video of the actual TV show. The footage is spliced from nine different episodes and the gameplay is reminiscent of games such as Dragon's Lair and Space Ace where the player must press a button at a certain time to avoid being punched, kicked, avoid a trap, etc. Failure to miss pressing a button will continue to play the footage, but cause the player to loose a life. After a certain set of lives are lost, the game will be over.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7372], 'genres' => [1], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 440, 'game_title' => 'Ecco: The Tides of Time', 'release_date' => '1994-08-25', 'platform' => 21, 'overview' => "The Tides of Time picked up right where the original Ecco the Dolphin left off. It turned out that the Vortex Queen was far from vanquished, and had, in fact, followed Ecco to Earth to build a new hive for herself. Ecco lost his powers from the Asterite early on, and soon after met a dolphin with unusually long fins. She was his descendant, Trellia, and had come to take him to her present in Ecco's distant future.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6155], 'genres' => [1, 2], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 441, 'game_title' => 'Hook', 'release_date' => '1992-04-01', 'platform' => 21, 'overview' => "PETER PAN has now grown up, far away from NEVERLAND, but his old enemy CAPTAIN HOOK has not forgotten, and schemes his revenge. Kidnapping Peter's children, he lures our hero back to the island of PIRATES and \"LOST BOYS\" for a final confrontation. With the help of TINKERBELL, the faithful fairy, you take on the role of PETER PAN in this magic adventure fraught with danger and excitement!", 'youtube' => '3rwtmJKsRP4', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [10_213, 10_214, 10_215], 'genres' => [1, 2], 'publishers' => [77], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 442, 'game_title' => 'Dungeon Explorer', 'release_date' => '1994-01-01', 'platform' => 21, 'overview' => 'Dungeon Explorer is an action role-playing game. It supports up to four players with a choice of six different character classes: monk, knight, elf, mage, beast and ninja. The game starts in the area surrounding a save point. This area functions as a central hub to access all the six dungeons. If a character leaves it, the food counter starts decreasing. If it reaches zero, the life points start diminishing until the character dies. Food can be found as potions or pots around the mazes. Returning the character to the save point area replenishes all the counters and cures all conditions (like poisoning and confusion). The gold collected in the game can be spent on equipment upgrades at the weapons shop. The tavern allows the player to switch characters.', 'youtube' => nil, 'players' => 4, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [3923], 'genres' => [1, 4], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 443, 'game_title' => 'Flashback: The Quest for Identity', 'release_date' => '1992-12-02', 'platform' => 21, 'overview' => "You've lost your mind! You're trapped on a distant planet inhabited by aliens plotting to overtake the Earth. The only problem is - you don't even know who you are! To stop the alien attack, you must discover your true identity and fight your way back through the galaxy to warn Earth!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2231], 'genres' => [2], 'publishers' => [110], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 444, 'game_title' => 'Racing Aces', 'release_date' => '1993-01-01', 'platform' => 21, 'overview' => 'Racing Aces puts you behind the stick of World War 1, World War 2, and modern day fighting aircraft. Each competition is a dogfight as much as a race, and you will have to gun down your enemies to win. The tracks are littered with power up balloons to give you extra weapons and speed.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3711], 'genres' => [7], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 445, 'game_title' => 'Robo Aleste', 'release_date' => '1992-11-27', 'platform' => 21, 'overview' => "Pilot your massive mecha Aleste in the name of the Oda clan and seek revenge against the evil Chugoku Army for their atrocities! Robo Aleste is another title in the Aleste series by famed shoot-'em-up developer Compile where players must collect power-ups to defeat countless waves of enemies and large bosses.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1785], 'genres' => [8], 'publishers' => [111], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 446, 'game_title' => 'After Burner II', 'release_date' => '1990-07-15', 'platform' => 18, 'overview' => "Similar to its predecessor, the premise of After Burner II is to get on the F-14 Tomcat and fly mission after mission of shooting planes out of the sky. At your disposal is a vulcan cannon (basically a machine gun) and a limited number of missiles. In some versions of the game the guns fire automatically all the time. Sometimes you come across a friendly supply plane and if you dock with it you can replenish your missiles.\r\n\r\nThe game is viewed from behind the plane with you fighting wave after wave of enemy fighters. But at heart it offers the usual shooter mechanics, meaning you spend most of your time dodging and shooting. You also can speed up and slow down to deal with enemies which appear behind you.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [8], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 447, 'game_title' => 'Aerobiz Supersonic', 'release_date' => '1993-04-02', 'platform' => 18, 'overview' => "LEAD YOUR AIRLINE INTO THE FUTURE!\r\nIt’s the beginning of the 21st century and competition in the airline industry is heating up. As a young, ambitious CEO, it's up to you to make sure your airline is a survivor and not just another casualty. To succeed, you will have to make some tough decisions including where to fly, which planes to purchase and how to attract visitors to the cities you service. Your goal: to differentiate your airline from the rest while still turning a profit.\r\n\r\nln Aerobiz Supersonic, fashion a powerful fleet of aircraft from more than 50 possible choices. organize routes to 89 global destinations and invest your profits in a variety of new services including amusement parks. ski resorts and airport shuttle services. And don’t target as CEO you're still responsible for ings like plane maintenance, advertising and handling those periodic emergencies such as a plane crash or employee strike.\r\n\r\nGet ready to make some tough decisions! If you make the right ones. your planes will dominate the skies of the 21st century.\r\n\r\n*Offer air service to over 80 major and minor cities around the globe\r\n\r\n*Select from four eras in aviation history including two futuristic scenarios Purchase from an extensive list of historical, supersonic and fictitious airplanes\r\n\r\n*Invest in business ventures such as concert halls, golf courses and amusement parks\r\n\r\n*One to four player fun", 'youtube' => '', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4741], 'genres' => [3, 6], 'publishers' => [50], 'alternates' => ['エアーマãƒã‚¸ãƒ¡ãƒ³ãƒˆII 航空王をã‚ã–ã›', 'Air Management II: KÅkÅ« ÅŒ wo Mezase', 'Aerobiz 2', 'Air Management 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 448, 'game_title' => 'Air Diver', 'release_date' => '1990-04-01', 'platform' => 18, 'overview' => 'Your mission is to find and eliminate the enemy terrorists. They are extremely well armed, and central intelligence informs us that they may have the backing of several unfriendly extraterrestrial nations...', 'youtube' => 'hKxMMbK_Jj8', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1823], 'genres' => [1, 8], 'publishers' => [112], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 449, 'game_title' => "Disney's Ariel: The Little Mermaid", 'release_date' => '1992-01-01', 'platform' => 18, 'overview' => "King Triton and his daughter Ariel battle the dangers of the deep to save the kingdom. As Triton, you must rescue Ariel and break Ursula's curse. As Ariel, the little mermaid, you must battle bewitched sea creatures and defeat Ursula to save Triton and the kidnapped merpeople. Dodge angry sharks, sword-wielding skeletons, and falling boulders. Battle the Molten Lava monster and slimy, stinging eels. And if you dare, brave the snake-infested locks of The Medusa. Navigate through undersea mazes, avoiding traps. Pals Sebastian and Flounder rush to the rescue in tight spots. Open sunken treasure chests loaded with booty. Consult maps which lead to your imprisoned friends. Then come face to face with Ursula the Sea Witch, and battle her in a final showdown!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1233], 'genres' => [2], 'publishers' => [15], 'alternates' => ['Ariel: The Little Mermaid'], 'uids' => nil, 'hashes' => nil }, { 'id' => 450, 'game_title' => 'Art Alive', 'release_date' => '1991-01-01', 'platform' => 18, 'overview' => "Surprise yourself and impress your friends with astonishing graphics you can make in minutes. Animate them and your TV screen becomes a lively work of art. All with just your television and the 16-bit Genesis system. It's simply the easiest way to be an artist. Create masterpieces that run, jump, and dance! You can even record them on your VCR. It's better than a game... it's ART ALIVE! Turn your imagination loose with the gallery of tools: A rainbow of colors to paint with; 3 different pencil tips for freehand drawing; Circles, rectangles and squares in 3 different outline widths; Spray cans for shading patterns; An eraser and clear feature to make mistakes vanish; Over 50 supplied graphics and animations, including Sonic the Hedgehog and ToeJam & Earl, or create your own; Predrawn backdrops you can color with the fill bucket.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9585], 'genres' => nil, 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 451, 'game_title' => 'Ballz 3D: Fighting at Its Ballziest', 'release_date' => '1994-01-01', 'platform' => 18, 'overview' => "Ballz is a fighting game, but what makes it uniqe is the fact that your player is made out of balls. The game has a detailed 3D engine with a fixed camera. The game plays like your normal beat 'em up game. This game supports 2 players, 3 difficulties and up to 21 matches.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [6543], 'genres' => [10], 'publishers' => [113], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 452, 'game_title' => "Barney's Hide & Seek Game", 'release_date' => '1993-01-01', 'platform' => 18, 'overview' => "Barney is a friendly dinosaur who likes playing with children. One day Barney and his little friends decide to play hide-and-seek game. Barney's task is to find the children and the presents they have hidden.\r\n\r\nBarney travels across four different levels. On each one there are five children and five presents to find. You can only jump in the game when there are higher platforms to access. Despite being a platformer, this is not an action game, since Barney can't die and there is no quick reaction required to complete the game. The game is designed for little children and has a very low difficulty level.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [7050], 'genres' => nil, 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 453, 'game_title' => 'Bass Masters Classic: Pro Edition', 'release_date' => '1996-07-01', 'platform' => 18, 'overview' => "Don't miss your chance to compete in the most realistic fishing game for the Genesis. Featuring pro bass anglers George Cochran, Shaw Grigsby Jr., Gary Klein, Tom Mann Jr., Dee Thomas and Kevin VanDam, BASS MASTERS CLASSIC PRO EDITION brings world championship bass fishing indoors! Compete as one of six actual pro fishermen or as an amateur enthusiast in the Bass Masters Classic. Fish the waters in five three-day tournaments at five different lakes. Rich graphics recreate the outdoor fishing experience in vivid detail. Choose your rod, reel, lure, and even boat engine.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [1160], 'genres' => [11], 'publishers' => [114], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 454, 'game_title' => 'Batman Forever', 'release_date' => '1995-09-07', 'platform' => 18, 'overview' => "The Real Game Begins! BATMAN FOREVER! Brace yourself for endless action with BATMAN FOREVER! BATMAN and ROBIN blast into GOTHAM CITY in a duo-player fighting game! Armed with over 125 incredible attacks, fierce combat moves, and an arsenal of gadgets, the DYNAMIC DUO are ready to battle the diabolical minds of TWO-FACE and THE RIDDLER! Without question... it's BATMAN FOREVER! Featuring over 80 unbelieveable stages! Incredible 3-D computer-rendered graphics! Real digitized characters and backgrounds! Team up as Batman and Robin and find tons of secret rooms and hidden surprises!", 'youtube' => nil, 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [194], 'genres' => [1, 10], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 455, 'game_title' => 'BattleTech: A Game of Armored Combat', 'release_date' => '1994-12-31', 'platform' => 18, 'overview' => "'MECH WAR!!\r\n\r\nThe 31st century is a brutal and violent place. The galaxy is racked by a devastating war waged with gigantic 75-ton BattleMechs teeming with the most ruinous weapons that science can create. MechWarriors like you are needed to pilot the \"Madcat\" Heavy OmniMech on desperate missions against enemy installations. This is the world of BATTLETECH!\r\n\r\nAlone against the relentless onslaught of hordes of enemy defenders, you'll need skill and cunning to knockout your objectives! Steer your lumbering 'Mech into the savage fury of a hornet's nest of attackers, and cut loose with the Madcat's incredible firepower to lay waste to all before you! Fight to the last for a victory that will bring you honor and glory! And if honor isn't motivation enough, it helps to remember that the enemy doesn't take prisoners...\r\n\r\n-Use 9 futuristic and devastating weapons systems to obliterate enemy resistance!\r\n-Battle the ground defenses of the Inner Sphere on five different planets!\r\n-2-Player Cooperative Mode lets one player steer while the other controls the Madcat's weapons systems!", 'youtube' => nil, 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [5215], 'genres' => [1], 'publishers' => [115], 'alternates' => ['BattleTech'], 'uids' => nil, 'hashes' => nil }, { 'id' => 456, 'game_title' => "Bill Walsh College Football '95", 'release_date' => '1994-06-01', 'platform' => 18, 'overview' => 'Bill Walsh College Football 95 was one of the many football games released by Electronic Arts back in the day. This one was a bit different as it includes a full season team and player stats, weekly rankings and a windowless passing mode. It has 38 powerhouse teams, such as Florida, Florida State, Texas and Notre Dame to name a few. There are many offensive and defensive plays, over eleven different offensive formations with close to eight options a piece, and six different defensive formations.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [3835], 'genres' => [11], 'publishers' => [82], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 457, 'game_title' => 'B.O.B.', 'release_date' => '1993-06-01', 'platform' => 18, 'overview' => "When B.O.B. crashes his dad's space car on the way to pick up his date, he finds himself stranded on a hostile asteroid filled with enemies. By collecting power ups and using fast reflexes B.O.B. tries to find his way off the planet and to his date. B.O.B. fights his way through the forty-five levels, including boss fights and spaceship-racing stages.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [3590], 'genres' => [1], 'publishers' => [2], 'alternates' => ['BOB', 'B.O.B'], 'uids' => nil, 'hashes' => nil }, { 'id' => 458, 'game_title' => "Bram Stoker's Dracula", 'release_date' => '1993-09-01', 'platform' => 7, 'overview' => "In the game the player takes on the role of Jonathan Harker. Throughout the levels, Abraham Van Helsing will help Jonathan in his quest by providing advanced weapons. With the exception of the MS-DOS version, the game is of the side-scrolling genre. In the game, Jonathan Harker fights Lucy Westenra as a vampiress, Count Dracula's three brides, Dracula's coach driver, Dracula's fire-breathing dragon, Renfield and even Dracula himself and also in some different forms, such as him in his bat form, his young form and his evil wolf form. Levels in the game include the Romanian countryside, a rat-infested old village inn, Dracula's castle, Dracula's cavernous vaults, Dracula's misty catacombs, various locations in London, Lucy's crypt, a graveyard and Carfax Abbey.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7992], 'genres' => [1], 'publishers' => [77], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 459, 'game_title' => 'Bubsy in Claws Encounters of the Furred Kind', 'release_date' => '1990-05-01', 'platform' => 18, 'overview' => "The plot focuses on a race of fabric-stealing aliens called \"Woolies\", who have stolen the world's yarn ball supply (especially Bubsy's, who owns the world's largest collection). Naturally, Bubsy does not take too kindly to the theft and sets out to \"humble\" the Woolies.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [203], 'genres' => [2], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 460, 'game_title' => 'Bugs Bunny in Double Trouble', 'release_date' => '1996-06-01', 'platform' => 18, 'overview' => "BUGS BUNNY has dreamed his way into double trouble. A Mad Scientist is after Bugs' brain! To escape, bugs must use the Scientist's Televisor to travel through dreamland and outwit his LOONEY TUNES pals, including DAFFY DUCK, ELMER FUDD, and YOSEMITE SAM. But Bugs' nightmare doesn't end there. Before he can rest, Bugs must rocket to Mars to battle MARVIN THE MARTIAN and his trusty dog K-9. Move fast or... \"That's all Folks!\"", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [778], 'genres' => [15], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 461, 'game_title' => 'Bulls Versus Blazers and the NBA Playoffs', 'release_date' => '1993-02-26', 'platform' => 18, 'overview' => "Another update in Electronic Arts' basketball series, this time featuring the teams and players from the 1992 NBA playoffs plus the East and West All-Stars.\r\n\r\nFeatures unchanged from the previous games include detailed stats, instant replay, substitutions, free throw T-meter and signature moves, some of which are new.\r\n\r\nExclusive to the Genesis version is the ability to create your own All-Star teams and to call defensive plays.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [2724], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 462, 'game_title' => 'Centurion: Defender of Rome', 'release_date' => '1991-01-01', 'platform' => 18, 'overview' => "Centurion: Defender of Rome is a turn-based strategy game. You start with one province, Rome, and one legion. To complete the game, you have to conquer all the provinces on the map. \r\n\r\nOne part of the game is micro-managing your provinces. You set up tax rates and make people happy by organizing games. In Rome, you can organize a chariot race, a gladiatorial combat or even a simulated naval battle; this starts an action mini-game where you control the chariot rider, gladiator or ship.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [1125], 'genres' => [6], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 463, 'game_title' => 'Chester Cheetah: Wild Wild Quest', 'release_date' => '1994-01-01', 'platform' => 18, 'overview' => "The player may explore the game world in a non-linear fashion. At any time, there are three levels available and the player may tackle them in any order. Each solved level leads to additional two. On each level, the player must find the missing map piece, proceed to the exit, and defeat the level boss. Chester can dash and kill enemies by jumping on their heads. He dies from one hit, unless he has a pack of the cheetahs snack at his disposal. In this case, he'll recover full health.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4598], 'genres' => [1, 2], 'publishers' => [116], 'alternates' => ['wild wild quest'], 'uids' => nil, 'hashes' => nil }, { 'id' => 464, 'game_title' => 'Chiki Chiki Boys', 'release_date' => '1993-01-01', 'platform' => 18, 'overview' => "This platform-based action game was converted from a Capcom arcade game, and set in the land of Alurea. The idyllic life of the Alurean people was shattered when the King is killed by a dragon, and a range of nasties inhabit the lands. Fortunately his twin sons have come to the rescue, and you must take control of one or the other to put the world right.\r\n\r\nThe boys have differing skills - one is more skilled in sword-fighting (which you are always armed with), the other in magic (available in limited amounts on each level). You collect coins as the game goes on, and spend these in the shop on extra magic, extra lives and enhanced swords.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [1436], 'genres' => [1, 15], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 465, 'game_title' => 'Columns', 'release_date' => '1990-06-30', 'platform' => 18, 'overview' => "The game takes place inside a tall, rectangular playing area, as in Tetris. Columns of three different symbols (such as differently-colored jewels) appear, one at a time, at the top of the well and fall to the bottom, landing either on the floor or on top of previously-fallen \"Columns\".\r\n\r\nWhile a column is falling, the player can move it left and right, and can also cycle the positions of the symbols within it.\r\n\r\nIf, after a column has fallen, there are three or more of the same symbols connected in a straight line horizontally, vertically, or diagonally, those symbols disappear. The pile of columns then settles under gravity. If this causes three or more other symbols to become aligned, they also disappear and the pile settles again. This process repeats as many times as necessary. It is not uncommon for this to happen three or four times in a row - it often happens by accident when the well is becoming crowded. If the well fills beyond the top of the screen, the game ends.\r\n\r\nOccasionally, a special column called the Magic Jewel appears. The Magic Jewel flashes with different colors and when it lands, it destroys all the jewels with the same color as the one underneath it.\r\n\r\nLike Tetris, the columns fall at a faster rate as the player progresses. The goal of the game is to play for as long as possible before the well fills up with symbols.\r\n\r\nSome ports of the game offer alternate game modes as well. \"Flash columns\" involves mining their way through a set number of lines to get to a flashing jewel at the bottom. \"Doubles\" allows two players work together in the same well. \"Time trial\" involves racking up as many points as possible within the time limit.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [5], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 466, 'game_title' => 'Crue Ball', 'release_date' => '1992-04-26', 'platform' => 18, 'overview' => "ATTENTION HEADBANGERS! The Ultimate Heavy Metal Pinball Concert is about to begin! You just got front row tickets to a no-holds barred, totally rockin' Metalfest. It's up to you to blast the anti-rock forces and crank up the volume to the max. Crue Ball gives you a backstage pass to the ultimate pinball tour. Blistering soundtrack features three Motley Crue hits! Nine rippin' volume levels (that's play levels, dudes)! Special appearance by Motley Crue's Alister Fiend! Loads of skill shots and nasty enemies!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [6178], 'genres' => [11], 'publishers' => [2], 'alternates' => ['Crue Ball: Heavy Metal Pinball'], 'uids' => nil, 'hashes' => nil }, { 'id' => 467, 'game_title' => "Crystal's Pony Tale", 'release_date' => '1994-01-01', 'platform' => 18, 'overview' => 'You navigate your pony through various locations, collecting horseshoes on your way and "paying" them at level gates to pass to another location. You can explore the locations in any order you wish, traveling directly between them or using teleportation pictures. The game has more adventure than action elements. Crystal Pony cannot die in the game; if an enemy hits her, she merely loses one of her horseshoes. The only battles are against the witch, occurring every time you use a gem at the correct place. The pony would automatically jump over obstacles, but you can also make her jump with a corresponding button. You can get extra items by interacting with various objects and characters, pressing the action button.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [653], 'genres' => [15], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 468, 'game_title' => 'Cyber-Cop', 'release_date' => '1992-01-01', 'platform' => 18, 'overview' => 'A first person shooter that requires you to think things through rather than just attack anything that moves. This game preceded Wolfenstein 3D by a number of years, and while the walls were not ray cast, but solid fill polygons, it was still one of the earliest simulations to tackle a human viewpoint with complete, 360 degree freedom of movement.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [1827], 'genres' => [8], 'publishers' => [117], 'alternates' => ['Corporation'], 'uids' => nil, 'hashes' => nil }, { 'id' => 469, 'game_title' => 'Dark Castle', 'release_date' => '1991-01-01', 'platform' => 18, 'overview' => "The Black Knight has brought misery to the land, and the end way to end this is to enter his haunted house to slay him. You are the brave adventurer taking on this quest through 14 increasingly-tough zones.\r\n\r\nThe bulk of the game is side-viewed, involving single screens to pass through, which incorporate ropes, cages and trapdoor. There are enemies walking, flying and hovering through this, and many of them respawn. Unusually your weapon to take them on (rocks) can be thrown through 360 degrees, which aims to make the gameplay more realistic and methodical. The screens were linked by hub screens, which the player passes through simply by clicking on a door.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [7730], 'genres' => [1], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 470, 'game_title' => 'Desert Strike: Return to the Gulf', 'release_date' => '1992-06-04', 'platform' => 18, 'overview' => "The Scuds Are Back!!!\r\n\r\nWith a fiery blast from your Hellfire missiles you must annihilate a ruthless tyrant's military arsenal. Smoke his private yacht and tear into his air force as you challenge the Madman's forces in a series of surgical strikes. Rip through 27 fiery missions. Force is highly recommended.\r\n\r\n-The Madman's got his finger on the SCUD trigger! Annihilate his Scud launchers before their deadly cargo wreaks havoc on the Western World!\r\n-Battle the Madman's military machine over land, air and sea. One well placed Hellfire could send the tyrant down with his ship.\r\n-Spearhead a rescue assault mission into Embassy City and break out American hostages being used as human shields!\r\n-Check out the on-board computer battle maps and satellite data for locations of enemy MIGs, SCUDs, and dug-in tank encampments.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2724], 'genres' => [8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 471, 'game_title' => 'Double Dragon 3: The Arcade Game', 'release_date' => '1992-04-12', 'platform' => 18, 'overview' => "The original martial arts adventure continues - all the hard-hitting arcade action is at your command! Battle your way across the globe with awesome special moves and lethal weapons straight from the arcade! Whether it's a swirling Hurricane Kick or a staggering One Armed Head Butt, you have what it takes to crush ruthless enemies in the Double Dragon adventure of a lifetime! Battle across America, China, Japan and Italy to your ultimate challenge in Egypt!", 'youtube' => '', 'players' => 2, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [7940], 'genres' => [1, 2], 'publishers' => [118], 'alternates' => ['Double Dragon III: The Arcade Game'], 'uids' => nil, 'hashes' => nil }, { 'id' => 472, 'game_title' => 'ESPN National Hockey Night', 'release_date' => '1994-08-01', 'platform' => 18, 'overview' => "ESPN National Hockey Night was one of the many hockey games released back in the day. This one featured all the NHL teams for its time, but lacked an official players license.\r\n\r\nIt had four game modes to choose from: Exhibition, Challenge, Playoff, and Season. The game also features both a horizontal and vertical perspective of the ice, battery backup to save progress and also featured the voice of Bill Clement for play-by-play commentary.", 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6451], 'genres' => [11], 'publishers' => [77], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 473, 'game_title' => 'Eternal Champions', 'release_date' => '1993-01-01', 'platform' => 18, 'overview' => "From various time periods of past, present and future, nine fighters killed in an unjust manner find themselves given a second chance for life. An alien being, known only as the Eternal Champion, brings back the fighters into a competition for one reason: to find one among them worthy of being resurrected, giving them a chance to avert their death and tip the balance between good and evil.\r\n\r\nThe fighters range from different eras of Earth's History: Larcen, the cat burglar. Jetta, the circus acrobat. Blade, the futuristic bounty hunter. Midknight, the vampiric bio-chemist. Rax, the cyborg. Shadow, the corporate assassin. Slash, the neanderthal. Trident, a Atlantean warrior. And Xavier, a warlock and alchemist.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7549], 'genres' => [10], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 475, 'game_title' => 'Family Feud', 'release_date' => '1993-01-01', 'platform' => 18, 'overview' => "The rules conforms to the shows, divided into rounds until a family reaches 300 points and the \"Three Strikes\" rule. It also featured the new \"Bulls Eye Round\" that was introduced to the show at the time.\r\n\r\nTo answer questions, the player uses the D-pad to move a cursor and pressing the required button in order to select that letter and spell out their answer. Players can also battle each other as well as customize their family to their liking, from their appearance, hobbies, intelligence and occupations and customize the rules to suit the player.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4107], 'genres' => [6], 'publishers' => [80], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 476, 'game_title' => 'Fantastic Dizzy', 'release_date' => '1993-01-01', 'platform' => 18, 'overview' => "The evil wizard Zaks casts a spell on the Yolkfolk and kidnaps Dizzy's girlfriend Daisy. It is up to Dizzy to undo Zak's doings and rescue Daisy from the castle in the clouds.", 'youtube' => 'bQGJWIi2n14', 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [1568], 'genres' => [1], 'publishers' => [16], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 477, 'game_title' => 'Fatal Labyrinth', 'release_date' => '1991-01-01', 'platform' => 18, 'overview' => 'Dragonia, the castle of doom, has come upon the world and its minions have stolen the Holy Goblet. Without it, the world will be in darkness forever. You play as Trykaar, who must enter the castle and traverse its thirty levels to retrieve the Holy Goblet. There is no other storyline; its dungeons are generated randomly each time you play, like in Rogue-type games.Much like Nethack or other Rogue games, the game is turn-based.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [7549], 'genres' => [4], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 478, 'game_title' => 'Fatal Rewind', 'release_date' => '1991-01-01', 'platform' => 18, 'overview' => 'This is a vertical platformer with horizontal wrap-around. For the entertainment of the futuristic masses, you play a criminal that has been inserted into a mechanical body with the promise that if you succeed in surviving through all the levels (there are many and they are hard), you will be set free. You start each level at the bottom, near pooling liquid which will soon rise, at your immediate peril. Navigate the level from bottom to the exit at the top before the liquid rises and kills you. There are many other foes that fly around, causing you damage and basically annoying you to spit. Most levels must be navigated through a series of keyed gates, doors, or portals. These shaped keys are scattered around the map and must by picked up and used only on the gates they match individually. Twist: You can only carry one special weapon (triple shot, laser beam, or vertical shot) and one tool (key, liquid-freeze, or a red herring) at a time. This game requires a lot of memorization of enemy movement patterns and optimum routes. A unique feature is that when you die, you can watch a replay and take over at any point to continue your game. You can also hit the HELP button at the start of each level to view a map, helping you plan your route.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [6979], 'genres' => [15], 'publishers' => [2], 'alternates' => ['The Killing Game Show'], 'uids' => nil, 'hashes' => nil }, { 'id' => 479, 'game_title' => 'Ferrari Grand Prix Challenge', 'release_date' => '1992-01-01', 'platform' => 18, 'overview' => "Following F1 Grand Prix Nakajima Satoru, Varie produced another racing simulation using the license. This time the racing is from a first person view aping Super Monaco Grand Prix. The car setup can be modified before you take to the track\r\n\r\nThere is a Time Attack mode, allowing you to go for as fast a laptime as possible on any of the game's 20 circuits (which include the 16 tracks of the 1992 Formula 1 season), as well as a full season mode, with qualifying and the race itself. Weather can be customised in the Time Attack mode but is randomly chosen in Grand Prix mode, while you can only choose one of the D-tier teams (the 4 weakest of the 16) in grand Prix mode, but can drive for McLaren, Williams et al in Time Attack.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [307], 'genres' => [7, 11], 'publishers' => [118], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 480, 'game_title' => 'Final Zone', 'release_date' => '1990-01-01', 'platform' => 18, 'overview' => "It is 100 years into the future. Nuclear weapons, missiles and other weapons of mass destruction are banned, but a new piece of military hardware is about to shape the future. The N.A.P. (New Age Power-Suit), is the newest weapon, a mechanical tank, able to destroy anything in its path. You play as a soldier of the El Shiria Military's \"Undead\" unit named Howie Bowie (no joke) as you are about to go on a urgent mission to destroy your enemies, The Bloody Axis, before they can strike at your nation.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [9678], 'genres' => [1], 'publishers' => [119], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 481, 'game_title' => 'Funny World & Balloon Boy', 'release_date' => '1993-01-01', 'platform' => 18, 'overview' => "Funny World is an action game where the player must shoot strange animals as they move across the screen. On each stage a set number of \"funnys\" will cross the screen, and the player must shoot a certain number of them before they can safely reach the other side. To make things harder, some will walk, some will run, and some will move erratically; from time to time a female funny will cross the screen, which if shot will cause the player to lose a life. They player also has a certain number of boulders they can drop, which will hit any funny on the screen that may be out of the player's range. If enough funnys are hit, the player moves on to the next stage.\r\n\r\nBalloon Boy is an action game where the player controls a boy at the bottom of the screen who must shoot at balloons floating across the top. When shot, the balloons will release either a trap or an item, and the boy must collect the items while avoiding the traps. If all the balloons are destroyed before the time runs out, the player moves on to the next stage.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [817], 'genres' => [1, 8], 'publishers' => [120], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 483, 'game_title' => "Hard Drivin'", 'release_date' => '1991-01-01', 'platform' => 18, 'overview' => "Hard Drivin' is a 3D arcade hit from Atari Games. You are in control of a high-performance sports car. Your objective is to race around the course as fast as possible and hit as many checkpoints as possible. If you hit a checkpoint you gain extra time to go farther. You will see traffic on the road both in your direction and coming down the opposite direction, so be careful when you pass...", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [748], 'genres' => [7], 'publishers' => [111], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 484, 'game_title' => 'Haunting Starring Polterguy', 'release_date' => '1993-04-01', 'platform' => 18, 'overview' => "Scare the evil, greedy Sardinis out of their houses by turning everyday household objects into something scary, funny or just plain gross. Or use your special spells to really send 'em shrieking. But you gotta hurry, 'cause your ectoplasm may run out! 16 megs of cool graphics, gross special effects and blood-curdling sounds. Unique 3/4 view perspective. Over 400 scary, funny or gross fright items, each causing something different to happen. Five special spells: Zom-B-Ize, Supr-Scare, Boo-Doo, Ecto-Xtra and Dog-Off. \"Killer\" dungeon with 12 different paths!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2724], 'genres' => [1], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 485, 'game_title' => 'Hellfire', 'release_date' => '1991-01-01', 'platform' => 18, 'overview' => 'In the year 2998, humanity has finally reached the stars, and was able to build a prosperous, peaceful society. However, a space matter known as the Black Nebula began to spread, threatening to engulf the galaxies controlled by humans. It turned out that a robotic dictator named Super Mech was behind this occurrence. The Earth sends Captain Lancer, a skillful pilot navigating the powerful CNCS1 aircraft, equipped with the most powerful weapon: the Hellfire...', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [8503], 'genres' => [1, 8], 'publishers' => [112], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 486, 'game_title' => 'Herzog Zwei', 'release_date' => '1990-01-11', 'platform' => 18, 'overview' => "\"Eins! Zwei! Drei!\" In the murky dawn the tyrant's troops scuffle towards foxholes and tanks. Taking battle position, they quickly check their equipment and load cannons. Then they hunker down, awaiting the cry: \"Attacke!\" \"Hup! Two! Three! Four!\" On your order, rebel soldiers race to their war machines! Jets blast into the dawn, afterburners roaring. Convoys rumble toward the advance bases. Their single purpose: attack! War! You and your opponent face off for control of the world! You're equally matched, man for man, weapon for weapon. You sweat as you order out heavy metal, mobilize troops, and plot the attack! You collide in dogfights, ground frays, and naval clashes! At last, you advance to their home base. Now! Crush the enemy - and become Supreme Commander of the free world!", 'youtube' => 'cJHyfavhI-g', 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [8609], 'genres' => [6], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 487, 'game_title' => 'Home Alone', 'release_date' => '1991-10-31', 'platform' => 18, 'overview' => "As young Kevin McCallister, you have mistakenly been left home alone this Christmas by your family. The big problem here is that a couple of bumbling burglars have set their sights on the McCallister belongings as their ultimate heist. You're the only thing that stands in their way and they're not about to negotiate. Scramble through the house, basement and tree fort while setting incredible traps for the unwanted intruders! Bounce chandeliers and irons off their noggins in an attempt to gain valuable time for yourself as the police race to your rescue. Can you keep out of Marv and Harry's clutches and protect your family's treasures? Find out in this hilarious adaptation of the classic comedy hit of the year!", 'youtube' => nil, 'players' => 1, 'coop' => nil, 'rating' => nil, 'developers' => [1010], 'genres' => [6], 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 488, 'game_title' => 'The Humans', 'release_date' => '1992-05-14', 'platform' => 18, 'overview' => 'Your job in this action puzzler is to help prehistoric man to evolve by helping them discover tools, the wheel, weapons, or even fire. Each level in the game will have a given task to help in this, and you are allotted a number of characters who must accomplish the task. The player can switch from person to person while moving the characters around each scrolling puzzle, and teamwork is essential to success.', 'youtube' => 'EeUonNq_-KY', 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [4114], 'genres' => [5, 6], 'publishers' => [80], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 489, 'game_title' => 'The Immortal', 'release_date' => '1993-08-09', 'platform' => 18, 'overview' => "The Immortal is an isometric action-adventure game.\r\n\r\nYour old mentor Mordamir has disappeared. Probably kidnapped. You're not too sure where he might be, but a dungeon is always a good place to look, so you seek out the nearest one and plunge into its depths. Beware: 8 levels of isometric death await.\r\n\r\nThe Immortal is the prototype of a trial-and-error game. Progress is made by encountering a hazard, dying, solving the problem, encountering the next hazard. To solve a level, you have to know its traps and their patterns by heart. As frustrating as this may sound (it is), The Immortal quite cleverly balances annoyance with curiosity and graphical rewards.", 'youtube' => 'YvVFnGYuv_M', 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [2724], 'genres' => [1, 2], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 490, 'game_title' => 'Insector X', 'release_date' => '1990-01-01', 'platform' => 18, 'overview' => "They're gonna bug ya... to DEATH! Compared to these guys, killer bees are about as scary as a butterfly. In this awesome insect Empire you've got to be a fast gun! No can of bug spray will help you here. These giant mechanized insects mean business. Become too enthralled with the beautiful landscape and your daydreams could become a nightmare! Become... Insector X! A moment's delay could be your last!!", 'youtube' => 'https://www.youtube.com/watch?v=dlRPuTnKN1o', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7383], 'genres' => [1], 'publishers' => [56], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 491, 'game_title' => '100 Percent Star', 'release_date' => '2001-12-07', 'platform' => 10, 'overview' => '100% Playstation Star allows players to create a musical group from the beginning. Then you assume various businesses as a producer, manager, composer ... to create the group of your dreams. It all starts with the selection of stars by casting their next look. You will then have the task of composing the music for the album. Finally, a manager with the cap you manage the schedule: rehearsals, photo shoots, studio or concert.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8661], 'genres' => [9], 'publishers' => [26], 'alternates' => ['100% Star', 'Popstar Maker'], 'uids' => nil, 'hashes' => nil }, { 'id' => 492, 'game_title' => 'Actua Golf 3', 'release_date' => '1999-01-01', 'platform' => 10, 'overview' => "Actua Golf 3 is a golf simulation game featuring eight courses. You can completely customize your own character. With a new character you start with amateur tournaments until you have removed your handicap. Then you can participate in the pro tournaments.\r\n\r\nTo hit the ball in this game the player will have to use his analogue stick and swing that much like a real club.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3620], 'genres' => [11], 'publishers' => [121], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 493, 'game_title' => 'Akuji the Heartless', 'release_date' => '1998-12-31', 'platform' => 10, 'overview' => "In Akuji: The Heartless the player takes the role of Akuji, a voodoo-priest. The title of the game is meant to be taken literally as Akuji's wedding day brought a problem with it: his brother kills him and rips out his heart. Now Akuji has to travel through the underworld to get back to the living and take his revenge.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1963], 'genres' => [1], 'publishers' => [26], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 494, 'game_title' => 'Alone in the Dark: The New Nightmare', 'release_date' => '2001-06-18', 'platform' => 10, 'overview' => "Set on October 31, 2001. Edward Carnby's best friend and partner, Charles Fiske, has been found dead off the coast of Shadow Island, a mysterious island near the coast of Massachusetts. Carnby's investigation quickly leads him to Frederick Johnson, who informs him of Fiske's search for three ancient tablets with the ability to unlock an incredible and dangerous power. Johnson pleads with Carnby to take the place of Fiske and reopen the investigation in order to recover the tablets. Carnby accepts and makes it his mission to find Fiske's killer. Johnson introduces Edward to Aline Cedrac, an intelligent, young university professor. She joins Edward to recover the missing tablets and assist Professor Obed Morton, who she believes to be her father. While flying over the coast of Shadow Island, Edward and Aline's plane comes under attack by an unknown creature. Edward and Aline both jump out of the plane and parachute to the ground, but are separated immediately. Edward lands in the dense forest just outside a manor, while Aline lands on the roof of said manor.", 'youtube' => 'mb6XExJq1p4', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2112], 'genres' => [8, 18], 'publishers' => [72], 'alternates' => nil, 'uids' => [{ 'uid' => 'SLUS-01201', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 495, 'game_title' => 'Alundra', 'release_date' => '1997-12-31', 'platform' => 10, 'overview' => "Between the worlds of light and dark lies the world of dram. A world where the rule of reason loosens its grip. A place where an insidious evil is stealing minds and blackening the hearts of those from the world of light. Grab a weapon and become the dreamwalker Alundra as he struggles to purge the evil Id of an ancient world before it falls to ash.\r\n\r\nExplore dungeons, find monster butt as you weave between tense reality and nightmarish dreams to save the hapless masses. With a wide cast of characters and scores of challenging puzzles created by the people responsible for Landstalker on the Genesis. Alundra will rob you of precious sleep until you finish.", 'youtube' => '6Bk8-Eyu52o', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5302], 'genres' => [1, 2, 4], 'publishers' => [122], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 496, 'game_title' => 'Aqua GT', 'release_date' => '2001-01-26', 'platform' => 10, 'overview' => "Aqua GT is powerboat racing game. It features three modes: Championship, Arcade and Two-player.\r\n\r\nChampionship mode is the main single player game, where you advance through the Bronze, Silver and Gold Championships. In the Arcade gameplay mode you have to beat the clock. In two-player split screen mode you go head to head against another player.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6820], 'genres' => [7], 'publishers' => [123], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 497, 'game_title' => 'Army Men: Air Attack', 'release_date' => '1999-10-13', 'platform' => 10, 'overview' => 'The green and tan armies once again battle, this time in the air via the huey(agile helicopter), chinook(Double rotor heavyweight lifting helicopter), Super Stallion and Apache. The tan army are not the only enemies. Insects also get in the way. You must protect tanks, trucks, other helicopters, a train and even a UFO.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [77], 'genres' => [1], 'publishers' => [63], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 498, 'game_title' => 'Asterix and Obelix Take on Caesar', 'release_date' => '1999-03-01', 'platform' => 10, 'overview' => "- For controller pros and budding tacticians alike!\r\n- Choose your own path through the game\r\n- Intelligent romans (for once...)\r\n- Plenty of punch-ups - in 3D!\r\n- Asterix the \"Intelligent\" action game.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [8013], 'genres' => [1, 6], 'publishers' => [72], 'alternates' => ['Astérix: The Gallic War', 'Astérix'], 'uids' => nil, 'hashes' => nil }, { 'id' => 499, 'game_title' => 'A-Train', 'release_date' => '1996-01-01', 'platform' => 10, 'overview' => "Although trains are your primary source of income in the beginning of the game, A-Train is not about building trains exclusively. By utilizing the train industry as well as buses and subways, it is up to you to manage an efficient transportation system for passengers and freighting companies. Everything you do must be well thought out because you're out to make a profit.\r\n\r\nAs soon as you've earned the adequate funds, you have to start making investments. With your money you can buy and sell all types of land and businesses. If you think you're lucky enough, you may opt to play the stock market. Purchased land can be developed in a variety of ways, such as in the development of offices, apartments, hotels, factories, golf courses, and so on. It is up to you to build the largest financial empire humanly possible.\r\n\r\nAs the city develops, new businesses will spring up, such as stadiums, high rise office blocks, and ski resorts. You can also build your own businesses, the success of which will depend on the local population, the presence of competing businesses, and even the changes of the seasons, among other factors.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [651], 'genres' => [6], 'publishers' => [124], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 500, 'game_title' => 'Ball Breakers', 'release_date' => '2000-07-26', 'platform' => 10, 'overview' => "The universe is made up of human and synthetic lifeforms. Synthetic lifeforms are considered second class citizens by their human counterparts. The story takes place on the prison planet Alpha Prime, a world completely designed for the holding of criminals. You are a synthetic lifeform sentenced for an eternity for a crime you didn't commit and in order to earn your freedom, you must compete against other prisoners in competitions in 10 different incarceration facilities. To compete in these competitions however, you must undergo a procedure that removes your legs and replaces it with a rolling sphere.\r\n\r\nThere are seven different events to compete in which are Pursuit, Last Man Rolling, Race, King of the Hill, Run the Gauntlet, Tag, and Powerball that pit you not only against your fellow inmates and guards, but against the levels themselves. Run the gauntlet charges you with making it to a goal point within a time limit, all the while avoiding other warriors and obstacles such as flame throwers, spikes, and gun turrets. Pursuit is identical, but it adds the challenge of the arena crumbling away. Powerball has you collecting balls throughout the arena and throwing them at a goalpost before time runs out. Tag has you collecting a set number of tokens that have been scattered throughout the arena within a set time limit.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5057], 'genres' => nil, 'publishers' => [123], 'alternates' => ['Moho'], 'uids' => nil, 'hashes' => nil }, { 'id' => 501, 'game_title' => "King's Field (Japan)", 'release_date' => '1994-12-16', 'platform' => 10, 'overview' => "The Japan-only release of the first installment in From Software's \"King's Field\" series.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [3192], 'genres' => [2, 4], 'publishers' => [126], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 502, 'game_title' => 'Beyond the Beyond', 'release_date' => '1996-08-31', 'platform' => 10, 'overview' => 'Beyond the Beyond gather warriors, mages, pirates and mystics. Observe as they transform into more powerful classes. Clerks evolve into high clerks monks into master monks and conjurers into mighty summers. Unravel complex secrets in two richly textured views, explore in lush top-down isometric view and battle savage enemies in full 360. Grow stronger and smarter, with each victory your swordsmanship increases in power and your magic will swell with potent energy. Use supreme magic to summon monsters, fatal storms to hurl tormentors into another dimension or drown them in a boiling sea of fire.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1421], 'genres' => [4], 'publishers' => [127], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 503, 'game_title' => 'Big Air', 'release_date' => '1999-02-28', 'platform' => 10, 'overview' => 'Includes several snowboarding events - standard slalom-style, half pipes, races, and more. Also features several licensed riders, 24 courses, and lots of licensed music.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6622], 'genres' => [11], 'publishers' => [113], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 504, 'game_title' => 'Black Dawn', 'release_date' => '1996-09-30', 'platform' => 10, 'overview' => 'Set in 1998, the player controls a helicopter ace recruited into a black ops counterterrorism strike force named Operation Black Dawn. The player pilots the agile AH-69 Mohawk, an advanced combat helicopter with a powerful arsenal of weaponry. The game consists of seven campaigns that take place in different areas, and each campaign has a number of different missions. In addition to search-and-destroy objectives, there are hostages that require saving. The game has drawn comparisons with Soviet Strike, another helicopter simulator released in the same year. However, Black Dawn resembles an arcade game rather than a typical simulator, not least because various power-ups are obtained from destroyed enemies.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1154], 'genres' => [1], 'publishers' => [117], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 505, 'game_title' => 'BRAHMA Force: The Assault on Beltlogger 9', 'release_date' => '1997-03-31', 'platform' => 10, 'overview' => "A mech-based FPS; pilot your Bipedal Robotic Assault Heavy Mechanized Armor (built by Bronx Industries, of course) through the Beltlogger 9 excavation colony...\r\n\r\n...discover what happened to the Beltlogger 9 colony- it may be related to the events on Probe Ship Mina 3, wherein a lone person apparently under the control of an outside intelligence slaughtered his shipmates.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1829], 'genres' => nil, 'publishers' => [109], 'alternates' => ['BRAHMA Force'], 'uids' => nil, 'hashes' => nil }, { 'id' => 506, 'game_title' => 'Breath of Fire III', 'release_date' => '1997-09-11', 'platform' => 10, 'overview' => "A MYSTERIOUS POWER...AN UNLIKELY HERO...A CLASSIC ADVENTURE...\r\n\r\nThe lone survivor of a legendary dragon clan, a rebellious youth embarks on a great journey. One of discovery... and danger. The classic role-playing game now returns to continue the epic tales of Ryu and the dragon people. An inner power of uncertain origin matures Ryu into a warrior who ponders his purpose as he embarks on a mystical journey. What lies ahead is shrouded in mystery... yet strangely familiar.\r\n\r\nDRAGON GENE SPLICING\r\nLEGENDARY ROLEPLAYING\r\nAN EPIC 3-D ENVIRONMENT\r\nLEARN OR STEAL ADVANCE SKILLS AND TECHNIQUES\r\nPOWERFUL MAGIC\r\n\r\nNOW YOU POSSESS THE POWER TO CONTROL RYU'S DESTINY.", 'youtube' => 'w1PGuMfytHc', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1436], 'genres' => [4], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 507, 'game_title' => 'Breath of Fire IV', 'release_date' => '2000-04-27', 'platform' => 10, 'overview' => "Stunning New and Improved Graphics - High Resolution, Animated Characters in Vast 3-D Worlds\r\n\r\nMore Than 200 Spells to Learn and Master - Unlock New Magic From Opponents\r\n\r\n2 Epic Intertwining Storylines - Follow the Fates of Ryu and Fou-Lu - A Classic RPG Adventure!\r\nOne Princess. Two War-Torn Lands.\r\nAn Epic Quest for Peace\r\n\r\nAfter centuries of war, the two lands bordering an impenetrable swampland have finally reached an armistice. Mysteriously, the noble Princess Elena disappears somewhere near the war-ravaged front lines. Distraught, her sister Nina goes in search of the Princess alone and on her journey, meets a mysterious, young warrior named Ryu. Their destinies soon entwine. The next chapter in the epic tale of magic and mystery now unfolds. The fate of what lies ahead rests in your control.", 'youtube' => 'fTzU3A2I7BU', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1436], 'genres' => [4], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 508, 'game_title' => 'Brigandine', 'release_date' => '1998-04-02', 'platform' => 10, 'overview' => "Brigandine: The Legend of Forsena is a role-playing war simulation title in the fashion of Tactics Ogre, Ogre Battle, and Final Fantasy Tactics. At the beginning of the game, players will select one of five different Knights of the Rune and defend a specific piece of Forsena. Lance is a young fourteen year old prince that has been summoned to protect New Almekia and Late Badostow; Lyonesse must defend her kingdom of Leonia; and the lord-ranked Vaynard will defend the northlands with his White Wolf warriors.\r\n\r\nFrom the Strategy Map, players will organize their party members into effective attack forces, equip newly found weaponry, check statistics, and move around the map in search for enemy soldiers. Battles take place on a hexagonal piece of country land with fixed amounts of character movements and actions. Depending on the class of certain characters, as the commander, you'll order your troops to unleash rune assaults, magical spells, and attacks with bows, blunt objects, and swords.", 'youtube' => 'g9cBs26A_Cs', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3777], 'genres' => [4, 6], 'publishers' => [58], 'alternates' => ['Brigandine: The Legend of Forsena', 'Brigandine - Legend of Forsena'], 'uids' => nil, 'hashes' => nil }, { 'id' => 509, 'game_title' => 'Bust-A-Move 4', 'release_date' => '2000-01-31', 'platform' => 10, 'overview' => "Puzzle Bobble 4 (also known as Bust-a-Move 4 in North America and Europe) is the third sequel to the video game Puzzle Bobble and is the final appearance of the series on the Arcade, PlayStation and Dreamcast. The game is also the final title to be recognizably similar in presentation to the original.\r\n\r\nBuilding upon the success of Puzzle Bobble 3, the game adds a pulley system that requires two sets of bubbles, attached to either side of a rope hanging across two pulleys. The game contains a story mode for single player play.", 'youtube' => 'og4R3YrvIzk', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8449], 'genres' => [5], 'publishers' => [130], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 510, 'game_title' => 'Casper', 'release_date' => '1996-08-01', 'platform' => 10, 'overview' => "The plot centers around the \"spoiled, grasping inheritor of Whipstaff Manor\" - Carrigan Crittenden. She's after the treasure she thinks is hidden in the walls. Casper will need the help of Dr James Harvey - therapist to the dead - if he has any hope of succeeding in his adventures.", 'youtube' => 'naL_d9nT0XM', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [181], 'genres' => [1, 2], 'publishers' => [130], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 511, 'game_title' => 'Castlevania: Symphony of the Night', 'release_date' => '1997-03-20', 'platform' => 10, 'overview' => "Five years ago, Richter Belmont, the latest in the Belmont lineage and the one destined to be a Vampire Hunter, defeated Dracula in a brutal battle which nearly cost him the love of his life, Annette, and her sister, Maria. Now, Richter has suddenly vanished, CastleVania has mysteriously reappeared, and Maria, now a young woman, sets off to find Richter. Alucard, the son of Dracula, is awakened from his eternal slumber after this large shift in power, and enters into Castlevania to find some answers and perhaps destroy the castle once again.\r\n\r\nSymphony of the Night is a direct sequel to Dracula X: Rondo of Blood. The game is set in a castle which you can explore freely with many different paths, although often items in certain areas need to be found that will allow passage to others. The action-based gameplay incorporates now strong RPG elements. The hero receives experience points for defeating enemies, gains levels and becomes more powerful. There is also money to be found in the game, and various accessories to buy. In a separate screen, players need to equip attack weapons, shields and other items. Magic plays an important role, as well as secondary weapons and a large amount of \"special moves\" that are executed similar to advanced one-on-one fighting games.", 'youtube' => 'd2JsYKbWubY', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [4765], 'genres' => [1, 2], 'publishers' => [23], 'alternates' => ['Akumajou Dracula X: Gekka no Yasoukyoku'], 'uids' => nil, 'hashes' => nil }, { 'id' => 512, 'game_title' => 'Championship Bass', 'release_date' => '2000-02-29', 'platform' => 10, 'overview' => 'Bass fishing reaches new level with Championship Bass! Artificial Intelligence creates the most realistic behavior in simulated bass ever. False strikes, swerves, return attacks, and short-strike lunges will keep you on the edge. Even if you do land a strike, watch these fish go for obstacles in order ot break your line! Multiple difficulty levels, plenty of tricks in your lure box, multiple game modes, multiple lakes, and more. Sit in a boat and go for the fish, or simulate a whole fishing trip. The choice is yours!', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2724], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 513, 'game_title' => "Chocobo's Dungeon 2", 'release_date' => '1999-11-30', 'platform' => 10, 'overview' => "FINAL FANTASY's Chocobo stars in an all-new adventure!\r\n\r\nIn search of treasure, Chocobo and Mog find more than they expect. Joined by other FINAL FANTASY characters, Chocobo must defeat foes and unveil a friend's secrets while exploring a series of mysterious dungeons.\r\n\r\nPlayers can combine armor or weapons to form stronger resources in their quest. There are also magic feathers that can aid in your efforts, since they allow gamers to perform magic spells that have an impact on combat. Between your dungeon travels, players are able to explore villages to obtain valuable clues for the journey. In addition, players can use this time to update Chocobo's inventory.", 'youtube' => 'rGwqyWsqc9w', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8096], 'genres' => [1, 4], 'publishers' => [11], 'alternates' => ["Chocobo's Magical Dungeon 2"], 'uids' => nil, 'hashes' => nil }, { 'id' => 514, 'game_title' => 'Cool Boarders 2', 'release_date' => '1997-10-31', 'platform' => 10, 'overview' => "Cool Boarders 2 features four stock riders and six stock tracks. Many more are available as you progress through the game or unlock them with codes or secrets.\r\n\r\nThis installment of the Cool Boarders series features a split screen \"Vs\" mode, where two human players can race each other. It also features a one person race option, to race against up to six CPU controlled players.\r\n\r\nThe tracks all vary in length and challenge level. There is also a half pipe, Boardpark level and a Trick Master Run with continuous jumps and a tutorial to teach you all the moves. The move list in Cool Boarders 2 is quite extensive, including standard board grabs and various flips and spins. The graphic technology is primarily based on 3D polygonal models. The game also features red book audio.", 'youtube' => 'p7mrFzi-aQA', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9188], 'genres' => [11], 'publishers' => [21], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 515, 'game_title' => 'Crash Bandicoot 3: Warped', 'release_date' => '1998-10-31', 'platform' => 10, 'overview' => "After defeating Dr. Neo Cortex, Crash and his sister, Coco, take a well-deserved vacation. However, their friend, Aku Aku, has a bad feeling, and as usual, he is right. Aku's evil twin, Uka Uka, was the person behind all of Dr. Cortex's schemes. Now Uka and Cortex have hatched a plot to gain control of the powerful crystals they desire. The have hired Dr. N. Tropy to create a time machine, which will allow Uka and Cortex to go back and take the crystals without interference. Take control of Crash and Coco as they travel through 30 levels across five time periods in an effort to stop Uka and Cortex. Use a motorcycle, plane, bazooka, and a baby T-rex to help Crash survive, or destroy the bad guys by using new moves like the super belly flop or the double jump. Will Crash and Coco be able to save the world? Play CRASH BANDICOOT: Warped and find out.", 'youtube' => 'r-bnMlpmkiE', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5839], 'genres' => [2, 15], 'publishers' => [21], 'alternates' => ['Crash Bandicoot 3: Warped', 'Crash 3: Warped'], 'uids' => nil, 'hashes' => nil }, { 'id' => 516, 'game_title' => 'Crusader: No Remorse', 'release_date' => '1996-12-31', 'platform' => 10, 'overview' => "As No Remorse opens, a trio of Silencers—enigmatic super-soldiers—are returning from a botched mission in which they disobeyed an order to fire upon civilians who were (mistakenly) believed to be rebels. They are ambushed by a WEC mech, and two of the Silencers are killed. The remaining one, a nameless captain, (whom the player plays as), joins the Resistance, where, as a significant symbol of the WEC's military power and political philosophy, he meets with resentment, distrust and outright hatred. However, he uncomplainingly undertakes dangerous missions, often with substandard equipment, and his continued success gradually earns the respect of his fellow Resistance members.\r\n\r\nThe Captain eventually uncovers secret plans for a WEC space station, the Vigilance Platform, which can attack any location on Earth from space, meaning cities with a known Resistance presence can simply be annihilated at the leisure of the WEC. All such cities are threatened with orbital bombardment unless they surrender. Concurrently, the player's Resistance cell is betrayed from within, and almost all the non-player characters are killed. Despite these setbacks, the Captain infiltrates the Vigilance Platform and destroys it. The traitor is also on the station, guarding the lifepods, and challenges the Silencer to a duel over the access card for the last pod. As the Vigilance Platform is exploding, the Captain is contacted by Chairman Draygan, who swears vengeance against the Silencer.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7050], 'genres' => [1, 2, 8], 'publishers' => [131], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 517, 'game_title' => 'Danger Girl', 'release_date' => '2000-09-14', 'platform' => 10, 'overview' => "Danger Never Looked So Good!\r\n\r\n3rd person action-adventure has never been sexier with DANGER GIRL, the only videogame based on on the best-selling comic book series by J. Scott Campbell and Andy Hartnell.\r\n\r\nDare to take control of 3 beautiful yet leathal Danger Girls in an espionage-themed thrill-ride deemed to dangerous for any man to handle!\r\n\r\n* \"I love to unleash my bullwhip, sniper rifle, and grenades on hammer goons!\"\r\n* \"Check out our loading screens, featuring original artwork by our creators!\"\r\n* \"Help me use my high-tech spy gadgets including infra-red goggles, bomb decoders and more...\"\r\n\r\nCOLLECTORS ITEM!\r\nManual features exclusive character sketches, bios and artwork from the creators!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5793], 'genres' => [8], 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 518, 'game_title' => 'Destrega', 'release_date' => '1999-01-31', 'platform' => 10, 'overview' => "Thousands of years ago, a people known as the Strega came to the country of Zamuel offering the secrets of peace and understanding. With them they brought great knowledge and power and shared gifts with the people to exercise powers such as those the Strega had. They showed the path towards true enlightenment, but underestimated the overwhelming drive of human greed and ambition.\r\n\r\nNow Lord Zauber has gained the control of the Strega relics. He seeks to wipe out any opposition to him and hunt down descendants of the Strega and eradicate them.\r\n\r\nPossibly one of the most in-depth fighting adventures to date, Destrega melds role playing with fighting. Moving freely within an environment that includes castle ruins, underground caverns and wide open countryside, you must discover the secret of the legendary relics, learn the truth behind the Strega and stop the Zauber's evil ambitions.", 'youtube' => 'q9KDJvJPJgI', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6242], 'genres' => [10], 'publishers' => [50], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 519, 'game_title' => 'Die Hard Trilogy', 'release_date' => '1996-08-20', 'platform' => 10, 'overview' => "You're at the center of three totally different, thrill-packed adventures. Every adventure you choose delivers amazing depth, palm-sweating realism and fully-rendered detail over thirty incredible levels.\r\n\r\n* Die Hard - Full screen 3-D action as you fight to rescue innocent hostages in a skyscraper wired to explode!\r\n\r\n* Die Hard 2: Die Harder - Arcade shooting at its fastest and finest as you eliminate terrorists at Dulles Airport.\r\n\r\n* Die Hard With A Vengeance - Heart-accelerating, simulated driving adventure as you race through New York City to find hidden bombs!", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [6787], 'genres' => [1], 'publishers' => [132], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 520, 'game_title' => 'Digimon World', 'release_date' => '2000-05-23', 'platform' => 10, 'overview' => "The PlayStation's answer to the Pokémon series phenomenon from Nintendo, Digimon World lets you raise customized Digimon monsters, training them for battle against other Digimon found in Digimon World. Most Digimon originally called File Island home, but for some unknown reason over time they lost the ability to speak and now live a nomadic lifestyle.\r\n\r\nIt is your goal to roam the dangerous countryside with your trained Digimon battling other lost Digimon. A victorious battle permits them to return home to the abandoned File Island. The main one-player mode on Digimon World is where the mysterious story unfolds as you raise your immature Digimon. Digimon are dependant on you for happiness, food, and parental guidance to guide their behavior (similar to the popular Tamagotchi toy).\r\n\r\nDigimon mature while \"working out\" in the training area and as you battle various Digimon in the surrounding areas. Your pet Digimon can compete against friends' Digimon in Battle Mode that provides an arena for head-to-head combat. A loss against a friend can provide plenty of initiative to return to the main mode to strengthen your Digimon, but you'll need one block of free space on the memory card to save your progress.", 'youtube' => 'CQ8m0HUDG0Y', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3107], 'genres' => [2], 'publishers' => [57], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 521, 'game_title' => 'Driver 2', 'release_date' => '2000-11-13', 'platform' => 10, 'overview' => "You are an undercover driver, trying to survive amidst an international war between American and Brazilian gangs. The action takes you to Chicago, Las Vegas, Rio and Havana, all of which are depicted in detail, with curved roads added from the first game.\r\n\r\nAs before, you have full control over the car as it storms around the streets. A new feature is the ability to get out of the car, and carjack others. This is especially useful when you have fallen victim to the advanced damage modeling.\r\n\r\nThere is a full sequence of missions to complete, as well as some pre-set challenges and a Free Driving mode allowing you to explore at your leisure.", 'youtube' => 'pxyePoT1Su0', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7109], 'genres' => [1, 7], 'publishers' => [72], 'alternates' => ['Driver 2: Back on the Streets', 'Driver 2: The Wheelman is Back'], 'uids' => [{ 'uid' => 'SLES-02994', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 522, 'game_title' => "Sesame Street: Elmo's Number Journey", 'release_date' => '1998-10-16', 'platform' => 10, 'overview' => "In Sesame Street: Elmo's Number Journey you assume the role of the cuddly red Muppet Elmo as you journey and explore three different fantasy worlds. These worlds are Cookie Monster's World, Count Von Count's Castle and Ernie's Carnival in the Park. You will begin your adventure on Sesame Street, where you will meet Sesame Street characters who invite you to visit their fantasy worlds to search for numbers and play games. Before you leave Sesame Street you can interact with the characters around you as well as visit Elmo's Room, where you can practice playing the game. While in Elmo's Room you can also view the game's credits and watch preview videos from Sony Wonder (by pressing the \"down\" directional button).\r\n\r\nEach of the three fantasy worlds you will travel to consist of two different game environments and a bonus world. Once you have acquired the correct amount of numbers required to pass through each fantasy world you will be instantly transported to the bonus world where you will be challenged to solve simple addition and subtraction problems.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'EC - Early Childhood', 'developers' => [7050], 'genres' => nil, 'publishers' => [133], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 523, 'game_title' => 'Evil Zone', 'release_date' => '1999-05-31', 'platform' => 10, 'overview' => "Originally released in Japan a few months ago as the tongue-twistingly titled Eretzvaju, Titus has picked up the projectile-based fighter and released it in the States as the hilariously named Evil Zone. An amalgamation of Psychic Force and Destrega, Evil Zone is a projectile-based 3D fighter that adds a dynamic element lacking from most of today's fighting games. Developed by Yuke's, the team behind the successful (in Japan at least) Toukon Retsuden series, and the not so successful Soukaigi (Square's recent action RPG), Evil Zone is a refreshing surprise from a development team not known for fighting games.\r\n\r\nThe premise in Evil Zone centers around the main character, Danvaizer, a superhero in the mold of classic Japanese afternoon TV shows (a la Power Rangers, Kamen Rider, etc.). While the storyline is truly superfluous, it nevertheless suffices as reason enough to gather Danvaizer and nine other combatants together to do battle in a distinctly different manner than most other fighting games.", 'youtube' => 'HznxJVvMo_k', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9785], 'genres' => [10], 'publishers' => [64], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 524, 'game_title' => 'Fighting Force 2', 'release_date' => '1999-11-30', 'platform' => 10, 'overview' => "Fighting Force 2 is a beat-em-up/adventure game set in the not-to-distant future. Human cloning has become a real possibility, but has been banned by an international treaty. The Knackmiche Corporation has been suspected of researching cloning, and you, Hawk Manson, are sent in on a covert mission to investigate.\r\n\r\nThis game features large levels and both hand-to-hand and weapons combat.", 'youtube' => '7pgzFeaCPJg', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1827], 'genres' => [1, 10], 'publishers' => [26], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 525, 'game_title' => 'Final Fantasy VII', 'release_date' => '1997-06-01', 'platform' => 10, 'overview' => "Set in a dystopian world, Final Fantasy VII's story centers on mercenary Cloud Strife who joins with several others to stop the megacorporation Shinra, which is draining the life of the planet to use as an energy source. As the story progresses, the situation escalates and Cloud and his allies face Sephiroth, the game's main antagonist.", 'youtube' => '1UwO1xgiOUE', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8096], 'genres' => [4], 'publishers' => [11], 'alternates' => ['ファイナルファンタジーVII Fainaru FantajÄ« Sebun', 'Final Fantasy 7'], 'uids' => [{ 'uid' => 'SCES-00867', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 526, 'game_title' => 'Final Fantasy VIII', 'release_date' => '1999-02-11', 'platform' => 10, 'overview' => "A member of an elite military team, Squall is forced into a conflict beyond imagination. To survive, he must contend with a desperate rival, a powerful sorceress, and his own mysterious dreams.\r\n\r\n* Realistic, detailed characters and background graphics enhanced by a breathtaking musical score\r\n* An epic story based on the theme of love, set in a massive new world\r\n* New Junction System allows characters to be customized with powerful magic spells drawn from enemies\r\n* Nearly an hour of stunning motion-captured CG cinemas seamlessly integrated into gameplay", 'youtube' => '2qH6gPZS1zI', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8096], 'genres' => [4], 'publishers' => [11], 'alternates' => ['Final Fantasy 8'], 'uids' => nil, 'hashes' => nil }, { 'id' => 527, 'game_title' => 'Final Fantasy IX', 'release_date' => '2000-11-13', 'platform' => 10, 'overview' => 'A band of thieves are hired to kidnap Princess Garnet of Alexandria. After they succeed, they end up becoming her guardians. And while protecting the fair Princess from a powerful evil...they hold the fate of the world in their hands. Play along on the epic journey filled with danger, mystery, war and love.', 'youtube' => 'MaJDP5uOV2w', 'players' => 2, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [8096], 'genres' => [4], 'publishers' => [11], 'alternates' => ['ファイナルファンタジーIX Fainaru FantajÄ« Nain', 'Final Fantasy 9'], 'uids' => nil, 'hashes' => nil }, { 'id' => 528, 'game_title' => 'Final Fantasy Anthology', 'release_date' => '1999-10-05', 'platform' => 10, 'overview' => 'Final Fantasy Anthology combines two titles from the Final Fantasy series and offers PlayStation owners a glimpse into the past. Huge worlds, in-depth storylines, and innovative battle and magic systems, and an incredible cast of characters all make for a deep gaming experience. The inclusion of Final Fantasy V marks the first time this title has appeared on a console in North America. Final Fantasy VI, originally released as Final Fantasy III on the SNES system in the U.S., makes its first appearance on the PlayStation. Both games in this compilation feature never-before-seen CG movies, adding to the appeal of these classics.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8096], 'genres' => [4], 'publishers' => [11], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 529, 'game_title' => 'Formula One 99', 'release_date' => '1999-10-31', 'platform' => 10, 'overview' => "Formula One 99 is the fourth installment in Psygnosis' FIA-licensed, Formula One series. All the racing teams, drivers, cars, and technical specs have been updated to match changes in the real world of Formula One racing. Even the newly constructed (as of 1999) Sepang International Circuit in Kuala Lumpur, Malaysia has been added to the season.\r\n\r\nPlayers may choose to participate in a Quick Race, an arcade-style game, a Grand Prix, which is a racing simulator, and various two-player racing options. In Quick Race, there is no concern for fuel, damage, pits or penalties. Select a track, set up race options such as weather, and go.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8252], 'genres' => [7], 'publishers' => [135], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 530, 'game_title' => 'Front Mission 3', 'release_date' => '2000-02-29', 'platform' => 10, 'overview' => "Yokosuka, Japan, 2112 AD. The young student Kazuki Takemura works as a test pilot with Kirishima Industries, a production company of military battle wanzers (walking panzers), mechanized walking robots with movement similar to that of a human being. Kazuki has just finished testing the combat capabilities of the new Zeinslev prototype in the lab. Finishing his day's tasks he is asked by his best friend Ryogo to help with a company delivery to the Japanese Defense Force (JDF) military based. This simple choice determines where Kazuki is when strange things begin happening in Japan. A large explosion, a wanzer theft, his sister Alysia being hunted, rumors of a powerful weapon, and accusations of involvement by agents of both the OCU and the USN all make the situation more complicated. Kazuki is swept up in a plot of conflicting loyalties and attacked by various factions. He will need to recruit additional characters and wanzers in order to be victorious in battle and investigate leads to uncover what is going on.", 'youtube' => 'uqkkyC8Jz-s', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8096], 'genres' => [4, 6], 'publishers' => [136], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 531, 'game_title' => 'Galerians', 'release_date' => '2000-03-29', 'platform' => 10, 'overview' => "A fleeting memory. A haunting vision. A childhood mystery that can prevent the destruction of mankind. Crave Entertainment, Inc. introduces Galerians, a survival-horror title for the PlayStation that thrusts players into a twisted future.\r\n\r\nRion is a young boy who awakens in a laboratory, unable to remember anything except his name. He soon discovers that he possesses psychic powers, although they come with severe consequences. With only a girl named Lilia, whose voice guides him, Rion must escape his captors and begin putting together the broken shards of his memories.\r\n\r\nPlayers assume the role of Rion and must guide him through four locations in his search for Lilia and the secret of his past. Armed with powerful psychic abilities, Rion must combat human enemies and a variety of frightening genetic experiments. Unfortunately, nothing can prepare him for the confrontation with his own history.\r\n\r\nThe game spans three discs, combining action and puzzle solving in a horrific setting. Galerians utilizes a third-person perspective and features polygonal characters on pre-rendered backgrounds. The shocking truth is gradually revealed through fragmented visions and confessions, building to an epic struggle between man and machine.", 'youtube' => 'Nqm3ai28-lQ', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [6733], 'genres' => [18], 'publishers' => [68], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 532, 'game_title' => 'G-Police', 'release_date' => '1997-10-15', 'platform' => 10, 'overview' => "After a violent interstellar resource war, mega-corporations seize power from the remnants of Earth's governments and lead humanity's way into the colonization of space. The last vestige of central authority is in the form of the G-Police (Government Police); an independent agency tasked with keeping order in the colonies. You play as rookie Jeff Slater - a former military pilot going undercover at the G-Police squadron on Callisto, in the hopes of finding the truth behind your sister's sudden death.\r\n\r\nG-Police is an arcade-style helicopter shooter set inside the colony domes on Callisto. You pilot a futuristic close-air-support gunship, and are tasked with engaging ground and air enemies as you uncover a sinister corporate plot. Your ship can hover and turn in a VTOL mode, fire weapons outfitted before each mission, and lock on to objects in the world to both track enemies and scan suspicious cargo. Missions require you to navigate through the skyscrapers and billboards of the various city districts, and complete a number of objectives updated through radio contact with headquarters.", 'youtube' => 'ZTEIh0sLlc0', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6840], 'genres' => [8, 13], 'publishers' => [21], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 534, 'game_title' => 'Joe Montana II: Sports Talk Football', 'release_date' => '1991-04-01', 'platform' => 18, 'overview' => "Joe's back - now with simultaneous non-stop play-by-play announcing. Control the action on the field and listen to the running commentary from the broadcast booth. It's a whole new game of sound and sight! The field zooms to a dazzling 6X close-up when the players cross the scrimmage line. You see every slamming interception, flying tackle and smash through the defensive wall! Up close and personal! Team up with another guy - you're the quarterback, he's the wide receiver. Call your strategy with over 50 plays in rain/snow, on grass/artificial field. Wide view shows all your receivers at once.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [1233], 'genres' => [11], 'publishers' => [15], 'alternates' => ['Joe Montana Football II'], 'uids' => nil, 'hashes' => nil }, { 'id' => 535, 'game_title' => 'Jordan vs Bird', 'release_date' => '1988-01-01', 'platform' => 18, 'overview' => 'Michael Jordan of the Chicago Bulls and Larry Bird of the Boston Celtics were the only two characters in the game, which allowed the player to participate in a one on one basketball game. Mini-games included a slam dunk contest (utilizing Jordan) and a three point contest (utilizing Bird).', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [2724], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 536, 'game_title' => 'Jungle Strike', 'release_date' => '1993-12-16', 'platform' => 18, 'overview' => "Some time after Operation Desert Strike, Ibn Kilbaba, son of Kilbaba S.R, threatens to annihilate America. After his father was killed, the people who were under his control, sent his son running off, along with his father's money and nuclear weapons program. Kilbaba, more ruthless than his father, longs for revenge of his father's death and decides to shed the blood of those who killed him, the Americans. Already armed, Kilbaba hires Carlos Ortega to help him set up his Nuclear Weapons program, deep in South America. Carlos Ortega, the world's most notorious druglord, also yearns to seek revenge. With his own private army, armed with the most hi-tech weapons, he's ready to fight America at all costs. \r\n\r\nBecause of this threat, you're hired again to battle these two characters, following their paths in the jungles of South America. Armed with the Commache, numerous other vehicles, and destructive weapons, you must take out their private army. Blow up the enemy with your hellfires, hydras, chain guns. Use the watercraft to launch mines at enemy ships. Pull off a drive-by on the enemy with guns on the side. Take out the evil duo and forever rid this threat.....in the jungle!", 'youtube' => 'fdJ8XtuJBuU', 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [3834], 'genres' => [8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 537, 'game_title' => 'Jurassic Park', 'release_date' => '1993-08-26', 'platform' => 18, 'overview' => 'Plunge into a heart-wrenching race for survival! On a tropical island, a violent hurricane rips through the dinosaur preserve, trapping the tourists and freeing the most terrifying animals in prehistory! Two bigger-than-life ways to play: Be a dinosaur! As a Raptor, rampage across the island battling other beasts and eluding the traps and weapons of your human enemies. As Grant, the paleontologist, arm yourself with tranquilizer guns, and sleeping-gas grenades. Dodge the slashing jaws of the Tyrannosaurus Rex and the paralyzing spit of the Dilophosaurs! 16 mammoth megs of nerve-shredding action!', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1233], 'genres' => [2], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 538, 'game_title' => 'King Salmon: The Big Catch', 'release_date' => '1993-03-21', 'platform' => 18, 'overview' => "King Salmon: The Big Catch is a fishing competition simulator: a player has to spend a day fishing for king salmon. Activities simulated include driving a boat to choose the best place to fish, choice of lures, line lengths, fishing depths, driving a boat to troll for salmon and, finally, pulling the caught fish out. The objective is to overcome some fictional fishermen, played by computer, in terms of the fish caught.\r\n\r\nGame also includes simple role-playing elements, as player's skill improve with time and experience and it's possible to catch bigger and better fish successfully.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [9344], 'genres' => [1, 11], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 539, 'game_title' => 'Klax', 'release_date' => '1990-09-06', 'platform' => 18, 'overview' => 'Klax features a conveyor belt at the top of the screen. It constantly rolls toward the playing area, delivering a steady supply of blocks. The player controls a small device which sits at the interface between the conveyor belt and the playing area, and can be moved left and right to catch the blocks and either deposit them in the playing area or push them back up the conveyor belt. The device can hold up to five blocks. A block which is not caught and placed in the playing area or pushed back up the belt is considered a drop. The blocks are solid colours, but there is also a flashing block which can be used as a wildcard on any colour.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [8654], 'genres' => [5], 'publishers' => [111], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 540, 'game_title' => 'Landstalker', 'release_date' => '1992-10-29', 'platform' => 18, 'overview' => "Eons ago, evil King Nole tyrannized the mythical island of Melcatle. With an insatiable greed for power and wealth, he crushed the people with heavy taxes while destroying their freedom. At last, in fury, the enslaved citizens stormed the palace. But King Nole was gone! And with him, the vast treasure, stolen from his subjects!\r\n\r\nNow Nigel, the Landstalker, journeys to this fantastic realm in search of the legendary fortune and power to reunite a divided kingdom!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1685], 'genres' => [1, 4], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 541, 'game_title' => 'Last Action Hero', 'release_date' => '1993-12-10', 'platform' => 18, 'overview' => "Last Action Hero blasts you out of the real world - onto the silver screen - and back again, in a non-stop action-adventure based on the epic fantasy feature starring Arnold Schwarzenegger. As movie hero Jack Slater, you'll team up with your biggest fan, Danny Madigan, who's got a magic movie ticket that's the ticket to serious trouble. Leaping between both the movie world and the real world with this magic ticket, you'll get into wild chases and deadly fights with the most dangerous criminals imaginable. Last Action Hero delivers all the excitement of the Schwarzenegger film with just one difference... you're the star! But this time, you must ultimately defeat the arch henchman Benedict to ensure a happy ending.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [1098], 'genres' => [1], 'publishers' => [77], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 542, 'game_title' => 'Lethal Enforcers II: Gunfighters', 'release_date' => '1994-01-01', 'platform' => 18, 'overview' => "You are the sheriff of a town set in the old Wild West. Using the control pad or Konami's own Justifier lightgun, you'll be taking out outlaws who are robbing banks and kidnapping innocents. You have the opportunity to upgrade and keep you gun, as long as you don't shoot the people you are trying to save.\r\n\r\nThe action is usually shown on a single screen with enemies \"popping out\" from various sections. If you do not shoot them in time they will either shoot or throw various weapons at you. You will lose energy if they hit you or you hit an innocent civilian.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [4765], 'genres' => [8], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 543, 'game_title' => 'Lightening Force: Quest for the Darkstar', 'release_date' => '1992-01-01', 'platform' => 18, 'overview' => "You must lead the battle against the evil Lohun Empire. Their computer system is poised to destroy your Galaxy Federation's defenses. Lead the attack on their heavily defended military planet. Knock out the planet's command center to pave the way for the invasion force. Take the fight underwater to destroy massive marine battlecruisers. Launch magnetically-charged photon blasts at alien bio-machines. Twist through the labyrinthine structure of the enemy's Bio-Base. There you'll meet your final objective, the destructive regenerating computer. Cut loose with the Thunder Sword, your most powerful energy beam, as you battle this ultimate weapon!", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [8609], 'genres' => [8], 'publishers' => [137], 'alternates' => ['Thunder Force IV'], 'uids' => nil, 'hashes' => nil }, { 'id' => 544, 'game_title' => 'The Lost Vikings', 'release_date' => '1992-01-01', 'platform' => 18, 'overview' => 'In the game, the three Vikings get kidnapped by Tomator, emperor of the alien Croutonian empire, for an inter-galactic zoo and become lost in various periods of time. The purpose of the game is to control the three characters (who all have separate abilities) in order to solve puzzles to escape and get back home.', 'youtube' => '', 'players' => 3, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [7729], 'genres' => [5], 'publishers' => [62], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 545, 'game_title' => 'Lotus II', 'release_date' => '1993-01-01', 'platform' => 18, 'overview' => "Licensed by the classic British car company, this game featured 2 modes of play - one has you racing against 19 computer rivals (with witty names such as Alain Phosphate and Crash-Hard Banger), and the other pits you against the clock. \r\n\r\nThere are 13 different types of races, ranging from Motorways to night-time to sections punctuated by roadworks, and some are lap-based with others being simple A-B. 2 players could play on a split screen mode.\r\n\r\nThe game's crowning glory, however, was the RECS editor, which allowed you to create courses of your own, with theoretically millions possible.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [5190], 'genres' => [7], 'publishers' => [2], 'alternates' => ['Lotus II: R.E.C.S'], 'uids' => nil, 'hashes' => nil }, { 'id' => 546, 'game_title' => 'Lotus Turbo Challenge', 'release_date' => '1992-01-01', 'platform' => 18, 'overview' => 'This sequel to Lotus Esprit Turbo Challenge is again a behind-the-car viewed racing game. It takes place in eight distinct circuits, adding surface and weather effects such as desert and snow. Later in the game, you must race through two-way motorways with oncoming traffic, (incorporating civilian cars and trucks), and face tough levels aided by speed and time boost pick-ups.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [5190], 'genres' => [7], 'publishers' => [2], 'alternates' => ['Lotus Turbo Challenge 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 547, 'game_title' => 'Vectorman 2', 'release_date' => '1996-11-15', 'platform' => 18, 'overview' => "After saving Earth from Warhead in the previous game, VectorMan's sludge barge is targeted and destroyed by a missile. VectorMan escapes, parachuting down to the planet to battle with the Earth's multitudinous enemy; mutant insects. Now it is up to VectorMan to fight through the mutant bugs and find the most fearsome source infestation; the evil Black Widow Queen.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1233], 'genres' => [1, 8, 15], 'publishers' => [15], 'alternates' => ['VectorMan 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 548, 'game_title' => 'Star Control', 'release_date' => '1991-01-01', 'platform' => 18, 'overview' => 'Star Control is a science-fiction wargame which pits the forces of the Alliance of Free Stars against those of the predatory Ur-Quan Hierarchy. The games are designed so that you can ease into play, familiarizing yourself with menus, options and player controls. The Alliance and Hierarchy each possess different types of warships. Each vessel has its own maneuvering and firing characteristics, plus a unique special power that you can employ when circumstances dictate.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [8978], 'genres' => [1, 6], 'publishers' => [139], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 549, 'game_title' => 'Super Battleship', 'release_date' => '1993-02-18', 'platform' => 18, 'overview' => 'Super Battleship is a Board game, developed by Synergistic Software and published by Mindscape Inc., which was released in 1993.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8399], 'genres' => [6], 'publishers' => [90], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 550, 'game_title' => 'The 3rd Birthday', 'release_date' => '2011-03-29', 'platform' => 13, 'overview' => "Hideous creatures descend on Manhattan. Ground reports from the squad tasked with containing the pandemonium refer to these life forms as the Twisted. An investigatory team known as the CTI is formed within the year.\r\nThe Overdive system emerges as a means of opposition, but only one viable candidate exists -- Aya Brea. A gift as she awakens from a lost past on this, the occasion of her third birth.", 'youtube' => 'kJtyPeekYR0', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3809], 'genres' => [1, 2], 'publishers' => [12], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 551, 'game_title' => 'Metal Gear Rising: Revengeance', 'release_date' => '2014-01-09', 'platform' => 1, 'overview' => "METAL GEAR RISING: REVENGEANCE takes the renowned METAL GEAR franchise into exciting new territory by focusing on delivering an all-new action experience unlike anything that has come before. Combining world-class development teams at Kojima Productions and PlatinumGames, METAL GEAR RISING: REVENGEANCE brings two of the world's most respected teams together with a common goal of providing players with a fresh synergetic experience that combines the best elements of pure action and epic storytelling, all within the expansive MG universe. The game introduces Raiden as the central character; a child soldier transformed into a half-man, half-machine cyborg ninja, equipped with a high-frequency katana blade and a soul fueled by revenge.\r\n\r\nIn the near future, cyborg technology has become commonplace throughout society. Three years have passed since the collapse of the Patriots system that had been secretly controlling the global power balance from the shadows. However, peace remains elusive. The dissemination of cybernetic technology has triggered instability and conflict as those who control the trade gain increasing power. Furthermore, large 'Private Military Companies', or PMC's, that had been supported and controlled by the Patriots have collapsed, spawning countless rogue entities with origins to larger criminal organizations. These renegade PMCs employing cyborg technology have become increasingly more disruptive shifting policy and power at will. As a member of the peace-keeping PMC 'Maverick Security', Raiden lives by the mantra of protecting and saving lives. But as the world plunges further into asymmetric warfare, the only path that leads him forward is rooted in resolving his past, and carving through anything that stands in his way.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1829], 'genres' => [1], 'publishers' => [140], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 552, 'game_title' => 'Ninja Gaiden Sigma', 'release_date' => '2007-07-03', 'platform' => 12, 'overview' => "As Ryu Hayabusa you are out to seek revenge after your clan is massacred by the Vigor Empire. Realistic battle actions and acrobatic ninja moves are at your finger-tips. You play with only your wits, your ninja skills, and your deadly sword. Slice down opponents in the Vigor Empire as you attempt to beat the Holy Emperor and reclaim the magic sword \"Ryuken\". Bringing the classic to the PlayStation 3, Ninja Gaiden Sigma is a more \"complete version\" of the Xbox Team Ninja title, with new moves, actions, and weapons for Hayabusa. Also added is a new playable character -- Racheal, one of the series' heroines, will be playable, and when using her, you'll get to experience the storyline from her perspective (with new cutscenes, attack moves and more.)", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [8563], 'genres' => [1, 2], 'publishers' => [24], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 553, 'game_title' => 'Hoshigami: Ruining Blue Earth', 'release_date' => '2001-12-20', 'platform' => 10, 'overview' => "Utilizing a host of new gameplay elements, Hoshigami: Ruining Blue Earth expands upon the formula made popular by the cult classic Final Fantasy Tactics. The continent of Mardias serves as the game's primary world, and is divided into three kingdoms: Nightweld, the Valaimian Empire and Gerauld. The story begins as Valaimian troops advance into Nightweld, a peace-loving kingdom. Lacking the military might to repel the invaders from multiple fronts, Fazz - a mercenary and the game's protagonist - is hired to defend the Tower of Wind. Needless to say, this is just the beginning of a dire and perilous journey for the unwitting Fazz.\r\n\r\nAs you and your party trek across the world map, you'll take part in various battles. Ready-for-Action Points (RAP) determine which, as well as the number of actions that can be performed by a particular character. The more actions performed (and thus, more RAPs expended) during a turn, the longer you'll have to wait for your next chance to act. When attacking, an interactive gauge appears that does damage based upon where the slider is stopped. Stopping it at the very end will result in greater damage dealt to the enemy. Wait too long however and the slider will return to the beginning.", 'youtube' => 'PZFinnczjyI', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5319], 'genres' => [4, 6], 'publishers' => [58], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 554, 'game_title' => 'Iron & Blood: Warriors of Ravenloft', 'release_date' => '1996-10-31', 'platform' => 10, 'overview' => "An axe-wielding medieval mother wants your heart on a stick... An armored killing machine wants his mace in your head... A feracious fiend wants his claws in your charred corpse... Either way, you're facing eternity on the edge of a rusty blade.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8465], 'genres' => [10], 'publishers' => [28], 'alternates' => ['Advanced Dungeons & Dragons: Iron & Blood: Warriors of Ravenloft'], 'uids' => nil, 'hashes' => nil }, { 'id' => 555, 'game_title' => 'Kartia: The Word of Fate', 'release_date' => '1998-07-31', 'platform' => 10, 'overview' => 'After numerous wars, peace was brought to the land by the power of Kartia... Yet, in this peaceful land, evil desires lived within the hearts of the people. This is the story of a boy and girl who courageously lived through this chaotic era...', 'youtube' => 'PYBwvgKehtA', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [771], 'genres' => [4, 6], 'publishers' => [141], 'alternates' => ['Legend of Kartia', 'Rebus'], 'uids' => nil, 'hashes' => nil }, { 'id' => 556, 'game_title' => "King's Field II", 'release_date' => '1996-10-31', 'platform' => 10, 'overview' => "King's Field II--the hour of destiny is at hand... Your kingdom is once again under attack by the ruthless minions of evil. This time they have possessed King Alfred himself! As the King's son, Prince Lyle, you must bring forth the tide of change that will effect the universe from now until the end of time. The fate of the world is in your hands!\r\n\r\nRe-enter the realm of King's Field for the most explosive debut on the PlayStation yet... ASCII Entertainment went all out to provide a fully non-linear three dimensional world that even blows away the original! The intense action and powerful storytelling will keep you riveted for months!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [3192], 'genres' => [2, 4], 'publishers' => [142], 'alternates' => ["King's Field III (Japan)"], 'uids' => nil, 'hashes' => nil }, { 'id' => 557, 'game_title' => 'Klonoa Beach Volleyball', 'release_date' => '2002-04-25', 'platform' => 10, 'overview' => "Invite your friends to join in the fun and play at THE volleyball party!\r\n\r\nGo head-to-head with Klonoa or one of his friends in this exciting seaside sport! Everyone is sure to hae a very good time. But watch out for those super attacks!\r\n\r\n-Play as Klonoa, Popka, Heart Moo, Lolo and even Joka too!\r\n-Lots of fun to pick up and play, on your own or with your friends.\r\n-Perfect your serve, toss and blocking skills", 'youtube' => 'ql3TnobfomA', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5804], 'genres' => [11], 'publishers' => [39], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 558, 'game_title' => 'Klonoa: Door to Phantomile', 'release_date' => '1997-03-10', 'platform' => 10, 'overview' => "Explore a magical world of mystery and adventure. Join Klonoa on a fantastic journey in the land of Phantomile, where the mysterious crash of a flying ship starts an epic quest through colorful worlds of thrills and danger.\r\n\r\nYou're never lost in this 3-D world. Klonoa's \"Guided 3-D\" construction gives players a vast 3-D world without the aimless and wandering feel of many other 3-D action games.\r\n\r\nBeautiful graphics and entertaining puzzles add a whole new level of fun & challenge.\r\n\r\nMultiple, forked paths add extra replay value - just remember that shortcuts aren't always what they seem!", 'youtube' => 'h8PsLF8vnzU', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5804], 'genres' => [15], 'publishers' => [39], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 559, 'game_title' => 'Legacy of Kain: Soul Reaver', 'release_date' => '1999-08-16', 'platform' => 10, 'overview' => "Soul Reaver is a third-person perspective action game with puzzle-solving and some platforming elements. The game follows Raziel on his quest to purge the land of vampires and take revenge on Kain and his brothers, leaders of the six clans. The player views the environments from behind Raziel's shoulder, moving him in any direction, climbing, attacking, jumping and using specific abilities. Raziel's can grip onto the edge of ledges and his torn wings allow him to glide gently downwards. He can also shift through the \"material\" world into the \"spectral\" realm at will, but must find specific locations in order to shift back. The two realms mirror one another, with distortions which give access to new areas and platforms. Existing in the material world drains Raziel's life energy at a constant rate.", 'youtube' => 'V9CB2RQ1Mec', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1963], 'genres' => [1], 'publishers' => [26], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 560, 'game_title' => 'Legend of Mana', 'release_date' => '2000-06-07', 'platform' => 10, 'overview' => "Create Your World\r\nIn ancient times, the world was saved from destruction by sealing locations and events within magical artifacts. Now, you have the chance to recreate this world as you desire by discovering artifacts, placing them, and exploring the mysteries inside.\r\n\r\n-Construct a unique world map and story by carefully placing artifacts.\r\n-Explore areas in any order, encountering nearly 70 different gameplay scenarios.\r\n-Battle enemies in real-time with special attacks and customizable controls.\r\n-Control every aspect of your new world: raise faithful net monsters, create powerful golems, forge mighty weapons, and refine magical instruments.\r\n-Adventure with a friend by having them import their Legend of Mana character from a MEMORY CARD, or take control of an NPC .", 'youtube' => 'voXZwYb3Xa8', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8096], 'genres' => [1, 4], 'publishers' => [11], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 561, 'game_title' => 'Lethal Enforcers I & II', 'release_date' => '1997-01-01', 'platform' => 10, 'overview' => "Plug in a light gun and dispense justice in LETHAL ENFORCERS I & II. In LETHAL ENFORCERS I, you must put a stop to an evil plot involving organized crime. You’ll blast mafia hit men and explore a modern urban landscape, which includes docks and a Chinatown district.\r\n\r\nIn LETHAL ENFORCERS II, you’re thrust into the Old West and must take on stagecoach thieves and cattle rustlers. Both games feature digitized graphics that make all of the bad guys look as real as possible. If you don’t happen to own a light gun, the standard controller is also supported. If you are looking for old-school shooting action, you should try LETHAL ENFORCERS I & II.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4765], 'genres' => [8], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 562, 'game_title' => 'Marvel Super Heroes', 'release_date' => '1997-01-01', 'platform' => 10, 'overview' => "There are ten playable characters. The heroes are Captain America, The Incredible Hulk, Iron Man, Psylocke, Spider-Man and Wolverine. The villains are Blackheart, Juggernaut, Magneto and Shuma-Gorath. Anita from the Darkstalkers series is a hidden character in the Japanese version. The bosses are Doctor Doom and Thanos. During the boss fight Thanos steals all the player's gems (except for mind) and uses them with new effects.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1436], 'genres' => [10], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 563, 'game_title' => 'Mass Destruction', 'release_date' => '1997-09-30', 'platform' => 10, 'overview' => "Played from an overhead 3D third-person perspective, the game is divided into four areas. Areas consist of a variety of mission objectives that must be completed; in addition to primary missions, some include secondary objectives. While primary objectives (24 in all) must be completed in order to claim victory for the overall mission, secondary objectives act as additional bonus points. There are also bonus and hidden objectives that award the player with bonus points. By completing hidden objectives, you'll be rewarded with new missions!\r\n\r\nMass Destruction requires one memory card block for saving game data and supports analog controls. So get in there and destroy anything that moves!", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6103], 'genres' => nil, 'publishers' => [83], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 564, 'game_title' => 'MDK', 'release_date' => '1998-11-30', 'platform' => 10, 'overview' => "MDK is a 3rd person action/shooter game in which the objective is to basically shoot everything that moves in six massive cities, each with their own sublevels. Because the world is being invaded by aliens, it is up to you and your sidekick Bones to stop the invasion and single handedly save Earth. In order to do so, you must make good use of your special suit, which allows you to do all kinds of things.\r\n\r\nThe super-suit comes equipped with many features you'll need to utilize in your journey, such as the sniper helmet. This allows you to zoom in on unsuspecting enemies and fire off shots with pinpoint accuracy. There is also a built in parachute (a ribbon-like device) that enables you to glide between different platforms as well as drop down on intruders.\r\n\r\nYour suit comes equipped with a chain gun that has an infinite supply of ammunition. You can also pick up special items, like a miniature nuclear bomb and powerful upgrades for your chaingun. In addition to running around and shooting, there are also special means of transportation including a surfboard-like jet and a bomber plane that is used to call in air strikes.", 'youtube' => '1wW4lQgnriQ', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7663], 'genres' => [1, 8], 'publishers' => [144], 'alternates' => ['M.D.K.', 'mdk'], 'uids' => nil, 'hashes' => nil }, { 'id' => 565, 'game_title' => 'Mega Man 8', 'release_date' => '1996-12-17', 'platform' => 10, 'overview' => "A gigantic space explosion sends two strange meteors crashing to Earth. The call goes out and Mega Man speeds to the site. There he sees his arch-rival, Dr. Wiley, fleeing the scene, clutching one of the mysterious metallic meteors. Now Mega Man must uncover the secret of the second meteor in a race to stay one step ahead of Dr. Wiley and his new deadly breed of super-powered robots.\r\n\r\n• Battle across 14 huge stages to face eight devious new enemies.\r\n• Multiple upgrades for Mega Man - customize to your specifications every game.\r\n• Intense Japanese anime intros, cut scenes and cinema screens.\r\n• Incredibly fluid animation and highly detailed backgrounds.", 'youtube' => 'yFGRDgQpkQk', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => ['Rockman 8: Metal Heroes'], 'uids' => nil, 'hashes' => nil }, { 'id' => 566, 'game_title' => 'Mega Man Legends', 'release_date' => '1998-08-31', 'platform' => 10, 'overview' => "THE BLUE BOMBER BLASTS INTO A WHOLE NEW DIMENSION\r\n\r\nMega Man blasts his way into the third dimension in an amazing new adventure. Mega Man Legends combines the best of classic Mega Man action with enormous bosses, a riveting storyline and all the depth of the hottest RPG.\r\n\r\nExplore vast 3-D worlds in your quest to find the treasure of all treasures, the Mother Lode. You'll love the new 3-D graphics, deadly weapons and non-stop action... unless of course, you're a boss.\r\n\r\n* Awesome Weapons!\r\n* Diabolical Bosses!\r\n* Legendary Gameplay!\r\n* Non-Stop 3-D Action!", 'youtube' => 'yX5x3zJEWog', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1, 2, 4], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 567, 'game_title' => 'Mega Man X4', 'release_date' => '1997-08-10', 'platform' => 10, 'overview' => "X-PLOSIVE GAMEPLAY.\r\nX-TREME GRAPHICS.\r\nMEGA MAN X4!\r\n\r\nVibrant Animation • Relentless Enemies\r\nUnsurpassed Graphics • Hidden Secrets\r\nMega Man X4 bombards the PlayStation game console and never lets up!\r\n\r\nBattle armies of Maverick Reploid Robots while mastering all-new strategic moves like the Air Hover and Zero's Saber Tactic system. Discover a myriad of power-ups, secret rooms, extra weapons and invincible vehicles to take on 8 all new X-Hunter Bosses. And for the first time, play as Mega Man X or battle with his mighty partner Zero in 2 separate adventures. Mega Man X4 - now you can be a hero, or a Zero!\r\n\r\n* Now, play as Mega Man X or Zero!\r\n* New X-Hunter levels with vivid color, brilliant detail, intricate passages, secret rooms and hard-to-reach items\r\n* Invincible vehicles like the Land Chaser superbike and other robot ride armors", 'youtube' => 'https://www.youtube.com/watch?v=F2JF-jVkLJ0', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => ['Rockman X4', 'Megaman X4'], 'uids' => nil, 'hashes' => nil }, { 'id' => 568, 'game_title' => 'Mega Man Battle & Chase', 'release_date' => '1998-11-30', 'platform' => 10, 'overview' => "It's robot mayhem at the Battle & Chase tournament! Dr. Wily is trying to take over the tournament with his army of Robot Masters, and now Mega Man has to enter to try and save the races! Choose your racer and head out on the tracks, and if you win, you'll get to steal parts off your opponent's cars, and eventually, you'll race against the mad Dr. Wily himself!", 'youtube' => '1v3avhAov18', 'players' => 2, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => ['RockMan: Battle & Chase'], 'uids' => nil, 'hashes' => nil }, { 'id' => 569, 'game_title' => 'MLB 2000', 'release_date' => '1999-02-28', 'platform' => 10, 'overview' => 'This game is basically an update to MLB 99 with a few new features. The game contains depictions of the real teams, stadiums, stats, and players that reflect their real life counterparts. The modes returning from the previous game include quick play, season, playoffs, spring training, and home run derby. One of the new modes is general manager mode. In this mode, players can draft, create, trade, call up, waive, release, and sign players. Another new mode is the manager mode. In this mode, players can check out scouting reports during the game, warm up relievers in the bullpen, and try to get their team to the World Series and hopefully win it.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7986], 'genres' => [11], 'publishers' => [21], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 570, 'game_title' => 'Monkey Magic', 'release_date' => '1997-11-27', 'platform' => 10, 'overview' => "Based on the cartoon series, this 2D side-scrolling action game (with 3D elements) has you seeking out Master Subodye to learn the four magic spells: fire, freeze, shrink and strength. Use these powers in over 30 worlds (five levels featuring 28 scenes and 16 opponents) to gain items like the Power Rod in order to survive the game. Then travel the world to gain other magical items and defend your monkey friends from, well, everybody.\r\n\r\nWith a playful spin on one of the great Asian folk tales, Sunsoft's Monkey Magic is filled with martial arts moves, environments and exotic, Eastern melodies. Can you set a world right when it doesn't want to be corrected? Are you \"monkey\" enough to survive the attacks of gods and monsters? You bet your prehensile tail you are!", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [865], 'genres' => [1], 'publishers' => [75], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 571, 'game_title' => 'Monsterseed', 'release_date' => '1999-03-31', 'platform' => 10, 'overview' => "Monster Seed obviously takes influence from the popular animal raising/fighting genre; specifically games like Pokémon and Monster Rancher. Of course, it does do a few things differently. One major difference is the fantasy setting. No ranches or medical settings here, no sir. Another key difference is in the overall presentation; Monster Seed's gameplay and interface are a lot more simple than most other breeding games.\r\n\r\nSimilar to mother games in the genre, there's a brief tutorial of sorts, and then you're off to gather your own creatures, earning better seeds and other breeding components as you go. Just be careful with your critters, because if they die in battle, they're gone for good. Granted you can always breed more, but it can certainly set you back if your creature hatches at level five, but you lost a level twelve.", 'youtube' => 'VYpblBSbt-c', 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6097], 'genres' => nil, 'publishers' => [75], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 572, 'game_title' => 'NASCAR 99', 'release_date' => '1996-09-30', 'platform' => 10, 'overview' => 'NASCAR 99, the arcade-style racing game from EA and Stormfront Studios. In addition to 2-player simultaneous racing the game featured 37 officially licensed cars and 17 tracks, as well as the voices of Bob Jenkins and Benny Parsons commentary. Using the Andretti Racing engine, NASCAR 99 was EAs first entry into NASCAR racing for the Nintendo 64 and and Playstation.', 'youtube' => 'Q3eRDPh_Mso', 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8219], 'genres' => [7], 'publishers' => [2], 'alternates' => ['NASCAR 99: Legacy'], 'uids' => nil, 'hashes' => nil }, { 'id' => 573, 'game_title' => 'NASCAR Racing', 'release_date' => '1996-09-30', 'platform' => 10, 'overview' => "The game presents three different game modes: Arcade Race, Simulation Race, and Simulation Testing. While the Arcade Race mode let's the player jump right into the fray after choosing their difficulty level (either rookie,veteran, or ace), the Simulation Race mode features a lot more customization options for the player to take into consideration.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6417], 'genres' => [7], 'publishers' => [145], 'alternates' => ['NASCAR Racing Season 96'], 'uids' => nil, 'hashes' => nil }, { 'id' => 574, 'game_title' => 'NBA Basketball 2000', 'release_date' => '1999-10-31', 'platform' => 10, 'overview' => "Updated with stats, rosters and player ratings for the 1999-2000 season, NBA Basketball 2000 features every player from all 29 NBA teams, plus two all-star and rookie teams. You can play an entire NBA season or skip ahead to the playoffs. If you're not ready for team ball, you can go one-on-one with your favorite pros on an outdoor court. Real Fox Sports announcers including former Atlanta Hawks point guard Doc Rivers, call the action.\r\n\r\nUsing one or two Multi Tap adapters, up to eight players can join in a single game of NBA Basketball 2000. Along with the standard head-to-head game, you can play on the same team against the computer with up to five players, each controlling a different hoopster. Or you can play on rival teams with each gamer controlling a different basketball player.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6942], 'genres' => [11], 'publishers' => [132], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 575, 'game_title' => 'NBA In The Zone 2', 'release_date' => '1996-11-30', 'platform' => 10, 'overview' => "Get ready to run the floors with NBA In the Zone 2 from Konami. After last years title, Konami has stepped up and added new features to ITZ2 to make it the best possible basketball game. Featuring different play modes such as exhibition and full season play, as well as containing full rosters for all the NBA teams and the ability to make substitutions, ITZ2 is loaded.\r\n\r\nAlso beefed up is the AI. Not only will it be harder to drive to the basket, gamers have a greater chance of getting fouled-out, with increased foul elements such as offensive fouls and basket-count. So step on the court and get ready for some solid b-ball action.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4765], 'genres' => [11], 'publishers' => [23], 'alternates' => ['NBA Power Dunkers 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 576, 'game_title' => 'NBA Live 98', 'release_date' => '1997-11-30', 'platform' => 10, 'overview' => 'NBA Live 98 is the 1998 installment of the NBA Live video games series. The cover features Tim Hardaway of the Miami Heat. The game was developed by EA Sports and released on November 11, 1997. The PlayStation version has network announcer Ernie Johnson and play-by-play announcer Verne Lundquist.', 'youtube' => '', 'players' => 8, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [2724], 'genres' => [11], 'publishers' => [82], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 577, 'game_title' => 'NBA Live 99', 'release_date' => '1998-10-31', 'platform' => 10, 'overview' => 'NBA Live 99 is the 1999 installment of the NBA Live video games series. The cover features Antoine Walker of the Boston Celtics. The game was developed by EA Sports and released on October 31, 1998 for the Windows and PlayStation, then in November 4, 1998 for the Nintendo 64. Don Poier is the play-by-play announcer. It was the first NBA Live game released for Nintendo 64. NBA Live 99 is followed by NBA Live 2000.', 'youtube' => '', 'players' => 8, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [2724], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 578, 'game_title' => 'NBA Live 2000', 'release_date' => '1999-10-28', 'platform' => 10, 'overview' => "The NBA Live series of basketball video games, published by EA Sports, is currently one of the leading National Basketball Association simulations on the market.\r\n\r\nStarting from NBA Live 2000, the series featured NBA Live Legend All-Stars Teams, that included some biggest names from five decades (50s to 90s). These teams could be used instantly, but to use the players as regular players (e.g. traded, played on regular NBA Teams) they needed to be unlocked. Along the series, some of the rosters were changed due to many reasons as Michael Jordan was on the 90's team through 2004.", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'E - Everyone', 'developers' => [2590], 'genres' => [11], 'publishers' => [82], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 579, 'game_title' => 'NBA Showtime: NBA on NBC', 'release_date' => '1999-10-31', 'platform' => 10, 'overview' => "The NBA like you've never seen it before! NBA Showtime: NBA on NBC brings you the top players from each team in a heart-pounding, pulse-racing above-the-rim match-up! You'll see the intensity on their faces and hear it in their voices, you'll feel the power of every pass and every shot! This is what the NBA is all about! Go for rebounds and 3-pointers in all 28 arenas around the league. Choose from over 130 real NBA players plus hidden characters!", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2886], 'genres' => [11], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 580, 'game_title' => 'The Next Tetris', 'release_date' => '1999-05-31', 'platform' => 10, 'overview' => "The Next Tetris is not only based on the original Tetris, which was created by Russian designer Alexey Pajitnov back in the mid- to late-1980s, it actually includes a copy of the original game, complete with enhanced graphics and sound. As most people know, Tetris is a game in which you maneuver falling blocks of seven different shapes into unbroken horizontal lines. When a line is created, the blocks in that line (or lines) disappear from the screen. Your job is to keep the pile of blocks from reaching the top of the playfield.\r\n\r\nThe Next Tetris mode of play introduces several new elements to the Tetris universe. The block-maneuvering action remains, but special multi-colored puzzle pieces that can separate and fall when they land enter the mix. Also, blocks above cleared lines will fall to spaces below, possibly setting up a chain reaction, which in this game is called a Cascade.", 'youtube' => 'pAkykYIYVpk', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1229], 'genres' => [5], 'publishers' => [30], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 581, 'game_title' => 'NFL Blitz 2000', 'release_date' => '1999-07-31', 'platform' => 3, 'overview' => "It's back and it's better than ever! NFL Blitz 2000 adds 4-player support, new offensive and defensive plays, realistic weather conditions, new stadiums and a Tournament mode! Customize offensive and defensive plays to your liking. Call audibles at the line of scrimmage. You've got control now! Passing made easy with new \"Blitz Passing\" for one-touch long bombs! \"ON-FIRE\" mode gives super power performance to your players! With non-stop action and a \"pick-it-up-and-play\" learning curve, NFL BLITZ 2000 is THE game for every football fan!", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5507], 'genres' => [11], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 582, 'game_title' => 'NFL Blitz 2001', 'release_date' => '2000-09-14', 'platform' => 10, 'overview' => "Who needs rules? This version of the offensively minded NFL BLITZ is even more fast-paced, action-driven, and penalty-free than its ancestors. Using an amazingly intuitive controller configuration, BLITZ keeps it as simple as possible. It's all about excitement, as you choose between 27 effective offensive plays and nine defensive sets for your NFL franchise. The teams are all here, but reality has flown out the window, as you rip off helmets, throw punches, and dive at kickers. New features include individual stats based on NFL performance, new player animations, updated stadiums, multiplayer options in Season mode, better AI, new rants from the BLITZ announcer, and a cool new soundtrack. The highlight of the additions, however, has to be the Party Games mode, which allows up to four players to compete in crazy football challenges. In \"1st and Goal Frenzy,\" you have four downs to score on your opponent; \"Goal Line Stand\" reverses the scenario and has you defending for four downs; and \"Quarterback Challenge\" has you passing at specific targets. Oh, and there's one more thing new cheerleaders.", 'youtube' => 'ivCDDvPt09c', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5512], 'genres' => [11], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 583, 'game_title' => 'NFL GameDay 99', 'release_date' => '1998-07-31', 'platform' => 10, 'overview' => "NFL GameDay 99[edit]\r\nNFL GameDay 99 was the fourth game in the NFL GameDay series. It was released July 31, 1998 on the PlayStation, and August 31, 1998 on the PC, both by 989 Sports. On the cover is Terrell Davis.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => nil, 'genres' => [11], 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 584, 'game_title' => "NFL GameDay '97", 'release_date' => '1996-11-30', 'platform' => 10, 'overview' => "Sony's football franchise carries on with another intense NFL match-up. In addition to all the features you expect from this series, GameDay '97 also includes new options like season-ending injuries, a full-fledged draft, more statistics, and the ability to create players. You'll also get expanded camera control, allowing you to place the camera at any angle. Every NFL team (over 1,500 players) and all stadiums are also included, letting you put your favorite team on the filed for some intense NFL action. But where the game really shines is in the gameplay. The control is deadly accurate, meaning diving catches are a distinct possibility. Making one-handed grabs, diving into the end zone, and even running out of bounds and slamming into the coach are also possible. And with a multitap seven of your friends can get in on the action.", 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7697], 'genres' => [11], 'publishers' => [520], 'alternates' => ['NFL Game Day 97'], 'uids' => nil, 'hashes' => nil }, { 'id' => 585, 'game_title' => 'NFL GameDay 98', 'release_date' => '1997-07-31', 'platform' => 10, 'overview' => "NFL GAMEDAY '98 is loaded with features like Preseason, Season, and Training Camp modes. You can also choose to play as a skill player, like wide receiver or fullback. And when you consider that you also get a play editor, a create-a-player feature, over 100 touchdown dances, and accurate player attributes, you'll realize why the GAMEDAY series is one of the best around. You can also take on your friends (up to eight with the multitap) in the Versus mode.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7986], 'genres' => [11], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 586, 'game_title' => 'NFL GameDay 2005', 'release_date' => '2004-08-01', 'platform' => 10, 'overview' => 'NFL GameDay 2005 was the tenth and final game in the NFL GameDay series, and unlike the last few GameDay video games, it was only available on the PlayStation console, and not on the PlayStation 2. It was released on August 1, 2004. On the cover is Derrick Brooks.', 'youtube' => 'Z8Scoq4XILc', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [135], 'genres' => [11], 'publishers' => [879], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 587, 'game_title' => 'No One Can Stop Mr. Domino', 'release_date' => '1998-10-31', 'platform' => 10, 'overview' => "No One Can Stop Mr. Domino is a puzzle game which sees you controlling the titular Mr. Domino (or one of his friends, if you prefer) as he zips around levels which can be best described as a racetrack. As the title suggests, you can't actually stop Mr. Domino - however, you can guide him around the track, speed him up and slow him down. He'll need to dodge obstacles as he aims to activate \"tricks\" which are placed around the board.", 'youtube' => 'xVnNQJOqJJI', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [651], 'genres' => [5], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 588, 'game_title' => 'Omega Boost', 'release_date' => '1999-04-22', 'platform' => 10, 'overview' => "Co-Existence between man and machine is no longer an option. The fate of humankind is hanging by a fiber... time is running out.\r\n\r\n-Pilot Omega Boost in a high-intensity action shooter across 19 diverse zones.\r\n-Multiple mission objectives, lethal ground and air assaults and deadly cyber-drogues.\r\n-Free-float in dizzying 360o combat.\r\n-Scan for targets, fire Vulcan guns and bag those bogeys with laser lock-on in the ultimate space dogfights!\r\n-Customize and upgrade equipment and weaponry with every win.\r\n-Review intense battles with the Replay Mode.", 'youtube' => '5-g-83_emKE', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6739], 'genres' => [1, 8], 'publishers' => [21], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 589, 'game_title' => 'Pandemonium!', 'release_date' => '1996-10-31', 'platform' => 10, 'overview' => "In the land of Lyr, there was a young sorceress called Nikki, a court jester called Fargus, and Fargus' stick-puppet Sid. They had gone to Lancelot Castle to attend a \"Wizards in Training\" seminar. Nikki, a talented acrobat with swift reflexes, had become irritated with her dull carnival life on the high-wire. After forgetting to feed the lions, and the trainer almost having his arm chewed off, she decided it was time to run away and become a wizard! Fargus and Sid had been spending their lives together traveling from fair to festival entertaining and embarrassing people here and there. Their act, however, was as old as the hills and usually turned into a bombardment of fruits and eggs. They, too, were a little tired of same old routine and had heard about the Wizards seminar.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8978], 'genres' => [15], 'publishers' => [27], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 590, 'game_title' => 'Parasite Eve', 'release_date' => '1998-09-09', 'platform' => 10, 'overview' => "THE CINEMATIC RPG\r\n\r\nOne of them is a police officer. The other is possessed by an ancient evil threatening all life on Earth. The horrifying bond between them will continue until something dies.\r\nA chilling adventure that could only come from the creators of Final Fantasy VII\r\nAn epic sci-fi tale told through stunning 3D rendered sequences\r\nBattle mutant monsters in real-time polygon combat\r\nCustomize weapons, armor, and character abilities", 'youtube' => 'BzXUUNpA9jw', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [8096], 'genres' => [4, 18], 'publishers' => [136], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 591, 'game_title' => 'Revelations: Persona', 'release_date' => '1997-10-25', 'platform' => 10, 'overview' => "In the near future, mankind has conquered dimensional travel but the door we have opened swings both ways. The peaceful city you have grown up in has become a haven for dark creatures from another world-Demons! Now it's up to you and your friends to harness the hidden power within you by entering the fantasy game known as Persona.\r\n\r\nYou awaken with incredible abilities that you will need to defeat the scores of Demon invaders and cleanse the land of their forces. Converse with them before doing battle to determine your best course of action. Fight them or enlist their aid in your mission. Either way, you are set for the fantasy adventure of a lifetime!", 'youtube' => 'fgi3V-7Vlow', 'players' => 1, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [771], 'genres' => [4], 'publishers' => [141], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 592, 'game_title' => 'Persona 2: Eternal Punishment', 'release_date' => '2000-12-22', 'platform' => 10, 'overview' => 'Welcome back to the twisted world of Persona, where nightmares become reality and reality becomes a nightmare... Over 50 hours of dark twisted gameplay, plus stunning anime cinematics that absorb you into the intriguing world of Persona! Enlist the help of the nightmarish denizens of Persona through the use of the unique "Contact System!" Unleash total devastation by combining over 80 Persona to defeat the minions of evil. Change the fate of your characters by employing the revolutionary "Rumor System."', 'youtube' => 'meQmQ7KxPlo', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [767], 'genres' => [4], 'publishers' => [58], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 593, 'game_title' => 'PGA Tour 97', 'release_date' => '1996-09-30', 'platform' => 10, 'overview' => "Players can choose to play as one of fourteen professional golfers such as Fuzzy Zoeller and Jim Gallagher Jr. or choose to create their own golfer by giving them a name and choosing what their golfer looks like from the few portraits that are available.\r\n\r\nPlayers are then able to select what type of game mode they want to play. Game modes include letting the player practice a round of golf, compete in a tournament, have a shoot-out, or compete in a Skins game.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2724], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 594, 'game_title' => 'Point Blank 2', 'release_date' => '1999-04-30', 'platform' => 10, 'overview' => "Point Blank 2 is the sequel to the now classic arcade game Point Blank, which was converted to the PlayStation in 1998. Using the Namco built GunCon (an arcade-like light gun), it offers 70 new shooting galleries, different party modes and a new single-player game.\r\n\r\nIf you're playing single-player, you have a few options from which to choose. The arcade mode is simply 16 rounds (of either beginner, advanced or insane difficulty) selected randomly from the 70 different shooting galleries. You'll get to shave sheep by shooting off their wool, test your accuracy in one-shot, one-hit bouts and save Dr. Don and Dr. Dan from wacky situations. There is also an endurance mode in which you climb a tall tower to see how far you can get in three tries.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5804], 'genres' => [8], 'publishers' => [39], 'alternates' => ['GunBarl'], 'uids' => nil, 'hashes' => nil }, { 'id' => 595, 'game_title' => 'Pong: The Next Level', 'release_date' => '1999-11-01', 'platform' => 10, 'overview' => "The classic videogame PONG is getting a 32-bit update. Players control a long, flat rectangular rod and maneuver it up and down the screen to defend their goal. The opponent is trying to direct the ball past you and into your goal the player who reaches the level's preset point total first wins the match. There are six zones filled with all kinds of PONG challenges, each with three distinct and increasingly difficult variations on that level. Most one-on-one games also include power-ups that you can collect, which will benefit you in some fashion against your opponent.", 'youtube' => '6JXHiWXvj4s', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8360], 'genres' => [1], 'publishers' => [146], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 596, 'game_title' => "PO'ed", 'release_date' => '1997-11-17', 'platform' => 10, 'overview' => "PO'ed is a first-person shooter with two simple objectives: escape the alien homeworld and kick lots of butt! There are 25 levels in all, each with a challenging array of horrific aliens to destroy, switch puzzles to solve, and platforming elements. Ox can either walk throughout the levels or utilize an ultra-powerful jetpack; use the latter in moderation as it's an important, yet limited tool.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [537], 'genres' => [1], 'publishers' => [113], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 597, 'game_title' => 'Powerslave', 'release_date' => '1997-02-28', 'platform' => 10, 'overview' => "An ancient evil force, neither of this time nor of this world, has remained buried since the Egyptians walked the earth. Now it has been exhumed. Of course, you, the hero, must find out what's going on in Egypt. Your helicopter crashes within this danger zone and you must survive on your own. Meet the Egyptian gods and follow their advice.\r\n\r\nExhumed for the Playstation and Saturn consoles was released as Powerslave in the United States.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [5017], 'genres' => [8], 'publishers' => [144], 'alternates' => ['Exhumed'], 'uids' => nil, 'hashes' => nil }, { 'id' => 598, 'game_title' => 'Professional Underground League of Pain', 'release_date' => '1997-02-28', 'platform' => 10, 'overview' => "A combination of ice hockey, basketball, and bare-knuckle fighting, Professional Underground League of Pain is a futuristic sports game with few rules and loads of violence. The object of the game is to throw a plasma ball into a round goal that is suspended above the middle of a hockey-sized arena. Before you or your computer opponent can make a basket, the ball must be charged. Each team's charger is located in their opponents end of the court. Be careful, though: If the ball is charged with your opponent's color and you make a basket, your opponent gets the points. The same rule applies for the opposing team. There are different zones on the court and depending on where a player is standing when he makes a shot, he will score one, two, or three points.\r\n\r\nThere are sixteen different teams to choose from, representing the countries of England, France, the United States, Germany, Japan, Mexico, Australia, and Russia. Each team has four players on the court at once. Most of the action consists of passing, shooting, and stealing the ball, punching and sliding into your opponents, and a whole lot of running.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1016], 'genres' => [1, 11], 'publishers' => [135], 'alternates' => ['Riot'], 'uids' => nil, 'hashes' => nil }, { 'id' => 599, 'game_title' => 'R4: Ridge Racer Type 4', 'release_date' => '1999-05-04', 'platform' => 10, 'overview' => "\"R4 has to be the best-looking PlayStation racer ever (yes, edging out even Gran Turismo).\" – Official PlayStation Magazine, December 1998\r\n\r\n* 8 tracks, 45 unique car models, and over 300 different car variations.\r\n* Sensational graphics and lighting effects give every race a cinematic feel.\r\n* Battle head-to-head in the 2-player, split screen VS mode.\r\n* Experience all the ups and downs of a full racing season with your team in the Grand Prix Mode.\r\n* New cars awarded based on your performance in every race.\r\n* Design original logos to customize your car.", 'youtube' => 'rTnTnrxws2c', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5804], 'genres' => [7], 'publishers' => [39], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 600, 'game_title' => "Tom Clancy's Rainbow Six: Rogue Spear", 'release_date' => '1999-08-31', 'platform' => 10, 'overview' => 'Following the collapse of the Soviet Union in 1991, the economic situation in Russia and the former Eastern Europe falls into chaos. Terrorism in the region is commonplace as people fight a seemingly endless stream of battles for supplies and other necessities. In this power vacuum though a dangerous a situation arises: the Russian mafia has begun buying up surplus military equipment with the assistance of current members of the Russian Army. During one such arms deal Rainbow forces raid the meeting grounds and recover weapons grade plutonium, tracing the fissile material to a nearby naval base.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7097], 'genres' => [8], 'publishers' => [147], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 601, 'game_title' => 'Rampage 2: Universal Tour', 'release_date' => '1999-03-01', 'platform' => 10, 'overview' => "Your 3 favorite human-munching, badly-behaved mutants have been captured! Unfortunately, for the humans inhabiting planet Earth, brand new mutants have been sent to rescue George, Lizzy and Ralph. You'll meet Ruby the Lobster, Boris the Rhino and Curtis the Rate as they destroy cities in North America, Asia and Europe! Get ready for destruction, mayhem, alien exterminations and the best buffet in town - the people of Earth!", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => nil, 'developers' => [819], 'genres' => [1], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 602, 'game_title' => 'RayCrisis: Series Termination', 'release_date' => '2000-10-25', 'platform' => 10, 'overview' => "An ambitious and unethical scientist, a secret experiment gone horribly awry, and an artificially intelligent supercomputer gone mad; all the necessary ingredients for the imminent extinction of mankind. You are humanity's last hope, a hotshot pilot given the unenviable task of flying an experimental fighter into the dark heart of the Con-Human Network. Seize the controls of three Wave Rider spacecraft, each equippped with the WR-01 primary weapon array, WR-02 secondary lock-on laser system, and WR-03 single-use weapon for emergency situations. RayCrisis: Series Termination is the final entry in Taito's acclaimed trilogy of shooters, and it bombards your CRT with an abundance of fourth-generation optical stimulation: multilevel scrolling, transparency and lighting effects, and enough polygons to overload your cerebral cortex. Dodge, weave, and blast through two play modes, disintegrating wave after wave of relentless bogeys, to achieve high scores and unlock hidden bonuses. Prepare your senses, reinforce your nerves, and limber your trigger finger - the final assault has begun!", 'youtube' => 'MO9EelOPEAk', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8449], 'genres' => [1, 8], 'publishers' => [122], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 603, 'game_title' => 'Re-Loaded: The Hardcore Sequel', 'release_date' => '1996-12-01', 'platform' => 10, 'overview' => "MAMMA, BOUNCA, BUTCH, and CAP'N HANDS are back and have been joined by SISTER MAQPIE and THE CONSUMER in the roll-call of shame, blasting their way through huge blood soaked worlds to inflict brutal revenge on C.H.E.B., who is hell bent on universal domination. PREPARE YOURSELF for an even heavier dose of maximum annihilation across 6 enormous 3D levels of terrifying morphing terrain which will leave you shell shocked and powered up with an array of awesome machinery and death sequences. Your bloody path is fraught with enemies to obliterate and riddles to solve in your quest to save the universe - If Loaded was twisted, then Re-Loaded is twisteder!!!", 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3620], 'genres' => [1], 'publishers' => [62], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 604, 'game_title' => 'Rhapsody: A Musical Adventure', 'release_date' => '2000-07-03', 'platform' => 10, 'overview' => "Follow the adventures of Cornet as she makes her way through Marl's Kingdom in search or her one true love. With the help of her trusty magical horn she enlists the help of many magical creatures along the way to battle the beautiful but evil Marjoly and her cohorts. Rhapsody is an epic RPG adventure that you'll never forget...\r\n\r\nIntuitive simulation-style battle system!\r\n\r\nUse magic spells such as the hilarious \"Pancake Attack\"!\r\n\r\nWonderfully illustrated anime characters and backgrounds!", 'youtube' => '5xD9ZxaMtbM', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6075], 'genres' => [4, 6], 'publishers' => [58], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 605, 'game_title' => 'Rugrats in Paris: The Movie', 'release_date' => '2000-10-29', 'platform' => 10, 'overview' => "Tommy Pickle's father has been sent to Europe for maintenance work at Euroreptarland. The Rugrats join him on his travel to Europe. There are 16 levels and hidden bonus level to play through.\r\n\r\nThe game consists of various mini-games that have to be completed in order to earn enough tickets to beat the game. Most tickets, however, can just be collected by running around the park and picking them up. Tickets can be used to buy prizes. There are ten mini games including whack-a-ninja, bumper cars and mini-golf.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [819], 'genres' => nil, 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 606, 'game_title' => 'SaGa Frontier 2', 'release_date' => '2000-01-31', 'platform' => 10, 'overview' => "Shape History or Be History\r\n\r\nSelect and control decisive moments during decades of royal conflict. Magic, revenge, and assassination will all play a part in determining who will obtain the country and the crown.\r\n\r\n-Create a unique history with Multi-Scenario System\r\n-Influence a variety of characters in an epic saga\r\n-Experience hand-painted watercolor artwork\r\n-Play Duel, Team, or Strategic battle modes\r\n-Choose from various, realistic sword maneuvers during combat\r\n-Form hundreds of possible combo attacks\r\n-Cast powerful and spectacular magic attacks", 'youtube' => '5kEr6kF2Hmc', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8096], 'genres' => [4], 'publishers' => [11], 'alternates' => ['SaGa Frontier II'], 'uids' => nil, 'hashes' => nil }, { 'id' => 607, 'game_title' => 'Skeleton Warriors', 'release_date' => '1996-01-01', 'platform' => 17, 'overview' => "As Prince Lightstar, players must defeat the Skeleton Warriors and Baron Dark in order to gain control of the Lightstar Crystal and bring balance back to the world. Gamers will explore the environments of 20 different levels as they face hundreds of enemies while riding on their skybike. The game features an original soundtrack composed by Tommy Tallarico.\r\n\r\nThe game is a 2D sidescrolling platform game with 3D pre-rendered graphics, with about 100 types of enemies for you to slay with the weapons you possess. You need to complete 21 levels filled with demonic evil creatures before you can fight the Baron Dark himself, with 3D rendered cutscenes inbetween some levels.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5926], 'genres' => nil, 'publishers' => [144], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 608, 'game_title' => 'Sled Storm', 'release_date' => '1999-07-31', 'platform' => 10, 'overview' => 'Sled Storm is a racing game featuring snowmobiles (referred to as sleds), stunts and fourteen snow-covered courses consisting of slippery slopes, inclement weather and treacherous cliffs. Up to four players can also participate at once, making this title one of the few racing games on the PlayStation (as of 1999) to feature split-screen action with more than two players. Sled Storm also offers two forms of racing for both multi-player and solo competition: Championship and Quick Race.', 'youtube' => 'U-R-zTBbZoY', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2724], 'genres' => [7], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 609, 'game_title' => 'SnoCross Championship Racing', 'release_date' => '2000-08-22', 'platform' => 10, 'overview' => "Sno-Cross Championship Racing provides players with the opportunity to race 12 snowmobiles by Yamaha. In the championship mode snowmobiles can be upgraded with money won by winning races and performing tricks. There are 10 racing circuits set in such locations as Nagano, Aspen, and Munich. A track editor is included as well so that users can modify current tracks or create their own.\r\n\r\nStrap on your goggles and helmet, choose your favorite Yamaha sled, and hit the courses. Gain experience day and night, sun rain or snow, racing on the icy flats of Vladivostok, the slopes of Aspen, and the tunnels of Nagano.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9186], 'genres' => [7], 'publishers' => [68], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 610, 'game_title' => 'Spider: The Video Game', 'release_date' => '1997-02-26', 'platform' => 10, 'overview' => "In Spider: The Video Game you control a spider that has been implanted with a neural transmitter port, cybernetic legs, and weapon accessories. You begin at a sector map which functions as a blueprint of the research laboratory which you must explore. In order to clear a level, you must collect a required number of microchips. You must also find exits in each area in order to advance to the next level.\r\n\r\nThe spider is always equipped with a Slasher leg and webbing, and he is capable of enhancing his fighting ability with weapons by collecting power-ups. The weapons include homing missiles, flame throwers, boomerangs, and electro-beams. You'll need these munitions to defend yourself against other spiders, cyber-rats, toxic green frogs, and other laboratory pests in this 3-D side-scrolling platform contest.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1292], 'genres' => [15], 'publishers' => [123], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 611, 'game_title' => 'Spider-Man', 'release_date' => '1991-10-17', 'platform' => 18, 'overview' => "The city of New York is certainly a great place to be, but not when there's the criminal element running about. Lucky for the NYPD, there's also the heroic Spider-Man on their side!\r\n\r\nBut now one of the biggest criminals in the city, Wilson Fisk, a.k.a. The Kingpin, has pulled of the ultimate plot! He announces to New York that a bomb has been planted somewhere in the city, and that it'll go off in 24 hours! What's worse, he lays the blame on Spider-Man, and now the webslinger is on his own, and on the run from the police. Spidey smells a rat, and he knows what he must do.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8604], 'genres' => [1], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 612, 'game_title' => 'Street Sk8er 2', 'release_date' => '2000-02-29', 'platform' => 10, 'overview' => "This is a skateboarding game very similar in gameplay to Tony Hawk's Pro Skater. You pick a skater and go through different skate parks, selecting either pro or amateur settings. You can also create your own skate park. Multiplayer competition is also provded, including 4 player serial play. Street Sk8er 2's sound track contains music from many well known bands such as Deftones, Ministry, and Static X.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [747], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 613, 'game_title' => 'Starwinder: The Ultimate Space Race', 'release_date' => '1996-10-31', 'platform' => 10, 'overview' => "In Starwinder: The Ultimate Space Race, you assume the role of Conner Rhodes, the first representative of Earth sent to compete in a galaxy-wide race. This isn't an ordinary race, however -- an unknown alien race built magnificent rails/tracks throughout the confines of space. Spanning thousands of miles in length, rails act in such a way that when pilots navigate toward one, it increases the speed of the ship.\r\n\r\nAs Conner, your overall objective is to bring home the ultimate reward -- the globe-like Starsphere. While your mission sounds fairly basic, it won't be easy; there are seven other pilots vying for the same prize. Residing in the far reaches of the Milky Way, competition includes a half man/half machine humanoid named Ko-Axe, the vengeful Tianna Stone, and an overconfident egomaniac that goes by the name of Dextor -- The Terrible. There are also drone pilots that fill in the rest of the playing field.\r\n\r\nBroken into quadrants, there are 44 different rails/tracks in which to race on; there are ten races per quadrant. While the bulk of the game is played against computer-controlled opposition, there are times when you'll race against the clock in a true test of speed and accuracy. Prove yourself worthy and you'll race against an elite group of pilots through Epsilon Indi -- the final railway. If you manage to win this final race, the Starsphere is as good as yours!", 'youtube' => 'peAD7IGCBdU', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5588], 'genres' => [7, 8], 'publishers' => [90], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 614, 'game_title' => 'Street Fighter Collection', 'release_date' => '1997-12-16', 'platform' => 10, 'overview' => "Street Fighter Collection is a 1997 fighting game compilation released for the PlayStation and Sega Saturn. It collects the original Super Street Fighter II and its follow-up Super Street Fighter II Turbo, along with an enhanced version of Street Fighter Alpha 2 titled Street Fighter Alpha 2 Gold exclusive to this compilation.\r\n\r\nThis compilation contains Super Street Fighter II and Super Street Fighter II Turbo (known in Japan as Super Street Fighter II X) in the first disc, with Street Fighter Alpha 2 Gold (Street Fighter Zero 2 Dash in Japan) in the second disc.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1436], 'genres' => [10], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 615, 'game_title' => 'Suikoden II', 'release_date' => '1999-08-31', 'platform' => 10, 'overview' => "Experience An Epic Tale of Warfare, Magic, Friendship And Betrayal\r\n\r\n-New tactical map battles add a whole level of strategy\r\n-Fantastic spells with stunning animation sequences and specialized attacks\r\n-Over 108 different characters can join your party and help you on your quest\r\n-Unlock hidden storylines using your memory card data from the original Suikoden\r\n-Build up your castle during the game to a thriving virtual community", 'youtube' => 'HibuSDMFvyg', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [4765], 'genres' => [4], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 616, 'game_title' => 'Super Puzzle Fighter II Turbo', 'release_date' => '1996-11-30', 'platform' => 10, 'overview' => "A Tetris-like puzzle game featuring popular characters from many Capcom games.\r\n\r\nColored gems fall from the top of the screen in pairs, but this time lining up those of the same color is not enough. To break the gems and punish your opponent with counter gems you have to place a crash gem of the same color next to the gems. If you make a block of gems of the same color they'll fuse, forming a power gem. Breaking a power gem sends more counter gems to your opponent than breaking the same amount of gems in some other configuration. But the ultimate attack is breaking power gems in chain.", 'youtube' => 'rnbnMsqBIsg', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [5], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 617, 'game_title' => 'Tactics Ogre: Let Us Cling Together', 'release_date' => '1998-01-01', 'platform' => 10, 'overview' => "After generations of war between the various ethnic groups, King Dogare brought peace to the land of Valeria. When the king dies Valeria is split into three different groups, each claiming the throne. You take the role of a young boy as he embarks on a quest to save the land from turmoil and assume the throne. You will have to journey throughout the land and recruit members for an army. Once recruited, the members will gain experience through the turn-based battles. \r\n\r\nUp to 10 party members can participate in any battle. Eventually, the characters can change classes and learn skills that are specific to each class. However, you will have to make sure your party is balanced or you will face certain doom. Will you be able to save the world from chaos in Tactics Ogre?", 'youtube' => 'ssJlXRqrtUs', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6909], 'genres' => [4, 6], 'publishers' => [58], 'alternates' => ['タクティクスオウガ LET US CLING TOGETHER', 'Tactics Ogre: Let Us Cling Together'], 'uids' => nil, 'hashes' => nil }, { 'id' => 618, 'game_title' => 'Time Crisis', 'release_date' => '1997-10-31', 'platform' => 10, 'overview' => 'Time Crisis is a rail shooter, originally released for the arcades, similar to Virtua Cop in gameplay style. The player moves automatically, using the light gun to eliminate appearing enemies, after which he can proceed to the next screen. The stages typically culminate in boss battles. The player can also press a button to make Richard dive for cover. However, using this feature too much might result in expiration of the time limit imposed on each screen.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5804], 'genres' => [8], 'publishers' => [39], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 619, 'game_title' => 'Tomb Raider II', 'release_date' => '1997-10-31', 'platform' => 10, 'overview' => "The story of Tomb Raider II surrounds the mythical Dagger of Xian, a weapon which was used by an Emperor of China to command his army. By plunging the weapon into its owner's heart, the weapon has the power to turn its bearer into a dragon. A flashback reveals that the last battle which was fought with the Dagger ended in defeat when the warrior monks of Tibet succeeded in removing the knife from the Emperor's heart. The Dagger was then returned to its resting place within the Great Wall.", 'youtube' => 'DdOs1Iz1hKA', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1827], 'genres' => [1, 2], 'publishers' => [26], 'alternates' => ['Tomb Raider 2'], 'uids' => [{ 'uid' => 'SLES-00719', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 620, 'game_title' => 'Uprising-X', 'release_date' => '1998-11-30', 'platform' => 10, 'overview' => "A war has been going on for nearly two hundred years between the cruel Imperium regime and the Rebel forces. The Rebels are beginning to turn the tides of the war to their advantage, and while the Imperium armies are by no means defeated, there is a great deal of hope in the Rebel camp.\r\n\r\nUnfortunately, the Imperium has introduced a new weapon of unspeakable power. When unleashed against a Rebel planet, the damage was absolute. This new \"planet-killing\" weapon will certainly mark the end of the Rebel forces if it continues to operate.\r\n\r\nUprising X, by The 3DO Company, is a blend of action and strategy for the PlayStation. Players take control of a tank-like vehicle known as \"The Wraith,\" which is the most powerful weapon available to the Rebel forces. The majority of the game is spent behind the controls of the Wraith, although some missions will require troop deployment and the construction of Rebel equipment. The game utilizes a first-person view from inside the Wraith or while building in Citadel mode.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2031], 'genres' => [1, 6], 'publishers' => [63], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 621, 'game_title' => 'Vandal Hearts', 'release_date' => '1997-06-01', 'platform' => 10, 'overview' => "You assume the role of Ash Lambert, a hero torn between saving his country and restoring honor to the disgraced Lambert dynasty. As he struggles with his inner demons and personal problems, he will meet various companions throughout his journey. They will help your character fight to overthrow the oppressive regime and ward off an ancient being that threatens the world.\r\n\r\nVandal-Hearts is a 3D turn-based strategy game. Unlike many games of the genre, the various battlefields have sloped surfaces that will either work to your advantage or against you. It will be up to you to accommodate your strategy and amount an appropriate offensive assault against your foes as well as set up defensive measures.", 'youtube' => 'd-e0XcKHPVg', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4765], 'genres' => [4, 6], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 622, 'game_title' => 'Warhammer: Shadow of the Horned Rat', 'release_date' => '1996-11-01', 'platform' => 10, 'overview' => "Warhammer: Shadow of the Horned Rat offers over 25 different troop types, 20 spells and nine characteristics for each regiment: movement, weapon skill, ballistic skill, strength, toughness, wounds, initiative, attack and leadership ability. In order to save campaign progress, players must have a memory card with at least one block free.\r\n\r\nBattles consist of two phases: deployment and real-time fighting. Deployment allows you to position your regiments within an area designated by white flags. This involves turning them to face certain enemies, issuing orders to attack, move (including setting waypoints and patrol loops) or simply hold ground.\r\n\r\nCombat involves charging the enemy, using magical spells (if available) or firing long-range weapons, such as arrows or catapults. Of course, line of sight and terrain will influence how successful your attacks are, and the emotion level (fear, hatred or frenzy) as well as the experience of your troops will also play a significant role. Each battlefield can also hold various magic items that may help in future battles.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3370], 'genres' => [6], 'publishers' => [149], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 623, 'game_title' => 'Warriors of Might and Magic', 'release_date' => '2001-02-07', 'platform' => 10, 'overview' => 'Warriors of Might and Magic is an action game with RPG elements set in the Might and Magic universe. The gameplay style is similar to that of Crusaders of Might and Magic. The player navigates Alleron through predominantly dungeon-like environments, fighting enemies in action-based combat, executing various melee moves (including blocking), and casting spells.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [77], 'genres' => [1], 'publishers' => [63], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 624, 'game_title' => "Wayne Gretzky's 3D Hockey '98", 'release_date' => '1997-12-26', 'platform' => 10, 'overview' => "Gameplay consists of two basic options: Arcade and Simulation. Although the graphics and earlobe vary little between the two, other changes have the effect of changing the chemistry and intensity of gameplay between the two options. The gamer has the ability to customize period length, fatigue (on/off), line changes, fighting (on/off), penalties (simulation only), rink size (arcade only), puck-streak (on/off), and camera angle.\r\n\r\nSimulation Mode:\r\nSimulation mode is designed to emulate the real game of hockey. Players may play five, four, or three to a side, depending on preference. Recognition of penalties, off-sides, and icing are all optional, but two-line pass is not considered. Period length can be selected between 5, 10, 15, and 20 minutes.\r\n\r\nArcade Mode:\r\nDuring the Arcade mode checking, hooking, and tripping are more violent. Fights occur with greater frequency, and penalties are disregarded entirely. Additionally, arcade mode sees the introduction of a \"power shot\", which a player may utilize to light the net on fire after a goal. Arcade mode tends to be more exciting.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7940], 'genres' => [11], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 625, 'game_title' => 'Wipeout XL', 'release_date' => '1996-09-30', 'platform' => 10, 'overview' => "Anti-gravity racing that’s light years ahead of the pack!\r\n\r\nThe original scorched the game world and became an instant classic. Fast-forward now to a brutal new generation of anti gravity racing. Loaded with faster, smoother graphics, more tracks, more crafts, and a range of nasty new weaponry. Wipeout XL will give you the rush of your life. \r\n\r\n-Up to 15 ships on the track as the same time\r\n-Secret racing features for accomplished players\r\n-New range of strategic and more explosive weapons\r\n-Multiple racing classes for a variety of player ability levels\r\n-Cool soundtrack by Future Sound of London, Chemical Brothers, Prodigy, Underworld, Fluke, and Photek", 'youtube' => 'mWo8LjUsego', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6840], 'genres' => [7], 'publishers' => [135], 'alternates' => ['Wipeout 2097'], 'uids' => nil, 'hashes' => nil }, { 'id' => 626, 'game_title' => 'WWF War Zone', 'release_date' => '1998-07-01', 'platform' => 10, 'overview' => "\"Rock the ring with the fiercest wrestling action ever seen!\" -GamePro\r\nThe top superstars in the World Wrestling Federation including Steve Austin, Shawn Michaels, The Undertaker, Kane, Triple H, and many more! Vince McMhaon and Jim Ross bring you the action from ringside. Training mode: Practice your moves before stepping into the ring!\r\n\r\n- 4 Player Action with Tag Team, Tornado and War Modes!\r\n- Specialized Matches Including Steel Cage Match\r\n- Signature and Finishing Moves Unique To Each Wrestler\r\n- Over 300 Motion Captured Maneuvers\r\n- Create and Save up to 30 Customized Wrestlers", 'youtube' => 'SPwp7JSKxWU', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [4065], 'genres' => [10, 11], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 627, 'game_title' => 'Xenogears', 'release_date' => '1998-10-20', 'platform' => 10, 'overview' => "Stand tall, and shake the heavens.\r\n\r\nA mysterious organization is turning the tides of a century-long war with ancient technology - giant combat robots. A failed attempt to steal one of these powerful mechanized weapons places it in the unwilling hands of Fei and his dubious allies. Now he is pursued by military governments, royal pirates, spies, the Emperor, and his own forgotten past.\r\n\r\n* Over 20 minutes of stunning hand-drawn animé tells this complex, futuristic tale.\r\n* Battle in giant robots or hand-to-hand using intuitive combat systems without menus\r\n* Explore detailed, fully-rotatable polygonal environments", 'youtube' => 'QTx8iG52Ruo', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8096], 'genres' => [4], 'publishers' => [11], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 628, 'game_title' => 'X-Men vs. Street Fighter', 'release_date' => '1998-06-30', 'platform' => 10, 'overview' => "X-Men vs. Street Fighter is a fighting game originally released as a coin-operated arcade game in 1996. It is Capcom's third fighting game to feature Marvel Comics characters and the first game to match them against their own, with characters from Marvel's X-Men franchise being matched against the cast from the Street Fighter series.\r\n\r\nIt was the first game to blend a tag team style of combat with the Street Fighter gameplay, as well as incorporating elements from Capcom's previous Marvel-themed fighting games, X-Men: Children of the Atom and Marvel Super Heroes. It was ported to the Sega Saturn in 1997 and PlayStation in 1998. However, the tag team feature was omitted from the PlayStation version due to memory limitations.", 'youtube' => 'NpZDoYifqLk', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1436], 'genres' => [10], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 629, 'game_title' => "John Madden Football '92", 'release_date' => '1991-01-01', 'platform' => 18, 'overview' => "This update of the John Madden football series offers several new features over its predecessor: instant replays, different weather conditions, player injuries and the ability to review and overturn pass interference calls.\r\n\r\nPlay modes include Pre-Season, Regular Season, Playoffs and Sudden Death. There are 28 teams plus one All-Madden team.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2724], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 630, 'game_title' => "John Madden Football '93", 'release_date' => '1992-01-01', 'platform' => 18, 'overview' => "Another update in the Madden football series. New this time are some graphics and animations, including an animated coin toss and some player moves. New gameplay features are no-huddle offense and a stop clock play.\r\n\r\nThere are 28 teams from the '92-'93 season, two All Madden teams and 8 Greatest Ever teams.\r\n\r\nGame modes are the usual pre-season, regular season, sudden death and playoffs. A special playoff mode for the 8 greatest teams is also available.\r\n\r\nThe Genesis version features John Madden's digitized commentary speech and a battery-backed RAM for saving playoff results and player stats", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [2724], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 631, 'game_title' => "Madden NFL '94", 'release_date' => '1994-02-18', 'platform' => 18, 'overview' => 'It features 80 teams -- 28 teams from the 1993 season, 38 Super Bowl teams from 1966-1991, 12 All Star franchise teams since 1950, and two "All-Madden" teams: one for the 1993 season and one from a 20-year time span. You can play these teams in a regular exhibition game or sudden death overtime game, or take the 1993 teams through an entire season. You can also enter the playoffs with the 1993 teams, the Super Bowl champions, or the All Star franchise teams. Unlike many other sports games, saving a season is done by password rather than by storing the data into a saved game.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2724], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 632, 'game_title' => 'Madden NFL 95', 'release_date' => '1994-09-05', 'platform' => 18, 'overview' => "John Madden's back in the 1995 version of Madden NFL.\r\n\r\nPlay exhibition, Super Bowl, playoffs or full season with any of the 1994 teams or all Madden teams.\r\n\r\nThis time around, you can select whether or not to include weather conditions, new player animations (high steppin', QB slides), a bigger field and over 100 injuries.\r\n\r\nAlso includes windowless passing, all new Madden-designed strategies and team match-up that shows how your players stack up to the other team in their position.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3834], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 633, 'game_title' => 'Marsupilami', 'release_date' => '1995-01-01', 'platform' => 18, 'overview' => "Marsupilami, a small furry marsupial with a tail with as many uses as a swiss army knife, must help his friend, Bonelli the elephant, across the world, returning him safely to his native home.Collecting Marsu's children along the way, you must solve puzzles, fight enemies and avoid traps, all with the aid of Marsu's incredible, ingenious tail!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [1, 15], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 634, 'game_title' => 'Math Blaster: Episode 1', 'release_date' => '1994-09-14', 'platform' => 18, 'overview' => "Oh no! The dreaded Trash Alien has captured Spot and littered the universe with garbage! Join our hero Blasternaut on a daring mission to rescue his robot pal. Blast your way through space junk, chase through dark and dangerous caverns, and fend off nasty alien creatures. Spot's fate is in your hands - good luck!", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9585], 'genres' => nil, 'publishers' => [150], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 635, 'game_title' => 'Mazin Saga: Mutant Fighter', 'release_date' => '1993-01-01', 'platform' => 18, 'overview' => 'The story takes place in 1999 where a Bio-Beast by the name of Godkaiser Hell has reigned supreme over Earth, after a nuclear and biological holocaust has disfigured most of the population and formed an army called the Steelmask Force. The survivors have fled underground and are constantly attacked by the Bio-Beast horde until one day a scientist by the name of Dr. Kabuto creates a mech, the Mazinger-Z, that can be used against the monsters. This is where the player takes control of the games protagonist and pilots the suit in an attempt to reclaim the Earth.', 'youtube' => 'https://www.youtube.com/watch?v=qCfG4hxStzc', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [376], 'genres' => [1], 'publishers' => [151], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 636, 'game_title' => "McDonald's Treasure Land Adventure", 'release_date' => '1993-09-23', 'platform' => 18, 'overview' => "McDonald's Treasure Land Adventure is a side-scrolling adventure starring Ronald McDonald.\r\n\r\nAfter finding a piece of a treasure map, the yellow clown travels through four different levels (Forest, Town, Sea and Moon). He's off to find and defeat the baddies who have the other pieces of the map.\r\n\r\nRonald can jump, shoot and use his scarf to grab onto hooks to jump to higher levels.\r\n\r\nJewels and flowers collected in each level can be used to purchase extra lives and power-ups in shops between levels.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9008], 'genres' => [15], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 637, 'game_title' => 'Mickey Mania: The Timeless Adventures of Mickey Mouse', 'release_date' => '1994-10-01', 'platform' => 18, 'overview' => 'The player must take on the role of Mickey and progress through each level, defeating enemies along the way and solving the occasional puzzle. Most enemies can be defeated either by stomping on them or tossing marbles at them. Frequently, the player must jump from platform to platform in order to advance, even occasionally within the constrains of a time limit (such as when escaping from a collapsing tower).', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8995], 'genres' => [2], 'publishers' => [77], 'alternates' => ['Mickey Mania Timeless Adventures of Mickey Mouse'], 'uids' => nil, 'hashes' => nil }, { 'id' => 638, 'game_title' => 'Halo: Reach', 'release_date' => '2010-09-14', 'platform' => 15, 'overview' => '“Halo: Reach†tells the tragic and heroic story of Noble Team, a group of Spartans, who through great sacrifice and courage saved countless lives in the face of impossible odds. The planet Reach is humanity’s last line of defense between the encroaching Covenant and their ultimate goal, the destruction of Earth. If it falls, humanity will be perched on the brink of destruction.', 'youtube' => nil, 'players' => 4, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [1389], 'genres' => [8], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 639, 'game_title' => "Dante's Inferno", 'release_date' => '2010-02-09', 'platform' => 15, 'overview' => "Dante's Inferno is an epic single player, third-person action adventure game inspired by \"Inferno\", part one of Dante Alighieri's classic Italian poem, \"The Divine Comedy.\" Featuring nonstop action rendered at 60 frames-per-second, signature and upgradable weapons, attack combos and mana-fueled spells and the choice of punishing or absolving the souls of defeated enemies, it is a classic Medieval tale of the eternal conflict with sin and the resulting horrors of hell, adapted for a new generation and a new medium.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9428], 'genres' => [1, 2], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 640, 'game_title' => 'F.E.A.R. 2: Project Origin', 'release_date' => '2009-02-10', 'platform' => 1, 'overview' => "The sequel to F.E.A.R. continues the supernatural suspense story of the supernatural being, Alma, whose rage against those who wronged her causes an escalating paranormal crisis that threatens to devour and replace reality with her own. Instead of playing as the Point Man, the game's protagonist is Michael Becket, a Delta Force operator whose squad is sent in to take Genevieve Aristide into protective custody approximately thirty minutes before the ending of F.E.A.R.", 'youtube' => 'bdLv5VGPzRY', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [5679], 'genres' => [8], 'publishers' => [152], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 641, 'game_title' => 'Bayonetta', 'release_date' => '2010-01-05', 'platform' => 12, 'overview' => "Bayonetta is a stylish and cinematic action game, directed by Hideki Kamiya.\r\n\r\nA witch with powers beyond the comprehension of mere mortals, Bayonetta faces-off against countless angelic enemies, many reaching epic proportions, in a game of 100% pure, unadulterated all-out action. Outlandish finishing moves are performed with balletic grace as Bayonetta flows from one fight to another. With magnificent over-the-top action taking place in stages that are a veritable theme park of exciting attractions, Bayonetta pushes the limits of the action genre, bringing to life its fast-paced, dynamic climax combat.", 'youtube' => 'qD62SZwhP1M', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1829, 7549], 'genres' => [1], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 642, 'game_title' => 'Mortal Kombat II', 'release_date' => '1994-12-05', 'platform' => 18, 'overview' => "Following his failure to defeat Liu Kang in the first Mortal Kombat game, the evil sorcerer Shang Tsung begs his master, Shao Kahn, to spare his life. He tells Shao Kahn that the invitation for Mortal Kombat cannot be turned down, and if they hold it in Outworld, the Earthrealm warriors must attend. Kahn agrees to this plan, and even restores Tsung's youth. He then extends the invitation to Raiden, who gathers his warriors and takes them into Outworld. The new tournament is much more dangerous, as Shao Kahn has the home field advantage, and an Outworld victory will allow him to subdue Earthrealm.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [5507], 'genres' => [10], 'publishers' => [41], 'alternates' => ['Mortal Kombat 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 643, 'game_title' => 'Team Fortress 2', 'release_date' => '2007-10-10', 'platform' => 1, 'overview' => 'Team Fortress 2 is the sequel to the game that put class-based, multiplayer team warfare on the map.This year’s most anticipated online action game, TF2 delivers new gametypes, a signature art style powered by Valve’s next generation animation technology, persistent player statistics, and more.', 'youtube' => 'h_c3iQImXZg', 'players' => 6, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [9289], 'genres' => [8], 'publishers' => [13], 'alternates' => ['TF2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 644, 'game_title' => 'Dungeons & Dragons: Dragonshard', 'release_date' => '2005-10-02', 'platform' => 1, 'overview' => "Dungeons & Dragons: Dragonshard is a real-time strategy role-playing video game, developed for Microsoft Windows by Liquid Entertainment, and published by Atari in 2005. It takes place in Eberron, one of the official Dungeons & Dragons campaign settings. The game combines elements of traditional real-time strategy gameplay with role-playing elements such as hero units, and questing. Dragonshard includes two single-player campaigns, single-player skirmish maps, and multiplayer support. The single-player campaign follows the struggles of three competing factions to gain control of a magical artifact known as the Heart of Siberys.\r\n\r\nAlthough Dragonshard was billed by Atari as \"the first Dungeons & Dragons real-time strategy experience,\"[2] Stronghold (1993) precedes it by over a decade.[3]", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => nil, 'genres' => nil, 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 645, 'game_title' => 'F.E.A.R. Extraction Point', 'release_date' => '2006-10-24', 'platform' => 1, 'overview' => "This expansion owes its name to the game's ultimate goal for the player, to reach the extraction point and leave the city where the adventure takes place.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [5678], 'genres' => [8], 'publishers' => [153], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 646, 'game_title' => 'Call of Duty: World at War', 'release_date' => '2008-11-11', 'platform' => 1, 'overview' => 'Call of Duty: World at War throws out the rulebook of war to transform WWII combat through a new enemy, new tactics and an uncensored experience of the climatic battles that gripped a generation. As U.S. Marines and Russian soldiers, players will employ new features like cooperative gameplay, and weapons such as the flamethrower in the most chaotic and cinematically intense experience to date.', 'youtube' => 'Y_Ip_SaJqpg', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9025], 'genres' => [8], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 647, 'game_title' => 'Half-Life', 'release_date' => '1998-11-19', 'platform' => 1, 'overview' => 'Half-Life, a First Person Shooter released by Valve & Sierra in 1998, tells the story of a recently graduated theoretical physicist, named Dr. Gordon Freeman, who is working on experiments in relation to teleportation technology with other scientists in the Black Mesa Research Facility. Unfortunately, an experiment goes disastrously wrong and aliens from another dimension, also known as Xen, subsequently enter the facility through a dimensional seam! As Freeman tries to make his way out of the ruined facility, he soon realizes that he is caught between two sides: the hostile aliens and a U.S. Marine Corps special operations unit dispatched to cover up the incident by eliminating all organisms in the facility, including every single survivor. Explore the facility as Gordon Freeman, escape the complex alive and discover both the mysterious Xens as well as their portals to other dimensions!', 'youtube' => 'qobDF0w5qJc', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9289], 'genres' => [8], 'publishers' => [32], 'alternates' => ['Half Life'], 'uids' => nil, 'hashes' => nil }, { 'id' => 648, 'game_title' => 'Call of Duty 4: Modern Warfare', 'release_date' => '2007-11-05', 'platform' => 1, 'overview' => "The game starts with Sergeant John \"Soap\" MacTavish beginning his career with the British SAS at a training camp in Credenhill, U.K. There, he trains for a cargo ship raid.\r\n\r\nAfter they board the ship, located in the Bering Sea, Soap, Captain Price, Gaz, and several SAS members attempt to find a nuclear device on board. As they clear the ship and kill the Russian soldiers aboard, the ship is attacked by Russian MiGs and begins to sink. The team escapes with the cargo manifest, which provides evidence of ties between the Russian Ultranationalist Party and a rebel faction in the Middle East.\r\n\r\nRussian Ultranationalist leader Imran Zakhaev, who plans to return his motherland to the times of the Soviet Union, draws international attention away from his plans by funding a coup d'état in an unnamed Middle Eastern country, organized by a local separatist leader named Khaled Al-Asad. Discovering the plot, the American government starts a police action to stop the uprising, while the SAS continues to operate in Russia. After President Al-Fulani of the Middle Eastern country is executed on live television and Al-Asad takes control, the SAS rescue their compromised agent, Nikolai, from Russian Ultranationalist forces.\r\n \r\nOne section of the game takes place in Prypiat, Ukraine. Several iconic aspects of the abandoned city, such as this square, were recreated in the game.\r\n\r\nIn the American invasion of the Middle Eastern country, a platoon from the USMC 1st Force Recon, led by Lieutenant Vasquez, deploys to search for Al-Asad, but are too late, and proceed to aid other American units fighting the separatists. During the final stages of the operation, United States Central Command learns of Al-Asad's position in the capital, but is also notified by SEAL Team Six of a Russian nuclear weapon nearby, and sends the Nuclear Emergency Support Team to disarm it. However, the nuclear device suddenly detonates, leveling most of the city, killing his own army, citizens, and the US Invasion Force of 30,000 Marines. Just before the detonation, Vasquez's squad makes a last minute rescue of a pilot from a downed AH-1 Cobra. While fleeing the city, the helicopter is caught in the blast, killing everyone on board..\r\n\r\nThe British learn that Al-Asad fled the country before the American invasion, and is hiding in a safe house in Azerbaijan. With the help of Nikolai's intelligence and assistance from Loyalist Russian soldiers, the SAS clear the village of the Ultranationalist forces and capture and interrogate Al-Asad at his safe house. After listening to the voice calling Al-Asad's phone, Captain Price executes Al-Asad, now knowing that Zakhaev is Al-Asad's backer. Price then has a flashback of his mission to eliminate Zakhaev in Prypiat, Ukraine, 15 years earlier.\r\nIn the aftermath of the Chernobyl disaster and the collapse of the Soviet Union, Zakhaev took advantage of the turmoil to profit from nuclear proliferation and used his new wealth to lure soldiers from the Soviet Army to form his Ultranationalist Party. In 1996, Price was paired with Captain MacMillan, a Scottish SAS captain, to carry out the black op assassination of Zakhaev. After sneaking into Prypiat and taking up a position in an abandoned hotel, MacMillan spotted Zakhaev, and Price hit him with a shot from a Barrett M82, but Zakhaev survived, losing an arm. Price and MacMillan were pursued, but escaped, with MacMillan sustaining an injured leg in the process.\r\nBack in the present day, a joint operation is conducted by Price's SAS unit, a USMC Force Recon unit led by Staff Sergeant Griggs, and Loyalist Russian forces led by Sergeant Kamarov, to stop Zakhaev. They capture his son Victor in an unnamed Russian city, to learn of Zakhaev's whereabouts, but as they corner him, Victor commits suicide to avoid being captured. Zakhaev becomes enraged, blaming Western nations for the death of his son, and plans to retaliate by launching ballistic missiles armed with nuclear warheads at the East Coast of the United States, with predicted losses of over 41 million people. When the Task Force operatives arrive at the facility in Russia, Zakhaev manages to launch ICBMs towards the United States. However, the squad successfully seizes the silo command room and remote detonates the missiles over the Atlantic. They escape the facility in military trucks with Zakhaev's forces in hot pursuit.\r\n\r\nBefore the squad can escape across a nearby bridge, it is destroyed by an Mi-24 Hind, leaving them trapped. Zakhaev's forces arrive and engage the remaining members of the strike force. Gaz receives a call from Kamarov, informing him that his forces are on their way to help. On the bridge, a gas tanker explodes, incapacitating most of the soldiers nearby, except Griggs, who is killed while trying to pull MacTavish to safety. Zakhaev, along with two of his soldiers, begin executing Gaz and other surviving members of the strike force. Before he reaches Soap and Price, he is distracted by the destruction of his gunship and the arrival of the Loyalist helicopters. As Zakhaev looks away, Price slides his pistol to Soap, who shoots and kills Zakhaev and his two guards. When Kamarov and his team arrive, MacTavish is evacuated to safety, while a Russian medic attempts to resuscitate Price.", 'youtube' => 'LhuIjNSg7Gg', 'players' => 1, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [4187], 'genres' => [8], 'publishers' => [33], 'alternates' => ['Call of Duty 4 Modern Warfare'], 'uids' => nil, 'hashes' => nil }, { 'id' => 649, 'game_title' => 'BioShock 2', 'release_date' => '2010-02-09', 'platform' => 1, 'overview' => "The game is set in the fictional underwater dystopia of Rapture, in a biopunk/dieselpunk 1968, eight years after the events of BioShock. The protagonist and player-controlled character is a Big Daddy, a being that has had its organs and skin grafted into an atmospheric diving suit. Among the first of its kind, the player-controlled Big Daddy, named Delta, reactivates with no recollection of the past decade's events, and scours the city in an attempt to relocate the Little Sister that he was paired with. Fearing this reunion will ruin her plans for the city, Sofia Lamb sends out her spliced up followers she calls The Family and new Big Sisters in an attempt to deter Delta.", 'youtube' => '2hLE4DeHtNE', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [44], 'genres' => [1, 2, 8], 'publishers' => [8], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 650, 'game_title' => 'Final Fantasy XIV Online', 'release_date' => '2011-03-01', 'platform' => 12, 'overview' => 'Take up arms with adventurers from around the globe and embark on an epic journey within the unforgettable realm of Eorzea - the stage for a revolutionary new MMORPG designed to fit the lifestyles of players everywhere, from casual users to the most hardcore gamers.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2808], 'genres' => [1, 2, 4], 'publishers' => [12], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 651, 'game_title' => 'Mortal Kombat 3', 'release_date' => '1995-04-01', 'platform' => 18, 'overview' => "Fed up with continuous losses in tournament battle, Shao Kahn, who had lost to Liu Kang in the Outworld tournament, enacts a 10,000 year-old plan. He would have his Shadow Priests, led by Shang Tsung, revive his former Queen Sindel, who unexpectedly died at a young age. However, she wouldn't be revived in the Outworld. She would be resurrected in the Earthrealm. This would allow Shao Kahn to cross the boundary lines and reclaim his queen.\r\nWhen Sindel is reincarnated in Earthrealm, Shao Kahn reaches across the dimensions to reclaim her. As a consequence of his action, the Earthrealm becomes a part of the Outworld, instantly stripping billions of their souls. Only a few are spared, as Raiden protects their souls. He tells them that Shao Kahn must be stopped, but he cannot interfere; due to his status, he has no power in Outworld, and Earthrealm is partially merged with Outworld.\r\nShao Kahn has unleashed extermination squads to roam throughout the Earthrealm and kill any survivors. Also, Raiden's protection only extends to the soul, not to the body, so his chosen warriors have to fight the extermination squads and repel Shao Kahn. Eventually with his final defeat, every human on Earthrealm comes back.\r\nMortal Kombat 3 follows Mortal Kombat II and shares continuity with both Ultimate Mortal Kombat 3 and Mortal Kombat Trilogy which were both updates of this game. The next new game in the series was Mortal Kombat 4.", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'M - Mature', 'developers' => [5507], 'genres' => [10], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 653, 'game_title' => 'Mortal Kombat', 'release_date' => '1992-10-01', 'platform' => 18, 'overview' => "In Mortal Kombat, the player receives information concerning the backstories of the characters and their relationships with one another mainly in biographies that are displayed when the start button is not pressed, during attract mode in the title screen. These bios featured short videos of the characters taking their fighting stances and text informing the motives for each character to enter the tournament. The game takes place in a fantasy setting, with most of the game's events occurring on the fictional realms of the Mortal Kombat series. The original game is notably the only title in the series that features only one realm, that being Earthrealm. The tournament featured in the story actually takes place fully at Shang Tsung's Island, located somewhere on Earth, with seven of its locations serving as Kombat Zones.", 'youtube' => 'https://www.youtube.com/watch?v=tbi7Fu6v9Rs', 'players' => 2, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [5507], 'genres' => [10], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 654, 'game_title' => 'Muhammad Ali Heavyweight Boxing', 'release_date' => '1992-12-01', 'platform' => 18, 'overview' => "In career mode, the player can choose to fight as any of the game's 10 boxers. They start at rank 10 in the heavyweight division, and fight their way through all the others in order.", 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6451], 'genres' => [11], 'publishers' => [48], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 655, 'game_title' => 'NBA All-Star Challenge', 'release_date' => '1992-01-01', 'platform' => 18, 'overview' => 'NBA All-Star Challenge offers one-on-one basketball featuring NBA players from the 1991-1992 season. Five different playing modes are available: a single one-on-one match, a free throw competition, a 3 point shootout, a H.O.R.S.E. competition and a one-on-one tournament. You can choose from 27 players (one from every NBA team), including Michael Jordan, Larry Bird, Patrick Ewing, Karl Malone and David Robinson. Each mode can also be played by two players.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [67], 'genres' => [11], 'publishers' => [118], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 656, 'game_title' => 'NBA Jam Tournament Edition', 'release_date' => '1995-02-23', 'platform' => 18, 'overview' => "NBA JAM Tournament Edition brings you more senses-shattering slam dunking excitement than ever! More than twice as many NBA superstars, more than double the secret characters, Hot Spots, Super Jam Power-Ups, battery back-up and - OH MY - nine all-new rim-rattling slam dunks plus all the original jams! NBA JAM Tournament Edition... it's on FIRE!", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'E - Everyone', 'developers' => [4065], 'genres' => [11], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 657, 'game_title' => 'NBA Jam', 'release_date' => '1994-03-04', 'platform' => 18, 'overview' => "NBA Jam, which featured 2-on-2 basketball, was one of the first real playable basketball arcade games, and was also one of the first sports games to feature NBA-licensed teams and players, and their real digitized likenesses.\r\n\r\nA key feature of NBA Jam was the exaggerated nature of the play - players jumped many times above their own height, making slam dunks that defied both human capabilities and the laws of physics. There were no fouls, free throws, or violations except goaltending and 24 second violations. This meant the player was able to freely shove or elbow his opponent out of the way. Additionally, the game had an \"on fire\" feature, where if one player made three baskets in a row, he would become \"on fire\" and have unlimited turbo, no goaltending, and increased shooting ability, until the other team scored (or the player had scored four consecutive baskets while \"on fire\").", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5507], 'genres' => [11], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 658, 'game_title' => 'New Horizons', 'release_date' => '1994-01-01', 'platform' => 18, 'overview' => 'In New Horizons, it is the early 16th century and the age of exploration and sea trade is underway. Players choose from any one of six adventurers (scenarios), each with their own distinctive but intertwining plot, to embark on a quest of sailing, seamanship and exploration.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4738], 'genres' => [4], 'publishers' => [50], 'alternates' => ['Uncharted Waters: New Horizons'], 'uids' => nil, 'hashes' => nil }, { 'id' => 659, 'game_title' => "NFL Football '94 Starring Joe Montana", 'release_date' => '1994-02-04', 'platform' => 18, 'overview' => "NFL Football '94 Starring Joe Montana is a 1993 Sega Mega Drive/Genesis game which has a realistic running commentary that runs while the player engages himself in exhibition, regular season, or playoff action.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1233], 'genres' => [11], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 660, 'game_title' => "NFL Sports Talk Football '93 Starring Joe Montana", 'release_date' => '1992-05-14', 'platform' => 18, 'overview' => 'Players may choose to play an exhibition game, or compete in the league (16 games, then the playoffs and Super Bowl).', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1233], 'genres' => [11], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 661, 'game_title' => "NHL '94", 'release_date' => '1993-03-15', 'platform' => 18, 'overview' => "Over 25 NEW features in HOCKEY '94! 4-Way Play Support - Use the EA Sports 4-Way Play and NHL '94 becomes a 1, 2, 3 or 4 player game! Goalie Control - You control the double pad stacks and kick saves of all the greats. Penalty Shots and Shootout Mode - Take the hottest shooters and go head to head with the greatest goalies in the league. One Timers - New blistering slap shots make offense faster and more challenging. New Expansion Teams - Play with the Mighty Ducks or with the Florida Panthers. Music and Animations - Over 70 new pieces of organ music from arenas around the league. Plus new crowd and player animations!", 'youtube' => nil, 'players' => 4, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [2724], 'genres' => [11], 'publishers' => [82], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 662, 'game_title' => 'NHL 95', 'release_date' => '1994-07-04', 'platform' => 18, 'overview' => "This is not your ordinary cup! It's the Stanley Cup! And only the victors of the grueling NHL season earn the right to have their name engraved on it. That's a whole season of blistering slap shots, board checks, hot rookies and mid-season trades. NHL '95 drops you into the opening face-off staring down the line at 84 relentless games - trying to carve your name on that Cup!", 'youtube' => '03GLFxsJzG8', 'players' => 4, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [3835], 'genres' => [11], 'publishers' => [82], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 663, 'game_title' => 'NHL 96', 'release_date' => '1995-10-26', 'platform' => 18, 'overview' => 'Fighting is reintroduced in NHL 96, as are major and double minor penalties.', 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3835], 'genres' => [11], 'publishers' => [82], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 664, 'game_title' => "NHLPA Hockey '93", 'release_date' => '1993-04-05', 'platform' => 18, 'overview' => "Skate with all the greats! Over 500 real players have skated into the hot sequel to NHL Hockey. Now you can skate, stick and score with all the greats - Robataille, Chelios, Recchi, and Mullen. Rosters of every professional team including expansion teams Ottawa and Tampa Bay! New Signature Moves - Smack a MacInnis glass breaking slap shot a little high and smash the glass behind the net - Awesome power! Track Player Statistics - Follow how many goals you've scored with your favorite players throughout the playoffs - Jagr, Stevens, Oates, Bure and more!", 'youtube' => nil, 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [6451], 'genres' => [11], 'publishers' => [82], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 665, 'game_title' => 'X-Men', 'release_date' => '1993-03-30', 'platform' => 18, 'overview' => "The evil mutant Magneto has devised the world's deadliest computer virus. Its sole purpose: To destroy the Uncanny X-Men. Now Wolverine, Gambit, Cyclops and Nightcrawler join Storm, Iceman, Archangel, Jean Grey and Rogue to stop Magneto from carrying out his diabolical plan. Their target is Magneto's secret base on Asteroid M. But lying in ambush are the murderous arch villains Juggernaut, Sabretooth, Mojo and Deathbird. Will Wolverine's adamantium claws and Gambit's energy-charged playing cards be enough to defeat the forces of Magneto? That's up to you.", 'youtube' => nil, 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [9585], 'genres' => [1], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 666, 'game_title' => 'Primal Rage', 'release_date' => '1995-08-25', 'platform' => 18, 'overview' => "In Primal Rage, a meteor strike has devastated the Earth; technology has ceased to exist, civilization has been utterly reduced to rubble, and humans have regressed into tribes of Stone Age dwellers. Into this new radiation-scarred world, primitively referred to as \"Urth\", primordial rainforest has covered the land and numerous new species have evolved.\r\nOut of their ranks seven creatures emerge who wage war for control over the new world; they are torn between those who wish to keep peace on Urth, and those who attempt to plunge the world into further chaos for their own benefit. These creatures have otherworldly or supernatural abilities. The Primal Rage trading cards that were distributed along with the toyline presented each creature as a god of an aspect of nature, as in life and death, fire and ice. There are four of the good Virtuous Gods and three evil Destructive Gods. The character Sauron, God of Hunger, is marked as a \"Virtuous Beast\" despite the fact that his in-game ending displays an image of him devouring humans. In fact, the creatures eating humans is a basic part of the gameplay.", 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6787], 'genres' => [10], 'publishers' => [155], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 667, 'game_title' => 'Pitfall: The Mayan Adventure', 'release_date' => '1995-01-01', 'platform' => 18, 'overview' => 'In this game, the player takes the role of Pitfall Harry Jr., son of the hero of the original game, who has to find his kidnapped father.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [234], 'genres' => [2], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 668, 'game_title' => 'Revolution X', 'release_date' => '1994-05-23', 'platform' => 18, 'overview' => "The plot concerns a dystopian version of 1996 where an alliance of corrupt government and corporate military forces have taken control of the world in the guise of the \"New Order Nation\" (NON). The NON, with their vampish commander Mistress Helga (portrayed by Kerri Hoskins), have declared war on youth culture (anyone aged from 13 to 30) and have banned music, television and video games. At a gig in Los Angeles at 'Club X', complete with neon sign, Aerosmith are captured by NON troops once the player reached inside the theater and the game begins.", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'T - Teen', 'developers' => [5507], 'genres' => [8], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 669, 'game_title' => 'The Lion King', 'release_date' => '1994-12-08', 'platform' => 18, 'overview' => "The game is a side-scrolling platform game, with the controlled character having to leap, climb, run and descend from platform to platform. There is an exception during the level The Stampede, where Simba is running towards (or in the NES and Game Boy versions, running with the camera looking straight down on top of him) the camera dodging wildebeest and leaping over rocks.\r\nIn most versions of the game two bars appear on the HUD. To the left is the roar meter, which must be fully charged for Simba's roar to be effective. To the right is the health bar which decreases when Simba is hurt. At the bottom left of the screen is a counter showing how many lives Simba has remaining. Health can be restored by collecting bugs which come in a variety of shapes and sizes. Some rare health-damaging bugs also exist.\r\nThe player controls Simba (first as a cub, then later as an adult) in the main levels and either Timon or Pumbaa in the bonus levels.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9399], 'genres' => [2], 'publishers' => [48], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 670, 'game_title' => "Olympic Gold: Barcelona '92", 'release_date' => '1992-07-24', 'platform' => 18, 'overview' => 'Each computer athlete has a fictional name and nationality (choosing from UK, France, Germany, Italy, Spain, USA, Japan and the Unified Team, everyone with its own anthem snippet) and actual strengths and weaknesses: J. Balen, for instance, is a frequent 100 m and 110 m hurdles record breaker but only an average hammer thrower. Also, each computer controlled player seems better in a particular event depending on his country: Germans usually take the top spots in archery, Italians on swimming, Russians on pole vault, Americans on sprinting and so on.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9135], 'genres' => [11], 'publishers' => [110], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 671, 'game_title' => 'Operation Europe', 'release_date' => '1993-01-16', 'platform' => 18, 'overview' => "Operation Europe: Path to Victory is a multiplatform war game where one or two players can compete in World War II action. The object of the game is to fulfill any one of the military objectives for either the Axis or the Allied forces. Players engage in modern warfare around Western Europe, Eastern Europe, Central Europe, and North Africa.\r\n\r\nThis game uses abstract numbers and figures in the map view and saves the concrete illustrations of soldiers only when they lock horns on the battlefield or in an urban setting. Urban settings give a traditional 1930s view of housing and office buildings that provide extra protection for units that are guarding them. However, there are massive numbers to crunch and the lack of graphics help enhance the number crunching ability of game's artificial intelligence.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4738], 'genres' => [6], 'publishers' => [50], 'alternates' => ['Operation Europe: Path to Victory 1939-45'], 'uids' => nil, 'hashes' => nil }, { 'id' => 672, 'game_title' => 'OutRunners', 'release_date' => '1994-05-13', 'platform' => 18, 'overview' => 'Unlike the original Out Run, some stages are accessible on more than one route combination. After the initial starting stage, the player has the option of either turning east or west. West leads through San Francisco, through the Easter Islands, into Asia and either into Africa or Europe. East goes through the Grand Canyon, South America or Niagara Falls, across the Atlantic Ocean, into Europe and either into Asia or Australia.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [410], 'genres' => [7], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 673, 'game_title' => 'Pac-Attack', 'release_date' => '1993-01-01', 'platform' => 18, 'overview' => "On a Tetris-like board the player drops blocks consisting of Ghosts, Blocks, Pac-Men, and one Fairy (if your Fairy Meter is full) to the ground. The objective is to not let the blocks overflow, let Pac-Man eat the ghosts, and make lines to shorten the amount of blocks on the board. When Pac-Man eats a ghost, the Fairy Meter goes up. Once full, a fairy will eventually be dropped. Once the fairy comes to a stop by landing on anything, it waves its wand and every ghost in the eight lines below it will disappear, often resulting in numerous lines being completed and simplifying the board. Once the fairy disappears, the score bonus is given, and gameplay continues.\r\n\r\nPac-Attack can also be played in 2-player mode. Player 1 must eat Blinky, while Player 2 must eat Sue, the purple ghost from Pac-Mania. As players eat ghosts and complete lines, they will drop ghosts on their opponent's board, messing up their board and bringing them closer to the top. This game can even be played in puzzle mode. The object of this mode is to smash all 100 stages. If you get a Game Over, all the regular blocks appear with red crosses on them, while Blinky and Sue over backwards laughing silently. However, you can try the level again.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5804], 'genres' => [5], 'publishers' => [39], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 674, 'game_title' => 'Pac-Man 2: The New Adventures', 'release_date' => '1994-08-26', 'platform' => 18, 'overview' => "In Pac-Man 2, the player plays the role of an observer and assistant that follows Pac-Man as he sets out to accomplish various tasks. Pac-Man himself walks around in a cartoon world and interacts directly with the player, as well as with objects and other characters. The player cannot control Pac-Man directly, but instead can direct his attention in various directions, and is armed with a slingshot that can be used to strike certain objects, including Pac-Man himself.\r\nPac-Man's mood varies throughout the game, usually in response to his environment or the player's actions, and generally his mood affects his actions and his willingness to cooperate with the player; the varieties of \"bad\" moods can at time compromise the player's ability to progress. There are a few instances, however, where Pac Man is required to be angry. Hitting objects with the slingshot can often get Pac-Man to look at that object and piece together parts of the puzzle he is currently trying to solve - for example, hitting a door may cause Pac-Man to go inside a house to discover a clue. But beware - a few objects when hit can also produce disastrous (and humorous) results. Hitting a trash can on a city street at the wrong time, for example, can cause a cat to jump out and attack Pac-Man.\r\nThroughout the game, Pac-Man is occasionally harassed by the four ghosts from the classic Pac-Man games. When this happens, Pac-Man is paralyzed by fear and eventually faints, unless the player gives him a power pellet. Then Pac-Man becomes Super Pac-Man for a brief time and flies around, eating the ghosts. In some cases, the ghosts may leave behind important objects.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5804], 'genres' => [2, 5], 'publishers' => [39], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 675, 'game_title' => 'Pebble Beach Golf Links', 'release_date' => '1993-01-01', 'platform' => 18, 'overview' => 'Eighteen of the most dramatic and toughest holes in golf. Five exciting golfing options: Practice, Stroke Play, Skins Game, Match Play, and Tournament Play versus 48 top golfers. In-depth Golf features: Caddie Advice, Instant Replays, Complete Shot, Leader Board, and Hole Fly-bys.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8429], 'genres' => [11], 'publishers' => [15], 'alternates' => ['Pebble Beach no Hatou'], 'uids' => nil, 'hashes' => nil }, { 'id' => 676, 'game_title' => 'PGA Tour Golf II', 'release_date' => '1992-01-01', 'platform' => 18, 'overview' => "The sequel to PGA Tour, this game was released solely for the Sega Genesis / Mega Drive along with an alternative version for the Game Gear, as was getting more common for EA sports titles at the time, helping to drive the sales of the 2nd choice console.\r\n\r\nThis update sees the series add ten professional players to the roster (60 in total) and have the ability to play against them on seven courses and across five tournaments. There is also a new graphics engine in place and new sounds to boot. Statistics became more detailed and the ball physics were improved through a Draw and Fade meter. Game data can be backed up through the built-in battery. Other features include different ball lies, dynamic wind conditions, digitized sounds, an improved automatic caddy and special shots such as chips, punches and fringe putts.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6731], 'genres' => [11], 'publishers' => [82], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 677, 'game_title' => 'PGA Tour Golf', 'release_date' => '1991-01-01', 'platform' => 18, 'overview' => 'PGA Tour Golf introduced many of the conventions commonly seen in the genre since. The three-click control method (the first to start the swing, the second setting power and over-swing, the third setting draw or fade) allowed for a multitude of different shots, and required a sense of timing.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8186], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 678, 'game_title' => 'Phantasy Star II', 'release_date' => '1989-03-21', 'platform' => 18, 'overview' => "The time: Space Century 3240. The place: The Algol Star System. It began when King Lassic turned evil and let hordes of hideous, magical creatures run amok on the three planets. When her brother was killed, Alis vowed to avenge his death and put an end to Lassic forever.\r\n\r\nJoin her in a journey across time and space to worlds where creatures speak...where magic and science combine to take you on the ultimate video quest.\r\n\r\nThe battle system is turn-based, allowing the player to choose commands for up to four characters. Each of the eight characters has a different set of preferred weapons and armor, as well as techniques, suited to the character's job. The player must defeat enemies in the overworld and in dungeons to advance in the game.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [4], 'publishers' => [15], 'alternates' => ['Phantasy Star 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 679, 'game_title' => 'Phantasy Star III: Generations of Doom', 'release_date' => '1990-04-21', 'platform' => 18, 'overview' => "Vanquish the Dark Forces\r\n\r\nIt's been a millennium since Laya's hordes battled Orakio's cyborg armies. And civilized man was almost destroyed. But the Dark Forces still remain. Conquer these monstrous mutations. Fight them with swords, knives, bows - even your wits. You live and die by them.\r\n\r\nExplore the Planet and Beyond\r\n\r\nTrek through 7 distant lands - some friendly, some not. Transform into an aerojet and fly over snow-capped mountains. Or become a submersible or aquaskimmer and cross vast oceans and raging rivers. Then find and fight your way through danger-laden dungeons.\r\n\r\nCome Forth Now\r\n\r\nEmbark on a journey so vast, it spans the lives of three generations. Begin with Maia, spirited away by a winged dragon on your wedding day. Experience one of our four endings that will surprise new and former Phantasy Star players alike.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [4], 'publishers' => [15], 'alternates' => ['Phantasy Star 3 - Generations of Doom', 'Phantasy Star 3'], 'uids' => nil, 'hashes' => nil }, { 'id' => 680, 'game_title' => 'Pit-Fighter', 'release_date' => '1990-08-01', 'platform' => 18, 'overview' => "The player begins Pit-Fighter by choosing one of the three playable characters, who all have different moves, speed, and power. As many as three people can play at a time, but there will be extra opponents to fight during any of this game's 15 different matches.\r\nEvery third fight is known as a Grudge Match. In a Grudge Match, the player must fight against a CPU controlled clone of his or her fighter (if playing alone) or the other players in a multiplayer game. Each player has three \"knockdowns\" - getting knocked down three times eliminates them from the Grudge Match, the winner is the last man standing. This match plays more like a bonus round, in that there is only results are gaining or failing to gain bonus money, and losing the Grudge Match does not eliminate a player.\r\nThe final battle, the \"Championship Match\", is between the player and the mysterious entity that taunts between matches every once in a while, the Masked Warrior. If more than one person is playing the game before this match, they must fight each other to the death until only one becomes victorious and can fight him.\r\n\r\n\r\nBuzz posing after taking down the Executioner.\r\nThe player must jump, punch, and kick their opponent until his/her energy runs out. If the player presses all three of the buttons at a time, the character will perform a \"super move\".\r\nSometimes during matches the player will come across foreign objects such as knives, crates, sticks, motorcycles, and bar stools that can be thrown at you or your opponent. The player may also come across a power-up known as the \"power pill\". If the player or the opponent grab this item, one will become temporarily stronger and take less damage from hits.\r\nSometimes even the crowd will interfere in the fights. Two characters, known as Knife Man and Knife Woman, will come out of the crowd and stab the player with their daggers. The player can take these nuisances out with one hit. Sometimes there is also a fat bearded man with a stick. If the player knocks him down, the player can take the stick and use it against the current opponent.\r\nThe audience will also push any fighter that ends up among them, and stays there more than a few seconds. They will be forced back into the fighting area.", 'youtube' => '', 'players' => 3, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [1], 'genres' => [10], 'publishers' => [111], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 681, 'game_title' => 'Ranger X', 'release_date' => '1993-05-27', 'platform' => 18, 'overview' => 'Engage in airborne combat with jump-jets and weapons of incredible power or link up with your cyber cycle for high speed ground attacks. Each step inches you closer to your goal and the fight of your life. You are Ranger X... A mysterious lone warrior who has risen from the ashes to return peace and justice to a failed society. Eight post-apocalyptic levels of high-intensity action! Monstrous mechanical bosses await your every move. Use jump-jets to attack by air or transform into the Super Cyber Cycle and roll to victory!', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3413], 'genres' => [8], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 682, 'game_title' => 'R.B.I. Baseball 4', 'release_date' => '1992-12-18', 'platform' => 18, 'overview' => "R.B.I. Baseball 4 or R.B.I. 4 Baseball (ï¼².ï¼¢.I.ï¼”.ベースボール) is a 1992 baseball game for the Sega Mega Drive by Tengen and the sequel to R.B.I. Baseball 3. It was followed by R.B.I. Baseball '93.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5804, 8654], 'genres' => [11], 'publishers' => [39], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 683, 'game_title' => 'Risk', 'release_date' => '1994-04-02', 'platform' => 18, 'overview' => 'Players attempt to capture territories from other players by rolling higher die numbers. The game is won when one player has managed to occupy every territory.', 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7527], 'genres' => [6], 'publishers' => [156], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 684, 'game_title' => 'Beauty & The Beast: Roar of the Beast', 'release_date' => '1993-10-01', 'platform' => 18, 'overview' => 'As the Beast, the player must successfully complete several levels, based on scenes from the film, in order to protect the castle from invading villagers and forest animals and rescue Belle from the evil Gaston.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8329], 'genres' => [15], 'publishers' => [75], 'alternates' => ['Beauty and the Beast - Roar of the Beast', 'Roar Of The Beast'], 'uids' => nil, 'hashes' => nil }, { 'id' => 685, 'game_title' => 'Rocket Knight Adventures', 'release_date' => '1993-06-16', 'platform' => 18, 'overview' => "He's courageous! He's clever! He's one good lookin' opossum. It's Sparkster the Rocket Knight, the heroic jet pack jockey with warp speed, quick wits and pumped up personality. After all, who else do you know can get a grip with his tail? Rocket through 7 epic stages of animalistic adventure, home of the hugest, strangest enemy pig creatures imaginable. (In fact, your mission is crammed with more ham than a Hollywood premier.) Destroy the Emperor who's on a porcine power trip that will take him to the Key to the Pig Star. In every stage you'll be moving, flying and riding in a new direction to escape opossum punishment. You're the thrust-meister controlling Sparkster's jet pack and his assault sword. Confront mechanized menaces like the Giant Pigbot, the Drill Of A Lifetime, and the snappy Crab Rangoon. Things take a turn for the worst in the room of rotating gravity where Axle Gear, the Black Knights awaits you. And you've never seen anything like the unreal mirrored lava pools where things will reflect badly on you. The tricks, the traps and challenges never end. But the world as you know it will if you don't grind those pigs for sausage.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4765], 'genres' => [1, 15], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 686, 'game_title' => "Roger Clemens' MVP Baseball", 'release_date' => '1992-09-12', 'platform' => 18, 'overview' => 'The game features 26 teams to use, an exhibition mode and a regular season mode. The game had the ability to "save" your career progress by giving you a password that you could enter at the menu screen, when you wanted to continue the season.', 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7527], 'genres' => [11], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 687, 'game_title' => 'College Slam', 'release_date' => '1996-01-31', 'platform' => 18, 'overview' => "Each team starts out by picking any 2 out of 5 players to play with during the game. During timeouts, and at half-time, the player has a choice to make substitutions. When a player makes 2 baskets in a row, the announcer says \"He's heating up\", and if he makes 3 baskets in a row without the other team scoring, he says \"He's on fire!\", which makes it easier to score.\r\nIn the season mode, the player can pick from 44 teams, and then play a 20 game season against quality competition. In the tournament mode, 16 teams compete for a chance to win the national championship. The player also has the ability to edit teams and players. The game itself is not realistic, as players can easily make full-courts shots and occasionally, players get struck by lightning as they dunk. The final score of the games are usually in the middle to high 100s.", 'youtube' => '', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4065], 'genres' => [11], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 688, 'game_title' => 'Shadow Blasters', 'release_date' => '1990-08-09', 'platform' => 18, 'overview' => "The evil god Ashura has unleashed hordes of monsters and demons onto Earth, hoping to take control of the planet as well as the hearts of men. The powerful god Hyprion has recruited four of Earth's most powerful warriors and assembled them into a team to fight the encroaching darkness. The player assumes control of this group of warriors in order to defeat the armies and their god, Ashura.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7712], 'genres' => [1], 'publishers' => [157], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 689, 'game_title' => 'Shadow of the Beast', 'release_date' => '1991-11-01', 'platform' => 18, 'overview' => "There Can Only Be One Master. Destroy the dreaded Dracubeast before his fangs rip through your battle armor. Eliminate the Pit Fiend and capture his Fiery Storm. Lobsterjaw and his wicked bosses defend the secrets of the Master's fortress. Beware of Tuskinhead and his evil minions as you assault the Master's castle!", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7109], 'genres' => [1], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 690, 'game_title' => 'Shaq-Fu', 'release_date' => '1994-10-28', 'platform' => 18, 'overview' => "Shaq brings his awesome skill and size to a multiworld fighting game! As Shaq, use your lightning-fast shuriken and other martial art techniques to prevail over 11 intensely evil warriors in the enforcement of justice. Or choose any of the 12 warriors and fight head to head. Summon Voodoo's bone-shattering earthquake, rebound with Rajah's shockwave sword or lash out with Sett's terrifying mummy wrap! Scores of secret power moves to discover and master!", 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2231], 'genres' => [10], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 691, 'game_title' => 'Sonic the Hedgehog 3', 'release_date' => '1994-02-02', 'platform' => 18, 'overview' => 'Swing from vines, launch new attacks, survive deadly traps and summon Tails to airlift Sonic out of danger. Discover hidden rooms and passageways in the mega-sized Zones. Transform into Super Sonic and experience the ultimate in speed and ultra-sonic power. Save your progress using the new Game Save Feature.', 'youtube' => 'rijqRjPVd3c', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [7979], 'genres' => [2], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 692, 'game_title' => 'Sonic Spinball', 'release_date' => '1993-11-23', 'platform' => 18, 'overview' => "Dr. Robotnik has assumed control of Mt. Mobius and turned it into a mechanical base. Utilizing energy produced by the magma flowing under the volcano, this new monstrosity (the Veg-O-Fortress) has the power to transform helpless animals into robot slaves at an astounding rate. Sonic the Hedgehog and Tails fly onto the scene to mount an aerial assault, but Sonic is knocked off the wings of Tails' airplane by a blast from the fortress. He falls into the water, but is rescued and taken to the subterranean levels of the Veg-O-Fortress. The fortress must be destroyed from the inside-out, and the only way to make that happen is to trigger an eruption in the volcano it's built on. Sonic knows this can be done by removing the Chaos Emeralds that keep the volcano stable. Robotnik, however, is also aware of the fragile relationship that exists between the Emeralds and the mountain, and he's set up an elaborate Pinball Defense System to make sure the precious jewels don't go anywhere.", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7574], 'genres' => [1, 5], 'publishers' => [15], 'alternates' => ['Sonic the Hedgehog Spinball'], 'uids' => nil, 'hashes' => nil }, { 'id' => 693, 'game_title' => "Street Fighter II': Special Champion Edition", 'release_date' => '1993-09-27', 'platform' => 18, 'overview' => "From the corners of the globe come twelve of the toughest fighters to ever prowl the streets. Choose your champion and step into the arena as one of the eight original challengers or as one of the four Grand Masters! Pound your opponent as Balrog and knock them out for the count. Tower over your prey as Sagat and daze them with your awesome Tiger Shot. Slash your opponent with Vega's claw and send them running for cover. Or strike fear into your enemies as M. Bison, the greatest Grand Master of them all!", 'youtube' => 'https://www.youtube.com/watch?v=1JKogi5nXCY', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1436], 'genres' => [10], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 694, 'game_title' => 'Streets of Rage 2', 'release_date' => '1992-12-20', 'platform' => 18, 'overview' => "Original rumblers Axel and Blaze slam the asphalt with bigger, better, totally devastating attacks! Skull-crushing ex-wrestler Max Thunder joins up with earth-shattering body slams and spinning fist attacks. New thrasher Skate slices punks with high speed in-line skate attacks and spinning jump kicks. Go maniac with jaw-shattering, bone-busting punches, head-cracking jump kicks and secret weapons. Gangs of dirt bikers dive into you from every side. Smash 'em with a pipe as they speed by. 16 gigantic megs of compound fractures! All new moves, and more of 'em! Bust knuckles with a friend in an all-new 2-player head-to-head mode!", 'youtube' => '', 'players' => 2, 'coop' => 'Yes', 'rating' => 'Not Rated', 'developers' => [7549], 'genres' => [1, 10], 'publishers' => [15], 'alternates' => ['Streets of Rage II'], 'uids' => nil, 'hashes' => nil }, { 'id' => 695, 'game_title' => 'Sunset Riders', 'release_date' => '1991-09-04', 'platform' => 18, 'overview' => 'The game, which is set in a fanciful version of the American Old West, revolves around four bounty hunters who are out to claim rewards given for eliminating the most wanted outlaws in the West. There is no true "storyline" aside from collecting progressively larger rewards. At the beginning of each level the player is shown a wanted poster, showing the criminal, the reward for stopping them, and the cliché line "Wanted dead or alive".', 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'E - Everyone', 'developers' => [4765], 'genres' => [1, 2], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 696, 'game_title' => 'Shove It! ...The Warehouse Game', 'release_date' => '1990-01-01', 'platform' => 18, 'overview' => "Shove It! follows a burly warehouse worker, whose aspiration is to earn enough money to buy an expensive car and impress the ladies. What must this worker do? Move boxes.\r\n\r\nThe worker is placed in a special grid, and there are only a few different types of blocks: movable crates, locations for crates, and barriers. Crates can only be pushed, not pulled, and only one at a time. The object of each stage is to move each crate to one of the designates spots where crates must be placed. When this is complete, the worker progresses. There is a multitude of stages, grouped in clusters of ten apiece.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2509], 'genres' => [9], 'publishers' => [158], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 697, 'game_title' => 'Shining in the Darkness', 'release_date' => '1991-03-28', 'platform' => 18, 'overview' => "Shining in the Darkness is a \"dungeon-crawler\" RPG. The game puts the player in control of the main character as he and two friends (Pyra and Milo) explore 3-dimensionally rendered dungeon mazes.\r\n\r\nThe game consists of story line interaction, dungeon exploration, random monster fights, and predetermined 'boss' fights. The combat in this game operates similarly to certain RPG games of the same era (e.g. Dragon Quest). Monster encounters happen randomly during dungeon exploration at which point turn-based combat proceeds.\r\nAdditionally, the dungeon contains three characters in need of rescue. Rescuing any or all of the three is optional, and the story changes depending on whether or not the player locates and returns each of these characters to safety.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1685], 'genres' => [4], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 698, 'game_title' => "Space Invaders '91", 'release_date' => '1991-01-01', 'platform' => 18, 'overview' => "Space Invaders '91 is a port of the the coin-op Space Invaders '91, just like Super Space Invaders for other platforms, but still different from those. This version differs from Super Space Invaders in that there are no cutscenes, there is only one mode of play as opposed to SSI's two, and there is no stage select.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [8449], 'genres' => [8], 'publishers' => [56], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 699, 'game_title' => "Spider-Man / X-Men: Arcade's Revenge", 'release_date' => '1994-06-24', 'platform' => 18, 'overview' => "In the first level, the player controls Spider-Man who must use his spider sense to disarm several bombs located throughout the immediate exterior and maze-like entrance to an abandoned building. After the player completes this level Spider-Man learns that the evil Arcade has kidnapped Storm, Cyclops, Wolverine, and Gambit. The player must successfully complete each character's level (each set in Arcade's deadly \"Murderworld\") in order to get to control Spider-Man in a final battle with Arcade.\r\n\r\nAfter completing each stage, the player controls each hero as they fight in similar-designed mini-levels themed after the \"Behind-the-Scenes\" of Murderworld. The only character to have a significant change is Storm, who now walks, shoots multiple bolts of lightning rapidly and calls upon gusts of wind, and jumps about four times the height of the other characters. The last level takes place inside a large room, where Arcade chases Spider-Man back and forth in a large Arcade-shaped robot, which operates like a Matryoshka Doll, until Arcade is finally defeated. The X-Men stand-by at the edges of the room, occasionally attacking on their own.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [7940], 'genres' => [1, 15], 'publishers' => [118], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 700, 'game_title' => 'Sports Talk Baseball', 'release_date' => '1991-08-30', 'platform' => 18, 'overview' => "Players can play either exhibition, regular season, all-star, or playoff games. The game also features authentic Major League Baseball rosters for the 1991 season. Gameplay commonly features double and triple plays, and only the fastest runners in the game are capable of stealing bases. It was one of the first video games to feature individual hitting abilities for each pitcher. Classic match-ups include Texas' Nolan Ryan versus Oakland's lineup with such all-stars as Jose Canseco, Rickey Henderson, Dave Henderson, and Mark McGwire.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => nil, 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 701, 'game_title' => 'Spot Goes To Hollywood', 'release_date' => '1995-11-21', 'platform' => 18, 'overview' => 'The central character in the game is, of course, Spot. Spot has somehow become trapped in a movie projector. As he jumps from film to film, he encounters many classic film genres; these make up the various levels of the game. The main levels are a pirate movie, an adventure movie, and a horror movie, but there are many other bonus films to unlock.', 'youtube' => '', 'players' => 1, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [2886], 'genres' => [2], 'publishers' => [48], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 702, 'game_title' => 'Strider', 'release_date' => '1990-09-29', 'platform' => 18, 'overview' => "Set in the future, the game centers around a secret organization of ninja-like operatives known as \"Striders\", who specializes in various kinds of wetworks such as smuggling, kidnapping, demolitions, and disruption. The player takes control Strider Hiryu, the youngest elite-class Strider in the organization. Hiryu is summoned by the organization's second-in-command, Vice Director Matic, to assassinate his friend Kain, who has been captured by hostile forces and has become a liability to the Striders. Instead of killing him, Hiryu decides to rescue Kain from his captors. With the help of his fellow Strider Sheena, Hiryu uncovers a conspiracy between a certain faction of the Strider organization led by Matic himself and an unknown organization known simply as the \"Enterprise\" (headed by a man named Faceas Clay) which involves the development of a mind-control weapon codenamed \"Zain\". In the course of finding and destroying these Zain units, Hiryu learns that the faction of conspirators is headed by Vice Director Matic himself. Hiryu eventually tracks Matic to an orbiting space station where the two Striders face off; after a brief battle Hiryu bests Matic and kills him. Afterwards Hiryu locates and destroys the last of the Zain units.\r\n\r\nIn the epilogue, it is revealed that though Hiryu was asked to return to the Strider organization he instead opted to retire. The final credits show him sheathing his weapon and walking away.\r\n\r\n\" Sega produced their home version of Strider for the Mega Drive/Genesis, which was released in Japan on September 29, 1990, with subsequent releases in North America and the PAL region. It was advertised as one of the first 8-Megabit cartridges for the system, and went on to be a bestseller. This version was also re-released for the Wii Virtual Console in Japan on November 15, 2011 and later in North America on February 16, 2012. The Genesis/Mega Drive version contains a different ending from the arcade game. This ending shows the destruction of the final stage as the game's protagonist makes good his escape. This is then followed by the main credit sequence that sees Hiryu flying his glider in space and reminiscing about the various encounters he had during his mission as he heads back to earth. The ending theme was an edited combination of two separate pieces of music planned for the arcade game, but replaced with a repeat of the first level music. Computer magazine ACE considered the previous Amiga conversion to be \"as good as this one\". \" -Wikipedia", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [1, 15], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 703, 'game_title' => 'Super High Impact', 'release_date' => '1992-01-01', 'platform' => 18, 'overview' => 'Super High Impact was one of the most hard hitting football games before the NFL Blitz series was created, with 18 teams and over 30 plays per team. The console versions are based on the Midway arcade series of the same name. The game has a Hit-O-Meter which often leads to massive brawls. Based on the arcade smash hit back in the days, featuring the three famous words: EAT THIS!!!, FIGHT!!!', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [5507], 'genres' => [11], 'publishers' => [159], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 704, 'game_title' => 'Super Thunder Blade', 'release_date' => '1989-08-14', 'platform' => 18, 'overview' => 'As in its predecessor, the player takes control of an helicopter which is used to attack a group of guerrillas. The helicopter itself uses guns and missiles, and can also air brake. A distinctive feature that also appears in the arcade game is the use of different viewpoints during the entire game; during normal gameplay and when fighting sub-bosses, the game utilizes a third-person perspective from behind the helicopter, similar to Space Harrier, but the camera changes to a top-down perspective when fighting bosses. Super Thunder Blade had four stages of play.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [8], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 705, 'game_title' => 'Sword of Vermilion', 'release_date' => '1989-12-15', 'platform' => 18, 'overview' => "Sword of Vermilion is about the son of Erik, king of Excalabria, who takes on a quest of revenge to defeat Tsarkon and free the world of Vermilion from evil.\r\nIn the town of Excalabria the people went about their business, and tended to the fields. One day, vicious fighting broke out everywhere as the army from Cartahena, led by the wizard-king Tsarkon, swarmed all over the town. The townsmen were overwhelmed, and the castle of King Erik V collapsed. Erik V summoned his bravest, strongest and most faithful warrior, Blade, and gave him his infant son and an ancient family heirloom, the Ring of Wisdom. Erik ordered Blade to save himself and the child while the castle burned. Blade traveled to a small village named Wyclif, where he settled down and raised the child as his own son. Eighteen years later, the son of Erik begins his quest.\r\nThe quest consists of travelling to towns and villages, battling creatures to gain experience and finding items such as swords, shields and armour, as well as many other items such as Herbs and Candles. Boss monsters take the form of larger, stronger creatures which are integral to the story. Fighting Boss Monsters takes place on a side on view of the battle where magic cannot be used.\r\nThe titular Sword of Vermilion is the most powerful weapon at the end of the game.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [7549], 'genres' => [4], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 706, 'game_title' => 'Syndicate', 'release_date' => '1993-01-01', 'platform' => 18, 'overview' => "The game puts the player in charge of a self-named corporation in a gritty near-future cyberpunk-style world. Game play involves ordering a four-person team of cyborg agents around cities displayed in a fixed-view isometric style, in pursuit of mission goals such as assassinating executives of a rival syndicate, rescuing captured allies, \"persuading\" civilians and scientists to join the player's company or simply killing all enemy agents.\r\nAs the player progresses through the game, they must manage the research and development of new weaponry and cyborg upgrades. The player has only limited funds, requiring taxation of the conquered territories while ensuring that they are not so over-taxed that they revolt against the player. The player begins the game with simple pistols, progressing through increasingly destructive weaponry that includes Uzis, miniguns, flamethrowers, sniper rifles, time bombs, lasers and the enormously destructive Gauss gun (a rocket launcher). In addition, the player can use items such as medikits to heal his agents, scanners to locate pedestrians/vehicles and the \"Persuadertron\" to brainwash the player's targets into blind obedience.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1383], 'genres' => [6, 8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 707, 'game_title' => 'TaleSpin', 'release_date' => '1991-01-01', 'platform' => 18, 'overview' => 'This game involves the adventures of Baloo and Kit, two bears delivering cargo for Rebecca, another bear. However, Shere Khan, the evil tiger tycoon, wants to put Rebecca out of business, so he hires pirates, led by Don Karnage, to do his dirty work.', 'youtube' => nil, 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1, 15], 'publishers' => [9], 'alternates' => ['Tale Spin'], 'uids' => nil, 'hashes' => nil }, { 'id' => 708, 'game_title' => 'Target Earth', 'release_date' => '1990-03-16', 'platform' => 18, 'overview' => "Target Earth is about Earth's outcasts, who have become Cyborgs, returning from space to attack the civilization that remained behind. The Earth Defense League fights to defend Earth in a galactic war. The battle begins on Ganymede. The game alternates between battles in space, on planets, on the earth and inside enemy outposts.\r\nFighting for the OPTOF (Outer Planet Treaty Organization Force),you pilot the Assault Suit Valken 2. Your enemy is the Daess.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [5851], 'genres' => [1], 'publishers' => [160], 'alternates' => ['Assault Suit Leynos'], 'uids' => nil, 'hashes' => nil }, { 'id' => 709, 'game_title' => 'Team USA Basketball', 'release_date' => '1992-01-01', 'platform' => 18, 'overview' => 'The game could be played in various ways: players could play against each other, or against the computer. Games against the computer were divided into two levels, "exhibition" or "tournament". Players could pick from one of the countries around the world to represent in the Olympics: USA, Yugoslavia, Angola, Australia, Canada, China, the CIS, Croatia, France, Italy, Lithuania, Slovenia, Netherlands, Spain.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2724], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 710, 'game_title' => 'Technoclash', 'release_date' => '1993-01-01', 'platform' => 18, 'overview' => "Long ago, magic was used in everyday life, the world lived in harmony where wizards lived happily among themselves. A mysterious portal appeared in the sky where machines started emerging, causing havoc upon the magical world. Ronaan is a wizard who embarks on a journey after a magical staff is stolen from his homeland. The war between the machines and magic have only just begun, It's up to Ronaan, Farrg and Chaz to prevent the destruction of their world as they travel through Las Vegas, a junkyard, a desert and the heart of the Machine Empire.", 'youtube' => '', 'players' => 0, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1233], 'genres' => [1, 4], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 711, 'game_title' => "Scholastic's The Magic School Bus: Space Exploration Game", 'release_date' => '1995-01-01', 'platform' => 18, 'overview' => 'Based on the PBS kids program, The Magic School Bus along with Ms. Frizzle and her companion Liz takes the player throughout the solar system one planet at a time to learn about them while exploring each one. Along the way, players will be transported on the bus on their way to the next planet where they can take photos of the planets, their moons, stars, among many other things they can see. Along the way they will encounter puzzles they have to solve in order to advance using the facts they have learned through their planetary visit and can also build their own solar system in any way they choose.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6155], 'genres' => nil, 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 712, 'game_title' => 'The Pirates of Dark Water', 'release_date' => '1994-01-01', 'platform' => 18, 'overview' => "The Pirates of Dark Water is a side scrolling hack'n slash platformer with a few adventure elements.\r\n\r\nYou take control of either Ren, Ioz or Tula who can jump, climb, attack and throw enemies. In most levels you are required to find keys to unlock doors and talk to NPCs who will give you hints. You will also find numerous useful items including throwing weapons, food to replenish your health, potions that have different effects such as temporary invincibility, money that is needed to pay certain NPCs and melons that can be fed to Niddler who will take you back to the map screen in turn.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4065], 'genres' => [1, 15], 'publishers' => [104], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 714, 'game_title' => 'Thunder Force II', 'release_date' => '1989-08-14', 'platform' => 18, 'overview' => "Taking place soon after Thunder Force, the ORN Empire creates a powerful new battleship, the Plealos (a.k.a Preareos). Using this battleship, ORN once again attacks the Galaxy Federation. The outcome of the attacks result in the destruction of the Galaxy Federation affiliated planet of Reda, and heavy destruction on the planet Nepura (a.k.a. Nebula), which ORN eventually captures from the Galaxy Federation.\r\nEventually, the Galaxy Federation learns that ORN houses Plealos deep below Nebula's surface when not in use and takes the opportunity to plan an operation to take it down. They send the next iteration of their Fire Leo series of fighter craft, the FIRE LEO-02 Exceliza, to destroy ORN bases on Nepura and eventually find and destroy Plealos. The player controls the Exceliza and travels through a variety of stages to accomplish this goal.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8609], 'genres' => [8], 'publishers' => [137], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 715, 'game_title' => "Tiny Toon Adventures: Buster's Hidden Treasure", 'release_date' => '1993-02-07', 'platform' => 18, 'overview' => "Hit it big when you join Buster Bunny on a 33 stage hunt for treasure. So loaded with hare-raising animation, it's like playing in a whacked-out Tiny Toon cartoon! Do you dare to set paw on this mysterious island? Trip through 7 tangly territories that include an overly-enchanted forest, caverns of bubbling lava-lava, secret underground seas, plains that are just plain crazy, a freaky factory, a mega mountain and a spooky shipwreck rumored to be dripping in 14 carrot gold! Save Babs Bunny and the rest of your pals along the way and you'll really see some kooky island hopping. With Gogo Dodo as your guide, you can be sure this adventure is packed with tricks, traps, and hidden bonus areas!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4765], 'genres' => [1, 15], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 716, 'game_title' => 'ToeJam & Earl in Panic on Funkotron', 'release_date' => '1993-04-01', 'platform' => 18, 'overview' => "The plot of the game follows on from that of its predecessor, which followed the adventures of alien protagonists ToeJam and Earl after they crash landed on Earth. After escaping to their home planet of Funkotron, the characters discover that antagonistic Earthlings have stowed-away on the duo's spacecraft.\r\n\r\nA sub-plot involves ToeJam and Earl's attempt to lure Lamont the Funkapotamus back from the Funk Dimension, where he is hiding from the invading Earthlings.\r\n\r\nToeJam and Earl must hunt down Earthling antagonists, which include a \"pneumatic-drill-crazed construction worker, a camera-wielding tourist, our old friends the bogymen [sic], pea-shooter armed kids and a rather rotund woman with ankle-snapping poodles.\r\n\r\nCapturing Earthlings involves rummaging for them in bushes and trees, before pelting the antagonist with \"jars\" which imprison them. The player completes a level by catching all the at large Earthlings and sending them back to Earth via spacecraft.", 'youtube' => nil, 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [4506], 'genres' => [1, 15], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 717, 'game_title' => 'Toki: Going Ape Spit', 'release_date' => '1991-01-01', 'platform' => 18, 'overview' => "The hero of the game is a young jungle-man named Toki. One day the evil wizard Dr. Stark kidnaps his girlfriend Wanda. When Toki tries to save her, he is turned into a monkey! Now Toki has to find Dr. Stark in his palace, to rescue Wanda, and to become a human being again!\r\n\r\nIt is a platform game with a lot of various levels: jungle, underwater, volcanic caves, on the ice... Toki's only weapons are spitting on the enemies or jumping on them and crashing them. There are many possibilities to upgrade his spitting \"weapon\"; for example, if he finds an upgrade, he can spit fireballs.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [8442], 'genres' => [1, 15], 'publishers' => [15], 'alternates' => ['JuJu Densetsu'], 'uids' => nil, 'hashes' => nil }, { 'id' => 718, 'game_title' => 'Tommy Lasorda Baseball', 'release_date' => '1989-08-14', 'platform' => 18, 'overview' => "It's batter-up and time for Tommy Lasorda's version of Pro-Ball. Whether you're infield or outfield, at the plate or on the mound, stealing bases or catching fly-balls, the competition is hot and you're even hotter now that you're playing with a big leaguer like Lasorda. And you've got control. Curve balls, fastballs or sliders are some of the wind-ups you'll pitch to outwit your batter. But be prepared when he connects, you'll have to think fast to make your players perform like a well-oiled machine. Are you up for a single, double, or even triple play? It all depends on how you throw the ball. But don't worry, you'll get your chance at bat. This is a race for the Pennant, so you better hope Tommy's on your side. Now take your pick, choose your line-up and let's play ball!", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [11], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 719, 'game_title' => 'Traysia', 'release_date' => '1992-02-14', 'platform' => 18, 'overview' => 'In Traysia the player controls a young man named Roy, who lives in the town Johanna. All his life Roy has been dreaming about leaving the town and going to explore faraway lands. Now, finally, his chance has come. His uncle, a travelling merchant, is going on a journey, and Roy decides to leave with him. His girlfriend Traysia gives him a pendant, to remind him of her... will Roy be able to escape from all the dangers that await him on his long journey and to see Traysia again?', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [8640], 'genres' => [4], 'publishers' => [119], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 720, 'game_title' => 'Triple Play: Gold Edition', 'release_date' => '1996-02-16', 'platform' => 18, 'overview' => 'Triple Play: Gold Edition is a baseball game released exclusively for the Sega Mega Drive. It is part of the long running Triple Play series.', 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2952], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 721, 'game_title' => 'Truxton', 'release_date' => '1989-12-09', 'platform' => 18, 'overview' => 'Taking place somewhere in space: an armada of Gidans, led by the evil Dogurava, is invading the planet Borogo aboard five gargantuan asteroids. After surviving an attack on an orbiting Borogo cargo barge, a pilot enters one remaining fighter and challenges the Gidans in a desperate attempt to quell the alien invasion and divert their asteroid fortresses in the process.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [8503], 'genres' => [8], 'publishers' => [15], 'alternates' => ['Tatsujin - Truxton', 'Tatsujin'], 'uids' => nil, 'hashes' => nil }, { 'id' => 722, 'game_title' => 'Ultimate Qix', 'release_date' => '1991-01-01', 'platform' => 18, 'overview' => "Taking place in another galaxy, a space pilot is returning to his home world of Volfied, only to discover that it is under attack by an unknown alien force. The few remaining Volfied inhabitants are in an underground location of the planet and signal the pilot to their aide. The pilot flies to Volfied using his ship's defensive weapons in order to eliminate the alien threat and save his people.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [4378], 'genres' => [5], 'publishers' => [56], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 723, 'game_title' => 'Urban Strike', 'release_date' => '1993-03-04', 'platform' => 18, 'overview' => "Home Field Advantage!\r\n\r\nFirst the Desert Madman, then the Jungle Drug Lord... now a new evil challenges the Strike C.O.R.E., right here in America! Ruthless media mogul and political maverick H.R. Malone secretly plans to destabilize the U.S. government. Crust this rebellion at all cost!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [8726], 'genres' => [1], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 724, 'game_title' => 'Valis III', 'release_date' => '1991-03-22', 'platform' => 18, 'overview' => "Somewhere in the Dark World, evil rears its ugly head once again...\r\nA black-hearted man named Glames, possessor of a sword named Leethus, threatens the Human World, the Dream World, and the Dark World with complete and utter destruction. A young girl from the Dark World named Cham escapes from Glames, and seeks help to destroy him.\r\n\r\nShe comes to the Human World, searching for the Valis Warrior, Y?ko Asou, and more importantly, the Valis Sword.\r\n\r\nYuko must now help Cham defeat Glames before the three worlds are torn apart!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8640], 'genres' => [1, 2], 'publishers' => [119], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 725, 'game_title' => 'Virtual Pinball', 'release_date' => '1993-11-01', 'platform' => 18, 'overview' => 'One to four players can choose from either 29 pre-made games or design one using the in-game editor tools. Designing options include ten different backgrounds and six themes. You also get to choose where objects are placed, the style of music, and the ball speed. Up to ten personal games can be saved.', 'youtube' => '', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1067], 'genres' => [11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 726, 'game_title' => 'Warlock', 'release_date' => '1995-09-01', 'platform' => 18, 'overview' => "Once every thousand years, the sun and the moon align together. When this happens, the Evil One sends his only son, the Warlock, to Earth to gather six ancient runestones. When assembled, the runestones give the possessor ultimate power to undo the Earth's creation. Using sorcery inherited from his ancestors, a modern druid must travel through time to prevent the Warlock from finding all of the runestones.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7050], 'genres' => [1], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 727, 'game_title' => 'Wheel of Fortune', 'release_date' => '1992-01-01', 'platform' => 18, 'overview' => 'A very basic translation of the popular game show Wheel Of Fortune, where you guess letters until you can guess the phrase. This CGA version has three old-school rounds of Wheel of Fortune (where the puzzles are simply "Phrase", "Title", "Person", etc.) and then a bonus round. You can compete against 2 computer players or up to three people can play against each other.', 'youtube' => nil, 'players' => 3, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4114], 'genres' => [5], 'publishers' => [80], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 728, 'game_title' => "Winter Olympic Games: Lillehammer '94", 'release_date' => '1993-12-07', 'platform' => 18, 'overview' => "This is the official license of Winter Olympics tournament in 1994 at Lillehammer, Norway. You can practice in any event before the tournament. The game offers two modes - Full Olympics and Mini Olympics, which vary in the number of events.\r\n\r\nIt includes 5 different types of sports - biathlon, alpine skiing (downhill, slalom, giant slalom and Super-G), ski jumping (90 m, 120 m), bobsleigh (2/4 men bob, 1/2 men luge) and skating (elimination, pursuit, time trial). The events use 3D views", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8826], 'genres' => [11], 'publishers' => [110], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 729, 'game_title' => 'Wonder Boy in Monster World', 'release_date' => '1992-12-04', 'platform' => 18, 'overview' => 'Townsfolk cower in fear as legions of deadly monsters invade the planet. Only Wonder Boy can fight smart enough - and tough enough - to wipe out the terrible beasts. Sleuth out secret clues to thwart the undead. Match wits against an evil force of otherwordly dimensions. And prove the awesome strength and courage of the amazing Wonder Boy!', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9590], 'genres' => [15], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 730, 'game_title' => 'World Series Baseball', 'release_date' => '1994-01-04', 'platform' => 18, 'overview' => "World Series Baseball is the first game in the long-running series. With all 28 teams included, it features the 6 division alignment (introduced shortly before its release), and has all 700 players of the league.\r\n\r\nThe game includes a play-by-play feature and the Home Run Derby. Players are able to play a 162-game season and keep full statistics for every player, thanks to a battery backup. The game also allows players to use the first-person perspective view from the batter's box.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1233], 'genres' => [11], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 731, 'game_title' => 'WWF WrestleMania: The Arcade Game', 'release_date' => '1995-08-10', 'platform' => 18, 'overview' => "WrestleMania's one-player mode has the player choose one of eight wrestlers - Bam Bam Bigelow, Bret Hart, Doink the Clown, Lex Luger, Razor Ramon, Shawn Michaels, The Undertaker or Yokozuna. One unique feature is that each character can \"bleed\" his respective objects other than blood upon taking damage from most attacks in the Mortal Kombat sense. Such \"bleeding\" objects include Yokozuna's food and Bam Bam Bigelow's flames.\r\nWWF WrestleMania features two single-player modes: the Intercontinental Championship and the WWF Championship. In the Intercontinental Championship mode, the player must win four one-on-one matches, two two-on-one matches, and one three-on-one match to win the title. In the more difficult WWF Championship mode, the player must win four two-on-one matches, two three-on-one matches, and finally a \"WrestleMania Challenge,\" where the player must defeat every wrestler in the game in a gauntlet, starting with a three-on-one setup, with each eliminated opponent being replaced with another until all eight have been defeated.\r\nThe game also features two multi-player modes; head to head, a one-on-one match between two players, or cooperative, where the two players team up in a tag team version of the WrestleMania Challenge in which they must defeat the game's eight wrestlers in groups of two to become the Tag Team Champions.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5507], 'genres' => [11], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 732, 'game_title' => "The Ren & Stimpy Show Presents: Stimpy's Invention", 'release_date' => '1993-12-31', 'platform' => 18, 'overview' => 'In one player the player controls either Ren or Stimpy and the computer controls the other character who will simply follow; however, the player can swap the character they control at almost any time during game play. In two player, players controls one character each, both within the same screen (no split screen). In one or two player several special moves can be performed by both characters standing close and a player pressing certain buttons simultaneously, the move differs depending on which buttons are pressed and whether the player is controlling Ren or Stimpy. The ability of swapping characters during game play in one player means the player can perform all the special moves not just those available for one character. The moves include: Stimpy throwing Ren to cover long distance such as over a hole.', 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1233], 'genres' => [2], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 733, 'game_title' => 'Sonic & Knuckles', 'release_date' => '1994-10-18', 'platform' => 18, 'overview' => "Sonic and Knuckles join forces to defeat rotten Dr. Robotnik's Death Egg invasion! Play Sonic & Knuckles by itself or Lock-on with other Sonic games. This game's revolutionary Lock-on technology adds all new features to your other Sonic games for ultimate replays! Play as Sonic and let loose on Robotnik with amazing new powers. Play as Knuckles and tackle Robotnik and Metal Sonic with bare-fisted attacks, high-speed glides and wall-climbing power! Lock-on with Sonic 3 and transform Floating Island into a huge 34 meg Sonic-epic loaded with new secrets! Play as Sonic, Knuckles, and even Tails - with Game Save! Lock-on with Sonic 2 and play as Knuckles with all his signature moves!", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [1], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 734, 'game_title' => 'Road Rash II', 'release_date' => '1993-07-22', 'platform' => 18, 'overview' => "Road Rashing isn't just a sport. It's an attitude! Road Rash II is the ultimate 2-player racing game with a radically unique split-screen for distinguishing between racers. Cruising cross-country was never this hairy! Spectacular new body-torquing wipe outs! More obstacles to crash into than ever before. Terrorize your opponents on 5 new tracks, each with 5 different levels. Swing a steel chain for some real heavy metal damage! 15 brand new, lightning-fast cycles, including nitro-equipped Super-Bikes!", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2724], 'genres' => [1], 'publishers' => [2], 'alternates' => ['Road Rash 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 735, 'game_title' => 'Cool Spot', 'release_date' => '1994-02-18', 'platform' => 18, 'overview' => 'Cool Spot is a solid, colorful platform game featuring the 7-up mascot in the hero position. The game objective is fairly simple; you have to collect enough number of bonuses throughout each level in order to find the trapped Spots.', 'youtube' => nil, 'players' => 1, 'coop' => nil, 'rating' => 'E - Everyone', 'developers' => [9399], 'genres' => [2], 'publishers' => [48], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 736, 'game_title' => 'Battletoads', 'release_date' => '1991-01-14', 'platform' => 18, 'overview' => "After her defeat by the Galactic Corporation at the battle of Canis Major, the evil Dark Queen and her renegade space troops retreat to the outer reaches of the universe, hiding out in dark spaces between the stars. Meanwhile, on board the spaceship Vulture, Professor T. Bird and the trio of Battletoads - Rash, Zitz and Pimple - are escorting the Princess Angelica back to her home planet, where her father, the Terran Emperor, awaits her safe arrival. Along the way, Pimple, the biggest Battletoad, takes Angelica out for a cruise in the Toadster to a nearby Leisure Station, but the Dark Queen ambushes them before they can get there, and they are kidnapped and carried away to Ragnarok's World, the Dark Queen's planet. Professor Bird sends remaining Battletoads down on Ragnarok to save Pimple and Angelica, but it will be a hard battle against planet's dangerous environments, traps and Dark Queen's troops. They have to go a long way from the planet's rough surface to deep caves and landed Gargantua and ultimately to the Tower of Shadows, where the Dark Queen awaits.", 'youtube' => nil, 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [6991], 'genres' => [1], 'publishers' => [164], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 737, 'game_title' => 'After Burner III', 'release_date' => '1992-04-17', 'platform' => 21, 'overview' => "You're strapped into the Navy's fiercest jet fighter-the F-14 Tomcat. Kick in the afterburner to outrun deadly cannon fire \"hot on your six.\" Pull up hard...lock and launch! Roll 360 degrees to blow desert tank patrols, radio towers, and missile sites into oblivion.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1923], 'genres' => [8, 19], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 738, 'game_title' => "Dragon's Lair", 'release_date' => '1994-06-19', 'platform' => 21, 'overview' => "Dragon's Lair features the hero, Dirk the Daring, attempting to rescue Princess Daphne from the evil dragon Singe, who has locked Daphne in a wizard's castle. The screen shows animated scenes, and the player executes an action by selecting a direction or pressing the sword button with correct timing. The comedy of the game stemmed not only from the bizarre looking creatures and death scenes, but also the fact that while Dirk was a skilled knight, he was somewhat clumsy in his efforts, as well as being a reluctant hero, prone to shrieking and reacting in horror to the various dangers he encounters.", 'youtube' => 'XXgAfyVYN2c', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [268], 'genres' => [2], 'publishers' => [56], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 739, 'game_title' => 'Sewer Shark', 'release_date' => '1992-10-15', 'platform' => 21, 'overview' => "Sewer Shark takes place sometime in the future, where environmental destruction has forced most of humanity to live underground. The player takes the role of a rookie pilot in a band of \"sewer jockies\", whose job is to exterminate dangerous mutated creatures to keep a vast network of sewers clean for the resort area \"Solar City\", an island paradise ruled by the evil Commissioner Stenchler (Robert Costanzo). The player's co-pilot, Ghost (David Underwood), evaluates the player's performance throughout the game, while a small robot named Catfish scouts ahead and gives directions. The player is later assisted by Falco, a female jockey who believes that there is a hidden route to the surface. Falco is later captured by Stenchler, who threatens to turn her into one of his mindless minions. This plot is thwarted when Ghost and the player reach Solar City.", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'E - Everyone', 'developers' => [2348], 'genres' => [8, 19], 'publishers' => [77], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 740, 'game_title' => 'Star Wars: Rebel Assault', 'release_date' => '1993-01-01', 'platform' => 21, 'overview' => "The game follows the adventures of a young pilot known as Rookie One, a farmer from Tatooine in the style of Luke Skywalker. The game largely takes place during the events of Episode IV: A New Hope, however the sequences on Hoth from The Empire Strikes Back are included.\r\nThe game begins with Rookie One's training (you), followed by an attack on the Star Destroyer Devastator, after its capture of the Tantive IV in the events of the film. The story then leads the player to sequences to defend the Rebel Base on Hoth from the attack shown in the Empire Strikes Back, and finally ends in the assault on the Death Star of the film, with the player taking the place of Luke Skywalker in destroying the battle station.", 'youtube' => 'F6yOX2vmxgY', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5068], 'genres' => [1, 8], 'publishers' => [25], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 741, 'game_title' => 'Surgical Strike', 'release_date' => '1993-11-16', 'platform' => 21, 'overview' => "The elite Special Forces unit, The Surgical Strike Team, have been called into action. High-tech urban guerrillas are attacking innocent people but once they're done with their carnage they fade back into the landscape. In a very delicate way, the Team must find these hidden enemies and get rid of them without harming innocent citizens. Inside your hovercraft, you can charge at the violent creatures, turn 180 degrees to watch your own back and explore new uncharted areas. You have a choice of weaponry choose the 30MM Gatling gun or the laser-guided rockets. AWACs C-130's hover above and give you pointers, plus on-board mapping allows you to zero in on hidden emplacements.", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'T - Teen', 'developers' => [1720], 'genres' => [1], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 742, 'game_title' => 'Aero Fighters 3 / Sonic Wings 3', 'release_date' => '1995-01-01', 'platform' => 24, 'overview' => "The world seems to be free from the menace of the evil alien forces. However, they are not willing to give up and launch a surprise attack against the Aero Fighters' base, effectively destroying their aircraft. Unable to counter the attack, they must use old WWII-era warplanes with strange modifications, in a desperate scramble for victory.", 'youtube' => '', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [9375], 'genres' => [1, 8], 'publishers' => [165], 'alternates' => ['sonicwi3'], 'uids' => nil, 'hashes' => nil }, { 'id' => 743, 'game_title' => 'Aero Fighters 2 / Sonic Wings 2', 'release_date' => '1994-08-26', 'platform' => 24, 'overview' => "The game is played with two buttons, with the A button firing bullets from the plane and the B button launching a special bomb attack which uses a bomb from a limited stock of bombs. Power bullets can be obtained by destroying buildings and armored enemy planes. There are 2 types of Power bullets: \"P\" Power bullets, that increases the plane's firepower by one level, and \"F\" Power bullets, that increases the plane's firepower to the maximum level instantly. The maximum level only lasts for a limited amount of shots.\r\nWhen certain ground enemies and buildings are destroyed, money bonuses appear which give a random amount of points each. When the player reaches the end of the stage, the player has to face a boss ship.", 'youtube' => '', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [9375], 'genres' => [1, 8], 'publishers' => [165], 'alternates' => ['sonicwi2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 744, 'game_title' => 'Samurai Shodown', 'release_date' => '1993-08-11', 'platform' => 24, 'overview' => 'The game is set in the late 18th century and all the characters wield weapons. The game uses comparatively authentic music from the time period, rife with sounds of traditional Japanese instruments, such as the shakuhachi and shamisen, and a refined version of the camera zoom first found in Art of Fighting. True to its use of bladed weapons, the game also included copious amounts of blood.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [7885], 'genres' => [10], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 745, 'game_title' => 'Doom', 'release_date' => '1993-12-10', 'platform' => 1, 'overview' => "In Doom, a nameless space marine, gets punitively posted to Mars after assaulting a commanding officer, who ordered his unit to fire upon civilians. The Martian marine base acts as security for the Union Aerospace Corporation UAC, a multi-planetary conglomerate, which is performing secret experiments with teleportation by creating gateways between the two moons of Mars, Phobos and Deimos. Suddenly, one of these UAC experiments goes horribly wrong; computer systems on Phobos malfunction, Deimos disappears entirely and \"something fragging evil\" starts pouring out of the gateways, killing or possessing all UAC personnel! \r\nResponding to a frantic distress call from the overrun scientists, the Martian marine unit is quickly sent to Phobos to investigate, where you, the space marine, are left to guard the hangar with only a pistol while the rest of the group proceeds inside to discover their worst nightmare. As you advance further, terrifying screams echo through the vast halls, followed by a disturbing silence ... it seems, all your buddies are dead and you're all on your own now - fight back, exterminate every evil creature and get your ticket back home to earth!", 'youtube' => 'u2CzxI04qHs', 'players' => 4, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [3993], 'genres' => [1, 8], 'publishers' => [166], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 746, 'game_title' => "Monkey Island II: LeChuck's Revenge", 'release_date' => '1991-01-01', 'platform' => 1, 'overview' => "LeChuck's Revenge is set in the fictional Tri-Island Area of the Caribbean, several months after The Secret of Monkey Island. The game opens in medias res as Guybrush Threepwood hangs on a rope above a hole, narrating to Elaine Marley on a separate rope the events that led to this situation. The flashback sequence starts on Scabb Island and constitutes most of the playable game's setting. During it, Guybrush also visits Phatt Island, Booty Island, and Dinky Island, voyaging on two different pirate ships.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [5068], 'genres' => [2, 4], 'publishers' => [25], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 747, 'game_title' => 'Star Wars: Dark Forces', 'release_date' => '1995-02-15', 'platform' => 1, 'overview' => "The storyline in Dark Forces follows Kyle Katarn, a mercenary employed by the Rebel Alliance. Before the events in Dark Forces, Katarn was a student learning the skills required to follow in his father's career of agricultural mechanics. While he was studying at an academy, he was told by officials that rebels had killed his parents. The pain from this caused him to enlist in the Imperial army.\r\n\r\nKatarn met Jan Ors who was undercover as a double agent and they got to know each other. Ors uncovered the real information about Katarn's parents which detailed that the Empire was really behind their deaths. The empire eventually discovered that Ors was working for the rebels and she was taken prisoner. Katarn helped her escape, thus ending his career with the Empire. Katarn soon became a mercenary and, due to his hatred of the Empire for killing his parents, he takes on jobs from the Rebel Alliance.", 'youtube' => 'F5YjJsh6BEk', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5068], 'genres' => [8], 'publishers' => [25], 'alternates' => ['Dark Forces'], 'uids' => nil, 'hashes' => nil }, { 'id' => 748, 'game_title' => 'Age of Empires', 'release_date' => '1997-10-15', 'platform' => 1, 'overview' => 'Control your tribe with the mouse. Make them build houses, docks, farms, and temples. Advance your civilization through time by learning new skills. The game allows for the player to advance through the ages: stone age, tool age, bronze age. If the player would rather get away from the historical aspect, the game offers a random terrain generator and a custom scenario builder.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2817], 'genres' => [6], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 749, 'game_title' => 'Age of Empires II: The Age of Kings', 'release_date' => '1999-09-30', 'platform' => 1, 'overview' => 'The Age of Kings focuses on building towns, gathering resources, creating armies, and destroying enemy units and buildings. Players conquer rival towns and empires as they advance one of 13 civilizations through four "Ages": the Dark Age, the Feudal Age, the Castle Age (The Middle Ages), and the Imperial Age, reminiscent of the Renaissance—a 1000 year timeframe.', 'youtube' => 'https://VnrtlX0q-b0&hd=1', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2817], 'genres' => [6], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 750, 'game_title' => 'Age of Empires III', 'release_date' => '2005-10-18', 'platform' => 1, 'overview' => "The story-based campaign mode consists of related scenarios with preset objectives, such as destroying a given building. In Age of Empires III, the campaign follows the fictional Black family in a series of three \"Acts\", which divide the story arc into three generations. All three acts are narrated by Amelia Black (Tasia Valenza).\r\n\r\nInstead of playing as one of the standard civilizations, the player takes command of a special civilization that is linked to the character or period that each Act portrays. Most units of the player civilizations speak in English language, with the exception of unique units such as Spanish Rodeleros, Spanish Lancers, German Ulhans and German War Wagons.", 'youtube' => 'GYz2PqB79nI', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2817], 'genres' => [6], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 751, 'game_title' => 'Battlefield 2', 'release_date' => '2005-06-21', 'platform' => 1, 'overview' => "The story takes place in the early 21st century during a fictional world war between various power blocks: China, the European Union (playable as of the 1.50 patch), the fictional Middle Eastern Coalition (MEC), Russia (playable only in the Special Forces expansion) and the United States. In-game, the European Union and the United States fight China and the MEC. It is known that in the game's story, the EU and the US are allies and the EU has negotiated a peace deal with Russia but it is unknown if China and the MEC are allies. The game takes place in different fronts, as the Middle East and China are being invaded by US and EU forces, and the United States is being invaded by Chinese and MEC forces.", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2327], 'genres' => [8], 'publishers' => [35], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 752, 'game_title' => 'Battlefield 2142', 'release_date' => '2006-10-17', 'platform' => 1, 'overview' => "In 2006 a climatic catastrophe triggered a new ice age on earth. A hundred years later, everyone gave up on finding a solution to the problem and two superpowers were formed: Europe and on the other side the Pan Asian Coalition - causing an arms race. Now it's 2142 and the war for the few resources left has already been going on for a few years, with no end in sight.", 'youtube' => 'Mk4wEAO07hM', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2328], 'genres' => [8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 753, 'game_title' => 'Call of Duty 2', 'release_date' => '2005-10-25', 'platform' => 1, 'overview' => 'The game is set during World War II and is experienced through the perspectives of four soldiers, one in the Red Army, one in the United States Army and two in the British Army.', 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [4187], 'genres' => [8], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 754, 'game_title' => 'The Curse of Monkey Island', 'release_date' => '1997-10-31', 'platform' => 1, 'overview' => 'This third installment in the Monkey Island franchise is, like its predecessors, a humorous puzzle-solving adventure game. The game features cartoon-style SVGA graphics and (for the first time in the series) voice-overs for all the conversations. The interface no longer involves a list of verbs that occupies a part of the screen; instead the player chooses first the object to interact with, then the action from a menu that appears. Like the second game, The Curse of Monkey Island has two difficulty levels.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5068], 'genres' => [2], 'publishers' => [25], 'alternates' => ['The Curse of Monkey Island'], 'uids' => nil, 'hashes' => nil }, { 'id' => 755, 'game_title' => 'Medal of Honor', 'release_date' => '2010-10-12', 'platform' => 1, 'overview' => 'Medal of Honor will feature a single-player campaign that takes place in 2002, in which the player will control multiple characters from both the “Tier 1†and “Big Military†perspectives. The storyline will follow several "Tier One Operators" working under the National Command Authority in Afghanistan during Operation Enduring Freedom. Players will also play as a US Army Ranger and an Apache helicopter gunner, fighting on a larger scale than the "Tier 1 Ops" campaign, as players will then only be a small part of the "war machine". The campaign will be heavily weighted (with regards to playtime) in favor of the Tier 1 operators.', 'youtube' => 'HigXVoGpU24', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2724], 'genres' => [8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 756, 'game_title' => "Sid Meier's Civilization III", 'release_date' => '2001-10-30', 'platform' => 1, 'overview' => "Civilization III, like the other Civilization games, is based around building an empire, from the ground up, beginning at start of recorded history and continuing beyond the current modern day. The player's civilization is centered around a core of cities that provide the resources necessary to grow the player's cities, construct city improvements, wonders, and units, and advance the player's technological development. The player must balance a good infrastructure, resources, diplomatic and trading skills, technological advancement, city and empire management, culture, and military power to succeed.", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'E - Everyone', 'developers' => [3041], 'genres' => [6], 'publishers' => [72], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 757, 'game_title' => "Deus Ex: Human Revolution - Director's Cut", 'release_date' => '2000-06-26', 'platform' => 1, 'overview' => 'Set in a dystopian world during the 2050s, the central plot follows rookie United Nations Anti-Terrorist Coalition agent JC Denton, as he sets out to combat terrorist forces, which have become increasingly prevalent in a world slipping ever further into chaos. As the plot unfolds, Denton becomes entangled in a deep and ancient conspiracy, encountering fictional versions of organizations such as Majestic 12, the Illuminati, and the Hong Kong Triads throughout his journey.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2685], 'genres' => [1, 4], 'publishers' => [26], 'alternates' => ['Deus Ex Game of the Year Edition'], 'uids' => nil, 'hashes' => nil }, { 'id' => 758, 'game_title' => 'Diablo', 'release_date' => '1996-12-31', 'platform' => 1, 'overview' => 'Set in the fictional Kingdom of Khanduras, located in the world of Sanctuary, Diablo has the player take control of a lone hero battling to rid the world of Diablo, the Lord of Terror. Beneath the town of Tristram, the player journeys through sixteen dungeon levels, ultimately entering Hell itself in order to face Diablo.', 'youtube' => '', 'players' => 1, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [1202], 'genres' => [1, 4], 'publishers' => [47], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 759, 'game_title' => 'Diablo II', 'release_date' => '2000-06-29', 'platform' => 1, 'overview' => "The story of Diablo II takes place some time after the end of the previous game, Diablo, in the lands of Sanctuary. In Diablo the main body of the story takes place beneath the floors of a cathedral in a small town known as Tristram. It is here that Diablo, the Lord of Terror, is defeated by an unnamed warrior after many previous battles are also won.\r\nThe unnamed warrior that vanquished Diablo drove the demon's soulstone into his forehead, in an attempt to contain the monster's essence within his own body. Later in the canon it is suggested that this is what Diablo intended so that, should he be defeated, he had an \"escape plan\" in place of dying.\r\nThe unnamed warrior is ill fated from the moment he does this and is gradually corrupted over the course of the next few days by the demon's spirit. Deckard Cain recounts the story to the next band of adventurers that pass through the Rogue Encampment in Diablo II. It is one of these adventurers that appears in the wake of the destruction caused by the now possessed unnamed warrior, and attempts to find out the cause of the evil, starting with the corrupted warrior (known as the Dark Wanderer throughout Diablo II).", 'youtube' => nil, 'players' => 4, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [1202], 'genres' => [1, 4], 'publishers' => [47], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 760, 'game_title' => 'Doom II', 'release_date' => '1994-09-30', 'platform' => 1, 'overview' => 'Immediately following the events in Doom, the player once again takes the role of the anonymous space marine who has proven too tough to be contained. After being teleported from Phobos, and subsequently fighting on Deimos which is suspended above Hell, the Marine finds himself back home on Earth, only to find that it too has fallen victim to the hellish invasion, leaving billions of people dead.', 'youtube' => 'tt3E7S8me2E', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3993], 'genres' => [1, 8], 'publishers' => [167], 'alternates' => ['Doom II: Hell on Earth'], 'uids' => nil, 'hashes' => nil }, { 'id' => 761, 'game_title' => 'Dungeon Keeper', 'release_date' => '1997-06-26', 'platform' => 1, 'overview' => "Dungeon Keeper is a strategy video game released for the PC in which the player attempts to build and manage a dungeon or lair while protecting it from (computer-controlled) 'hero' characters intent on stealing the user's accumulated treasures and killing various monsters.", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1383], 'genres' => [6], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 762, 'game_title' => 'Dungeon Keeper 2', 'release_date' => '1999-06-30', 'platform' => 1, 'overview' => "Like its predecessor, players take the role of a dungeon keeper, building and defending an underground dungeon from the would-be heroes that invade it, as well as from other keepers. In the game's campaign mode, the player is charged with recovering the portal gems from each area in order to open a portal to the surface.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1383], 'genres' => [6], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 763, 'game_title' => 'The Elder Scrolls IV: Oblivion', 'release_date' => '2006-03-20', 'platform' => 1, 'overview' => "The Emperor has been killed by an unknown assassin and the throne sits empty. With no true Emperor, the gates to Oblivion open, and demons begin to invade Cyrodiil and attack its people and towns. It's up to you to find the lost heir to the throne and unravel the sinister plot that threatens to destroy all of Tamriel.", 'youtube' => 'qJnnPh44Rlo', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1010], 'genres' => [2, 4], 'publishers' => [8], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 764, 'game_title' => 'Escape From Monkey Island', 'release_date' => '2000-11-06', 'platform' => 1, 'overview' => 'The game begins with Guybrush Threepwood and Elaine Marley returning to Mêlée Island from their honeymoon, which they embarked on in the epilogue of The Curse of Monkey Island. Here they find that Elaine has been declared officially dead, her position as governor has been revoked and her mansion is scheduled to be demolished. The governorship is up for election, and suddenly a person known as Charles L. Charles presents himself as the lead candidate. As Elaine begins her campaign to recover her position, Guybrush meets again with three of his old "friends", Meathook, Otis and Carla and heads out to recover the Marley family heirlooms and obtain the legal documents to save her mansion. During his trip, Guybrush learns of the Marley family guarding a secret known as the Ultimate Insult, an insult so insidious, it destroys the spirit of those who hear it. He also winds up being framed for bank robbery by crook Peg-Nosed Pete at the hiring of the Australian Ozzie Mandrill, but manages to prove his innocence.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5068], 'genres' => [2, 5], 'publishers' => [25], 'alternates' => ['Escape from Monkey Island'], 'uids' => nil, 'hashes' => nil }, { 'id' => 765, 'game_title' => 'Homeworld 2', 'release_date' => '2003-09-16', 'platform' => 1, 'overview' => "Homeworld 2 continues the struggle of the Hiigarans and their leader Karan S'jet.\r\nDuring the events of the original game, the Kushan race of the planet Kharak began a quest to discover and reclaim their home planet. The Kushan discovered the wreckage of the Khar-Toba, an interstellar transport, in a desert on Kharak, and inside found a galactic map etched on a piece of stone. From this the Kushan concluded they had been transplanted to Kharak some time ago. To reclaim their home planet—\"Hiigara\"— the Kushan built an enormous self-sufficient Mothership to carry 600,000 people on a crusade to reclaim Hiigara. This led to the engagement and eventual defeat of the Taiidan Empire which exiled them.\r\nThe story continues that some time later, the Khar-Toba was found to contain one of the Three Hyperspace Cores, left behind by a so-called Progenitor race, which eventually allowed hyperspace travel. The First Core was possessed by the Bentusi: a powerful and enigmatic race of traders who assisted the Exiles (the campaign can be played using Kushan or Taiidan craft in the original game) during the first game. The third was lost until approximately one hundred years after the Exiles reclaimed Hiigara, found by a Vaygr Warlord named Makaan, who used it to conquer much of the galaxy and—as of the beginning of Homeworld 2—began attempts to capture Hiigara. The story states that religious beings of the galaxy consider the discovery of the Third Core to announce the End Times, during which Sajuuk, thought to be an immensely powerful being, will return.\r\nThe game begins with the commissioning of a new Mothership, the Pride of Hiigara, similar in shape and design to the original Mothership and commanded by Karan S'jet, as in the original game. The ship is attacked by the Vaygr during the final stages of construction but escapes. The Bentusi inform the Hiigarans that they must find Balcora Gate, left behind by the Progenitors, behind which is something essential for stopping either the Vaygr threat, the End Times, or both. Makaan learns of and reaches the location as well, and the game's penultimate mission takes place on the other side of Balcora Gate, where Hiigarans and Vaygr alike discover an enormous Progenitor starship, named Sajuuk, with sockets for the Three Hyperspace Cores. After defeating Makaan the Hiigarans combine the Vaygr, Hiigaran and Bentusi Cores (recovered from the wreckage of the last of the Bentusi ships) within Sajuuk, and use it to defeat the leaderless-but-still-dangerous Vaygr invasion; Sajuuk is later found to be the key to a galaxy-wide network of hyperspace gates, ushering in a new age of trade and prosperity for all civilized races in the galaxy.", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'T - Teen', 'developers' => [7131], 'genres' => [6], 'publishers' => [32], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 766, 'game_title' => 'Homeworld', 'release_date' => '1999-09-28', 'platform' => 1, 'overview' => "Beneath the scorching sands of Kharak, the Kushan people have discovered the remains of a long-forgotten titanic spaceship. Buried within the ancient remains, the secret of their lost homeworld.\r\nFor thousands of years, the Kushan have survived on the arid planet Kharak, corralled into the temperate geographical poles by a vast, unforgivingly hot desert. Scarcity of arable land and natural resources has coloured Kushan history with near constant inter-clan (or \"Kiith\") warfare.\r\nAs new technologies emerged, religious and political conflict partially gave way to unified scientific exploration. DNA sequencing of Kharak's native life revealed no genetic resemblance to the Kushan, giving rise to their \"XenoGenesis Theory\" - which stated that they were not native to Kharak at all.\r\nThe first space flights reinforced this idea. Small pieces of metallic debris, the largest no bigger than a hand, were retrieved from low orbit and, when analyzed, were found to be made up of materials totally unknown to Kushan metallurgy. In addition to helping accelerate their space technology research, the debris confirmed that a large advanced spacecraft had once been in orbit. It was an ironic twist of fate occurring later in their history that boosted them even further along their development.\r\nA high-powered satellite designed to scan the planetary system malfunctioned upon deployment and ended up facing entirely the wrong way, scanning the Great Desert around Kharak's equator instead. Despite this error, however, it found something, beneath the sands: a derelict city with a massive central metallic structure. An expedition discovered that the central structure was the spacecraft of which they had earlier found traces in orbit. It carried advanced spaceflight technologies including a Hyperspace Core, one of a few ancient machines that were the Homeworld setting's foundation for all faster-than-light technology.\r\nMore importantly however, a stone with a galactic map bearing two coordinates was found. One was recognized as Kharak. The other bore a name so ancient it was common across all their languages and dialects: Hiigara. \"Home\". The stone would become known as the Guidestone, and confirmed the XenoGenesis Theory. Kharak's people united in building the \"Mothership\", a vast colony ship that would bear 600,000 of them to their destination, made rugged and self-sufficient in order to survive possible problems during the long trip. It is during the Mothership's final testing phase that the single-player game begins.", 'youtube' => 'di4NlkpKaGw', 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7131], 'genres' => [6], 'publishers' => [32], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 767, 'game_title' => 'Unreal Tournament', 'release_date' => '1999-11-30', 'platform' => 1, 'overview' => "UT was designed as an arena FPS, with head-to-head multiplayer deathmatches being the primary focus of the game. The game's single-player campaign is essentially a series of arena matches played with bots. For team matches, bots are again used to fill the roles of the player's teammates. Even on dedicated multiplayer servers, bots are sometimes used to pad out teams that are short on players.", 'youtube' => 'sar3_ll2bpM', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2834], 'genres' => [8], 'publishers' => [167], 'alternates' => ['Unreal Tournament Game of the Year Edition'], 'uids' => nil, 'hashes' => nil }, { 'id' => 768, 'game_title' => 'Lost Planet: Extreme Condition', 'release_date' => '2007-06-26', 'platform' => 1, 'overview' => 'Lost Planet begins in the year of T.C. -80 where the Earth has become too hostile for human life. A company named NEVEC (Neo-Venus Construction) tries to start colonization on the planet E.D.N. III. Upon arriving on the planet, NEVEC discovers an alien race called Akrid and are forced off the planet, momentarily stopping colonization efforts. Returning to E.D.N. III with an army prepared to fight, they find that the Akrid contains an energy source called Thermal Energy (T-ENG) that is needed to survive on the planet. NEVEC builds the first Vital Suit (VS), powered by T-ENG, to fight the Akrid. Meanwhile, civilian colonists and E.D.N. III military personnel continue to seek out a nomadic existence as "snow pirates," harvesting T-ENG from fallen Akrid.', 'youtube' => '', 'players' => 1, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [1436], 'genres' => [1, 8], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 769, 'game_title' => 'Far Cry', 'release_date' => '2004-03-23', 'platform' => 1, 'overview' => 'Far Cry is a First-Person Shooter developed by Crytek Studios and published by Ubisoft in 2004. In Far Cry an Ex-U.S. Special Forces operative named Jack Carver runs his own boat charter business in the south pacific after he quit his former job. One day he is contacted to escort a female journalist to a lonesome, tropical archipelago. But shortly after she arrives at the beach, she disappears and Jack nearly gets killed as mercenaries destroy their anchoring boat. Stranded on a remote beach, Jack decides to fight back against the mercenaries and to search for the missing journalist to find some answers. On his vendetta he explores beautiful beaches, dense rain forests, as well as mines, canyons and even volcanic forests to discover disturbing secrets - secrets that were buried in underground complexes and hidden facilities for a long, long time.', 'youtube' => '3pnKAljANsU', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1970], 'genres' => [8], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 770, 'game_title' => 'Far Cry 2', 'release_date' => '2008-10-21', 'platform' => 1, 'overview' => "Far Cry 2 abandons the science fiction aspects of its predecessor in favor of a more realistic setting. The game takes place in late 2008 in a small, failed Central African state, currently embroiled in a civil war. The government has recently collapsed, leaving two factions vying for control. At war are the United Front for Liberation and Labour (UFLL, led by Addi Mbantuwe, a former opposition leader) and the Alliance for Popular Resistance (APR, best far led by Maj. Oliver Tambossa, Chief of Staff for the former government). Both factions have claimed to have the people's interests at heart, but both have shown ruthlessness, warmongering, greed, and a general disregard for the well-being of the people. Both sides have hired many foreign mercenaries to bolster their strength over the course of the conflict. The recent exhaustion of the nation's diamond mines has thrown the nation into further turmoil, leaving many foreign mercenaries without payment and no way out.\r\nThe goal of the player's character is to find and assassinate the Jackal, an arms-dealer who has been selling weapons to both sides of the conflict. The player must accomplish this goal by whatever means necessary, even if he has to reach the level of immorality employed by the warring factions and the Jackal himself.", 'youtube' => 'm-7m4vtn-eM', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9150], 'genres' => [8], 'publishers' => [7], 'alternates' => ["Far Cry 2: Fortune's Edition"], 'uids' => nil, 'hashes' => nil }, { 'id' => 771, 'game_title' => 'SimCity 2000', 'release_date' => '1993-01-01', 'platform' => 1, 'overview' => "SimCity 2000 is the successor to the city simulation game Sim City. You are once again the mayor, but this time you can fully customize the terrain before building your city. The graphics are isometric, whereas the original had graphics displayed in a top-down fashion.\r\n\r\nThis title adds numerous features over the original such as the ability of building \"light\" zones, subways, hospitals, colleges, zoos, and arcos which are actually cities in cities. You can now give names to places, and your city is surrounded by neighboring towns with which you can make trade. Finally, instead of the poll in the first game you now have the option of reading several newspapers to get an idea of your progress.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5322], 'genres' => [3, 6], 'publishers' => [124], 'alternates' => ['SimCity 2000: Special Edition', 'SimCity 2000 CD Collection', 'SimCity 2000: The Ultimate City Simulator'], 'uids' => nil, 'hashes' => nil }, { 'id' => 772, 'game_title' => 'SimCity (1989)', 'release_date' => '1989-02-01', 'platform' => 1, 'overview' => "The player can mark land as being zoned as commercial, industrial, or residential, add buildings, change the tax rate, build a power grid, build transportation systems and take many other actions, in order to enhance the city.\r\nAlso, the player may face disasters including flooding, tornadoes, fires (often from air disasters or even shipwrecks), earthquakes and attacks by monsters. In addition, monsters and tornadoes can trigger train crashes by running into passing trains. Later disasters in the game's sequels included lightning strikes, volcanoes, meteors and attack by extraterrestrial craft.\r\nIn the SNES version and later, one can also build rewards when they are given to them, such as a mayor's mansion, casino, etc.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5322], 'genres' => [3, 6], 'publishers' => [124], 'alternates' => ['Micropolis'], 'uids' => nil, 'hashes' => nil }, { 'id' => 773, 'game_title' => 'SimCity 4', 'release_date' => '2003-01-14', 'platform' => 1, 'overview' => 'The game allows players to create a region of land by terraforming, and then to design and build a settlement which can grow into a city. Players can zone different areas of land as commercial, industrial, or residential development, as well as build and maintain public services, transport and utilities. For the success of a city players must manage its finances, environment, and quality of life for its residents. SimCity 4 introduces night and day cycles and other special effects for the first time in the SimCity series. External tools such as the Building Architect Tool (BAT) allow custom third party buildings and content to be added to the gameplay.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5322], 'genres' => [3, 6], 'publishers' => [2], 'alternates' => ['SimCity 4 Deluxe Edition'], 'uids' => nil, 'hashes' => nil }, { 'id' => 774, 'game_title' => 'SimCity 3000', 'release_date' => '1999-01-31', 'platform' => 1, 'overview' => "SimCity 3000, released in 1999 as the third major installment in the SimCity series, continues its successful course as a city building simulation game. In SimCity 3000 new tools have been introduced to create and control the city build-ups. Recreate the world's greatest cities using predefined landscapes such as San Francisco or Berlin and landmark buildings like the Empire State Building or Big Ben. Negotiate and barter with neighbouring cities to strengthen your metropolis and seal contracts to import water or get rid of huge amounts of waste.", 'youtube' => '_3Cps2AYIK4', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5322], 'genres' => [3], 'publishers' => [2], 'alternates' => ['Sim City 3000', 'SC3K'], 'uids' => nil, 'hashes' => nil }, { 'id' => 775, 'game_title' => 'Freelancer', 'release_date' => '2003-03-04', 'platform' => 1, 'overview' => 'In the game, players take on the roles of spacecraft pilots. These characters fly single-seater ships, exploring the planets and space stations of 48 known star systems. They also engage in dogfights with other pilots (player- and computer-controlled) to protect traders or engage in piracy themselves. Other player activities include bounty-hunting and commodity trading. The single-player mode puts the player in the role of Edison Trent, who goes through a series of missions to save the Sirius sector from a mysterious alien force. In multiplayer mode, players are free to take on any role and to explore anywhere from the start.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2303], 'genres' => [1, 13], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 776, 'game_title' => 'Ground Control', 'release_date' => '2000-06-01', 'platform' => 1, 'overview' => "Ground Control is set in the 25th century. Mankind emerged from the devastation of the Third World War (known in the game as \"The Sixteen-minutes War\", which almost wiped out the whole of humanity) and managed to colonize several planets across the galaxy. The Earth is ruled by a council called GCC (Global Central Command) that is formed by elected representatives and representatives of the mega corporations which rose to power after the fall of the Terran nations.\r\nThe game's plot revolves around the conflict between the Crayven Corporation and the Order of the New Dawn for the possession of the distant world of Krig 7-B. In the beginning of the game, the player assumes the role of Major Sarah Parker of the Crayven Corporation as she leads the Crayven forces in order to eliminate the presence of the \"Dawnies\" (her derogatory nickname in reference to followers of the Order). In the second campaign, the player assumes control of Deacon Jarred Stone in his attempt to drive the \"Crays\" from the surface of Krig 7-B. During the course of the campaign, however, both characters unravel a dark secret hidden within the depths of the planet, a secret that threatens all mankind, and turns out to be the reason for such interest in what seems to be a desolate fringe world.", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'T - Teen', 'developers' => [5293], 'genres' => [6], 'publishers' => [145], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 777, 'game_title' => 'Quake', 'release_date' => '1996-06-22', 'platform' => 1, 'overview' => 'The player takes the role of an un-named protagonist sent into a portal in order to stop an enemy code-named "Quake". Previously, the government had been experimenting with teleportation technology, and upon development of a working prototype called a "Slipgate", this enemy has compromised the human connection with their own teleportation system, using it to insert death squads into the "human" dimension, supposedly in order to test the martial capabilities of humanity.', 'youtube' => '5WzyVjx-SXM', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3993], 'genres' => [8], 'publishers' => [167], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 778, 'game_title' => 'Quake 4', 'release_date' => '2005-10-18', 'platform' => 1, 'overview' => "The Quake 4 single player mode continues the story of Quake II by pitting the player against a cyborg alien race known as the Strogg. The game follows the story of a Marine named Matthew Kane who is a member of the fabled Rhino Squad. Following the success of the protagonist of Quake II in destroying the Strogg's leader, the Makron, the Rhinos are tasked with spearheading the mission to finally secure the aliens' home planet Stroggos. In the course of the invasion, the squad ship is shot down and crashes in the middle of a battle zone, separating Kane from his companions. Kane eventually rejoins his scattered team members and partakes in the assault against the Strogg.", 'youtube' => 'HN0PHBXuEw4', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3993], 'genres' => [8], 'publishers' => [33], 'alternates' => ['Quake IV'], 'uids' => nil, 'hashes' => nil }, { 'id' => 779, 'game_title' => 'Max Payne 2: The Fall of Max Payne', 'release_date' => '2003-10-14', 'platform' => 1, 'overview' => "Two years after the events of the first game, Max Payne has quit his job at the DEA and returned to his former job as an NYPD detective. While investigating a series of murders by a group of contract killers called the Cleaners, Max encounters Mona Sax, who was assumed dead at the end of the previous game. Wanted for the murder of Senator Gates and, despite Max's protests, Mona is arrested and taken to the police station. While at the station, Max overhears his new partner, Detective Valerie Winterson, talking on the phone about Mona. Suddenly, the station is attacked by the Cleaners, who are looking for Mona. Before they reach her, Mona breaks out of her cell and vanishes into the night. After Max meets her again at her residence, where they fight off the Cleaners who followed Max to her place, they begin hunting down the people responsible for the attack. Their search leads them to a construction site, where Max and Mona defend themselves against the Cleaners. After their foes flee, Detective Winterson arrives and holds Mona at gunpoint. Mona claims that Winterson is there to kill her while Winterson claims that she is simply trying to arrest a fleeing fugitive. After several moments of consideration, Max shoots Winterson, allowing Mona to escape. Before she dies, Winterson shoots Max, leading to his hospitalization.", 'youtube' => 'KYT2_Ww6wtM', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7138], 'genres' => [1, 8], 'publishers' => [17], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 780, 'game_title' => 'Max Payne', 'release_date' => '2001-07-23', 'platform' => 1, 'overview' => "The story is told in medias res and consists of three volumes: \"The American Dream\", \"A Cold Day in Hell\", and \"A Bit Closer to Heaven\". The game begins in the winter of 2001, as New York City finishes experiencing the worst blizzard in the history of the city. The intro sequence shows Max Payne, a renegade DEA agent and former NYPD officer, standing at the top of a skyscraper building as police units arrive. He then experiences a flashback from three years ago. Back in 1998, Max returned home to find that a trio of apparent junkies had broken into his house while high on a new designer drug called Valkyr. Max rushed to the aid his family, but was too late and his wife and their newborn daughter had already been brutally murdered. After his family's funeral, Payne transferred to the DEA.\r\nThree years later, Max Payne is employed as an undercover operative inside the Punchinello Mafia family responsible for the trafficking of Valkyr. His DEA colleague B.B. gives Max a message asking him to meet another DEA agent, who is also Max's best friend, Alex Balder, in the NYC Subway station. Max's arrival at the subway results in a shoot-out after he encounters mobsters working for Jack Lupino, a Mafia underboss in the Punchinello crime family, attempting a bank robbery by breaking through from the station. Working his way back to the surface, Max encounters Alex, who is then killed by an unknown assassin and Payne becomes the prime suspect in the murder. Additionally, the Mafia find out that he is a cop and now want him dead.", 'youtube' => 'Pgg3VG7Hug8', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7138], 'genres' => [1, 8], 'publishers' => [168], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 781, 'game_title' => 'Mafia: The City of Lost Heaven', 'release_date' => '2002-08-28', 'platform' => 1, 'overview' => "The game begins with Thomas \"Tommy\" Angelo entering a bar to speak to police Det. Norman. After announcing that he wants to be in the Witness Protection Program, Tommy proceeds to tell the story of how he got involved with a crime family headed by Ennio Salieri, providing the story's main narrative.\r\nWhile working as a cab driver in fictional Lost Heaven in 1930, Tommy picks up two mobsters, Sam and Paulie, who force him to help them lose two mobsters working for Salieri's rival, Don Morello. After losing them and delivering the two to their boss' place, Tommy is rewarded a large amount of money. The next day, while taking a break, Tommy is attacked by the thugs he helped Sam and Paulie escape from. Though he is saved by Salieri's men, he subsequently loses his job. Desperate to make money, Tommy falls in with Salieri's crew and gets involved in all his criminal operations.\r\nOver the next 8 years, Tommy does big jobs for the family, such as murdering other gangsters, entering races, stealing, bootlegging (this is during Prohibition), robbing banks, and property destruction. He slowly rises through the ranks as the jobs get bigger, such as when he has to kill Salieri's double-crossing consigliere. Eventually, the rivalry between Salieri's crew and Morello's crew erupts into a war. This is where Tommy gets his biggest job: assassinating Morello, ending the feud once and for all. During this time, Tommy falls for and marries Sarah, daughter of Salieri's bar's bartender, Luigi, with whom he eventually has a daughter of his own.\r\nTommy's story reaches its climax when, in 1938, he and Paulie (whom, along with Sam, he's become close friends with) learn that Salieri's been smuggling diamonds in secret and keeping the profits for himself. Deciding to get back at him, they rob a bank (Sam refuses). Though the heist is successful, Tommy finds Paulie shot dead the next day. Sam calls Tommy and asks that he meet him at an art gallery. There, he learns that Sam ratted him and Paulie out to Salieri, who ordered their whacking. After a shootout, Tommy manages to kill Sam and several others. He then flees to Europe with his family, but quickly returns to set up the meeting with Norman.\r\nHis story over, Tommy makes his demands: in return for immunity for his past actions and protection, he'll testify against his former comrades. In the trial that ensues, 80 gangsters are tried, most are executed and Salieri gets life in prison. Tommy and his family are put under federal protection and remain safe for 13 years. However, in 1951, his past fatally catches up to him as he is shot dead by two gunman. The game ends with Tommy lamenting in voiceover the mistakes he made, saying that in wanting it all, he eventually lost everything.", 'youtube' => 'qVrLHREBWME', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4078], 'genres' => [4, 8], 'publishers' => [168], 'alternates' => ['Mafia'], 'uids' => nil, 'hashes' => nil }, { 'id' => 782, 'game_title' => 'Return to Castle Wolfenstein', 'release_date' => '2001-11-19', 'platform' => 1, 'overview' => "While investigating the activities of the SS Paranormal Division in Germany, B.J. Blazkowicz and Agent One have been captured by the Nazis. Agent One dies while being interrogated, but B.J. manages to escape Castle Wolfenstein's dungeon. He then fights his way out of the castle and uses a tram car to leave the area and meet up with a member of the German resistance in a nearby village.\r\nThe SS Paranormal Division under Oberführer Helga von Bulow has been excavating the catacombs and crypts of an ancient church within the village. Their sloppy precautions have led to the awakening of hordes of undead creatures, including Saxon knights, and the entrance had to be sealed off with many soldiers trapped inside. B.J. descends regardless and fights both Nazis and Undead until he arrives at the ancient \"Defiled Church\" where Nazi scientist Professor Zemph is conducting a \"life essence extraction\" on the corpse of a Dark Knight. Shortly before B.J.'s arrival, Zemph tries to talk Helga von Bulow out of retrieving an ancient Thulian dagger, but she shoots him impatiently and proceeds. This awakens a monster which kills her too. Blazkowicz fights the monster and is airlifted out, with Zemph's notes and the dagger.\r\nOne of Germany's leading scientific researchers and Head of the SS \"Special Projects Division\", Wilhelm \"Deathshead\" Strasse, is preparing to launch an attack on London using a V-2 rocket fitted with an experimental germ warhead from his base near Katamarunde in the Baltics. Blazkowicz is parachuted some distance from the missile base and smuggles himself in a supply truck. Inside the base, Blazkowicz destroys the V-2 rocket on its launchpad and fights his way out of the facility towards an airbase filled with experimental jet aircraft. There, he commandeers a \"Kobra\" rocket-plane and flies to safety in Malta.", 'youtube' => '3AedXvBXgHw', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3993], 'genres' => [8], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 783, 'game_title' => 'Need for Speed II', 'release_date' => '1997-04-30', 'platform' => 1, 'overview' => 'There are three main game types. The first two are single race and tournament and the last is a knockout race. Single races allow players to become familiar with the circuits and increase their skill of any one of the six tracks. The six tracks are called Mediterranean, Mystic Peaks, Proving Grounds, Outback, North Country, and Pacific Spirit.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2724], 'genres' => [7], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 784, 'game_title' => 'Need for Speed: Undercover', 'release_date' => '2008-11-18', 'platform' => 1, 'overview' => "Undercover features a new open world map consisting of 109 miles (175 km) of road and a large highway system, making it the largest Need for Speed \"world\" EA has created so far. The game's environment consists of four boroughs: Palm Harbor, Port Crescent, Gold Coast Mountains, and Sunset Hills. In the Wii and PS2 versions two boroughs are copied off Need for Speed Most Wanted and put into different positions. These four boroughs make up the city, Tri-City (referring to the real-life city in Tri-City, Oregon), presumably a city located on the Gulf Coast or on the California Coast although the city itself heavily resembles Miami.", 'youtube' => '6gxFZNZPh0E', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2724], 'genres' => [19], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 785, 'game_title' => 'Neverwinter Nights', 'release_date' => '2002-06-18', 'platform' => 1, 'overview' => "Play centers on the development of a character who becomes the ultimate hero of the story. In the original NWN scenario supplied with the game engine, the player is single-handedly responsible for defeating a powerful cult; collecting the four reagents required for stopping an insatiable plague; thwarting an attack on the city of Neverwinter, and many other side quests.\r\nThe first and final chapters of the story in the official campaign deal with the city of Neverwinter itself, but the lengthy mid-story requires the player to venture into the countryside and then northward to the city of Luskan. Neverwinter is a city on the Sword Coast of Faerûn, in the Forgotten Realms campaign setting of Dungeons and Dragons.", 'youtube' => 'aD8BnROvBRc', 'players' => 4, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [1086], 'genres' => [4], 'publishers' => [72], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 786, 'game_title' => 'The Elder Scrolls III: Morrowind', 'release_date' => '2002-05-01', 'platform' => 1, 'overview' => 'Morrowind was released in 2002 by Bethesda as a sequel to Arena & Daggerfall, its much-praised predecessors in the RPG series The Elder Scrolls. While Morrowind contains many quests and storylines, the central plot revolves around the reincarnation of the Dunmer hero Indoril Nerevar. The incarnate of Nerevar, referred to as "The Nerevarine", has been prophesied to oppose and defeat the rise of the malevolent deity Dagoth Ur and the remnants of his followers. These followers are encompassed in a forbidden faction named "The Sixth House", and are mainly located within the volcanic region of Red Mountain in the centre of Vvardenfell, the island on which the game takes place. Dagoth Ur has used the Heart of Lorkhan, an artifact of great power, to make himself immortal and now seeks to drive the Imperial occupiers from Morrowind using his network of spies, as well as an enormous golem, powered by the Heart of Lorkhan, which Dagoth Ur had originally been tasked to guard.', 'youtube' => 'Cr3TCWPlDrw', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1009], 'genres' => [2, 4], 'publishers' => [34], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 787, 'game_title' => 'Empire Earth', 'release_date' => '2001-11-12', 'platform' => 1, 'overview' => 'Epochs are the ages a player passes through in Empire Earth. Each of these epochs represents an age within history. In Empire Earth, the last two ages (Digital and Nano Ages) are set into the moderate future. In the Art of Conquest, a third future age, the Space Age, is available. It deals with space colonization. Each epoch brings new technologies and units. Epoch advancement requires additional buildings to be built and the costs of advancing increases as more epochs are attained, although the ability to gather the required resources greatly increases as well. With new epochs, some new units are available at the cost of having to abandon the ability to produce old units, though any old units still alive are kept. The epochs in Empire Earth are the Prehistoric Age, the Stone Age, the Copper Age, the Bronze age, the Dark Age, the Middle Ages, the Renaissance, the Imperial age, the Industrial age, the Atomic World War I age, the Atomic World War II Age, the Atomic Modern Age, the Digital Age and the Nano Age. An extra epoch, the Space Age, is available in Empire Earth: The Art of Conquest.', 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'T - Teen', 'developers' => [8125], 'genres' => [6], 'publishers' => [32], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 788, 'game_title' => 'Grand Theft Auto III', 'release_date' => '2002-05-21', 'platform' => 1, 'overview' => "The player character has robbed the Liberty City Bank with his girlfriend, Catalina, and a male accomplice. While running from the scene, Catalina turns to him and utters, \"Sorry, babe, I'm an ambitious girl and you ... you're just small-time\". She shoots him and leaves him to die in an alley; the accomplice is also seen lying nearby. It soon becomes apparent that the player character has survived but has been arrested and subsequently found guilty and sentenced to jail. While he is being transferred, an attack on the police convoy aimed at kidnapping an unrelated prisoner sets him free.\r\nWith the help of a fellow escaped prisoner, the player character then takes on work as a local thug and rises in power as he works for multiple rival crime gangs, a corrupt police officer and a media mogul. In the process, Maria, the mistress of a local Mafia boss, begins to take a liking to him. The Mafia leader, Salvatore, grows suspicious and lures the player to a death trap; but Maria saves him, remaining close to him throughout the storyline. He later goes to work for others, including the Liberty City Yakuza and media mogul Donald Love. Eventually, his exploits attract the attention of Catalina, now affiliated with a Colombian drug cartel, resulting in the kidnapping of Maria. This gives him the opportunity to face Catalina once more, which results in a large firefight and Catalina's death.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7279, 10_255], 'genres' => [1, 2, 8], 'publishers' => [17], 'alternates' => ['GTA 3'], 'uids' => nil, 'hashes' => nil }, { 'id' => 789, 'game_title' => 'Grand Theft Auto: Vice City', 'release_date' => '2002-10-27', 'platform' => 1, 'overview' => "The player takes on the role of Tommy Vercetti, a man who was released from prison in 1986 after serving 15 years for killing eleven people. The leader of the organization for whom he used to work, Sonny Forelli, fears that Tommy's presence in Liberty City will heighten tensions and bring unwanted attention upon his organization's criminal activities. To prevent this, Sonny ostensibly \"promotes\" Tommy and sends him to Vice City to act as their buyer for a series of cocaine deals. During Tommy's first meeting with the drug dealers, an ambush by an unknown party results in the death of Tommy's bodyguards, Harry and Lee, and the cocaine dealer. There is another survivor, the pilot of the dealer's helicopter, who flies off and escapes. Tommy narrowly escapes with his life, but he loses both the Forelli's money and the cocaine.", 'youtube' => 'https://www.youtube.com/watch?v=Ag6H1e1rXJ0', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7273], 'genres' => [1, 4, 8, 9], 'publishers' => [17], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 790, 'game_title' => 'Grand Theft Auto: San Andreas', 'release_date' => '2004-10-26', 'platform' => 1, 'overview' => 'Grand Theft Auto: San Andreas is the fifth installment in the GTA series and takes place within the state San Andreas, which is based on sections of California & Nevada. It comprises three major fictional cities: Los Santos corresponds to real-life Los Angeles; San Fierro corresponds to real-life San Francisco; and Las Venturas and the surrounding desert correspond to real-life Las Vegas and the Nevada and Arizona desert.', 'youtube' => 'u_CbHrBbHNQ', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7273], 'genres' => [1, 4, 8, 9], 'publishers' => [17], 'alternates' => ['GTA: San Andreas'], 'uids' => nil, 'hashes' => nil }, { 'id' => 791, 'game_title' => 'Red Faction', 'release_date' => '2001-09-18', 'platform' => 1, 'overview' => 'Red Faction takes place on Mars around the year 2075. Earth’s minerals are being depleted and humans need more of them to survive. The vast Ultor Corporation runs the mining operation on Mars. The living conditions are deplorable, human rights for the miners are few and a disease called "The Plague" is running rampant throughout the colony with no known antidote available - predominantly within the confines of the mine complex. Parker, a downtrodden miner, came to Mars to make a new start in his life - taken in by the promises and advantages Ultor has to offer in the mines of Mars. After a routine day in the mine with the typical aggression toward miners and cramped living conditions and poor nutrition, he witnesses the spark that starts a rebellion when a security guard abuses a miner at the end of his shift and heartlessly kills him. Parker takes up arms, with the help of Hendrix, a rebellious Ultor security technician who guides Parker through the complex. Hendrix tries to get Parker to join up with a group of miners who are about to steal a supply shuttle and escape the complex, but Parker arrives too late. The shuttle takes off, and is destroyed by missiles moments later.', 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'M - Mature', 'developers' => [9487], 'genres' => [8], 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 792, 'game_title' => 'Red Faction II', 'release_date' => '2002-10-15', 'platform' => 1, 'overview' => "In the year 2075, five years after the events of Red Faction, on Mars, the nanotechnology developed by Capek has been claimed by the Earth Defense Force (EDF). With this technology, the EDF commences a reorganization of the Ultor Corporation with a particular focus on enhanced supersoldiers and suitable weaponry. However, the research that was done by Capek in his laboratories has been consequently stolen by other militant groups and assorted terrorist organizations. This has gone on for years; the research has changed hands in the criminal underworld many times. The player is introduced to the role of an explosives expert (codenamed \"Alias\"), as he embarks on a special operations mission to claim the research data for the Republic of the Commonwealth.\r\n\r\nEventually, the research was successfully claimed by the elite forces of Victor Sopot, Chancellor of the dystopic military state known as The Commonwealth. Sopot uses the nanotechnology to enhance his already formidable military forces, and successfully creates the first supersoldiers with the research data. Fearing the potential of his new supersoldiers, he orders them all to be hunted down and executed at once and replaced with far less intelligent, mutated horrors known as \"The Processed\".", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9487], 'genres' => [8], 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 793, 'game_title' => 'Serious Sam', 'release_date' => '2001-12-01', 'platform' => 1, 'overview' => "In ancient times, Earth was involved in a conflict between Mental and the Sirians, an alien race that left many of its artifacts to be found by humanity. In the 22nd century Mental's forces return to Earth hell-bent on eradicating humankind: as a last resort the usage of the \"Time Lock\" is decided: this Sirian device can send back through time a single individual who can, hopefully, defeat Mental and alter the course of history. Because of his bravery in fighting the monsters, Sam \"Serious\" Stone is chosen to use the \"Time Lock\".", 'youtube' => 'JTbwOukQlDY', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1948], 'genres' => [8], 'publishers' => [168], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 794, 'game_title' => 'Serious Sam II', 'release_date' => '2005-10-11', 'platform' => 1, 'overview' => "The game's story picks up shortly after the end of Serious Sam: The Second Encounter, with the hero of the series, Sam \"Serious\" Stone, continuing on his goal to defeat the series' nemesis, Mental. The game begins with Serious Sam being summoned before the Sirian Great Council, where the council asks Sam to defeat Mental and provides him with guidance on how to accomplish this feat. The council reveals to Sam that he must collect five pieces of an ancient medallion, each held by various groups on five different planets, and states that once Sam has the entire medallion, Mental will be vulnerable. All the planets (except Kleer) are populated by friendly, big headed humanoids. The problem is that all the planets are under Mental's control. Sam has to visit five planets in order to recreate the medallion.", 'youtube' => '0FZq3wE_FFs', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1948], 'genres' => [8], 'publishers' => [8], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 795, 'game_title' => 'S.T.A.L.K.E.R.: Shadow of Chernobyl', 'release_date' => '2007-03-20', 'platform' => 1, 'overview' => 'The game begins with an unconscious, wounded stalker (the player character) being brought to Sidorovich, a black-market trader operating inside the Zone of alienation (or simply "The Zone"). Sid is able to save his life, but the wounded stalker is amnesic; the only clues to his identity are a tattoo on his arm of the acronym "S.T.A.L.K.E.R." and his PDA which contains only one entry in the to-do list: "Kill Strelok." The amnesiac stalker is dubbed "Marked One" by Sid.', 'youtube' => 'exGOtsiS0tw', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3645], 'genres' => [1, 8], 'publishers' => [40], 'alternates' => ['S.T.A.L.K.E.R.: Тень Ð§ÐµÑ€Ð½Ð¾Ð±Ñ‹Ð»Ñ (RU)'], 'uids' => nil, 'hashes' => nil }, { 'id' => 796, 'game_title' => 'Star Wars: Republic Commando', 'release_date' => '2005-03-01', 'platform' => 1, 'overview' => 'The game is set during the events of the Clone Wars that started at the climax of the movie Star Wars Episode II: Attack of the Clones. In the game, the player is expected to take command of a Clone commando team, made up of elite Clone troopers. These "clone commandos" have been specially bred at the clone factories on Kamino. The commando team will travel to various locations in the Star Wars universe, including Kashyyyk, Geonosis, and the derelict spacecraft, The Prosecutor.', 'youtube' => 'rsH8LAb-5qQ', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5068], 'genres' => [8], 'publishers' => [25], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 797, 'game_title' => 'Tribes: Vengeance', 'release_date' => nil, 'platform' => 1, 'overview' => "Set hundreds of years before the events of Starsiege: Tribes, Vengeance depicts the birth of the growing Tribal War. It focuses on the events surrounding five different characters over the course of two generations and how they each contribute to the developing war. The story (\"The Past\") begins with a Phoenix sub-clan leader named Daniel abducting the soon to be Queen, Princess Victoria. He takes her to his home world to show her the injustices done to his people and the two eventually fall in love. During this time, a cybrid assassin named Mercury is hired by an unknown contractor to eliminate Daniel, but the contract is canceled moments before the shot is fired. Eventually, Victoria and Daniel try to make amends between the Imperials and the Phoenix, but it all ends disastrously when the Phoenix's enemies, the Blood Eagle tribe, stage a raid on a Phoenix base disguised as Imperial troops. In rage, Daniel kills the Imperial King, Tiberius, whom Victoria avenges by killing Daniel. It turns out that Victoria was pregnant with Daniel's child, who was born female under the name Julia soon afterwards.", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'T - Teen', 'developers' => [4357], 'genres' => [8], 'publishers' => [169], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 798, 'game_title' => 'Unreal Tournament III', 'release_date' => '2007-11-19', 'platform' => 1, 'overview' => 'Similarly to the previous entries of the series, the game is primarily an online multiplayer title offering several game modes, including large-scale Warfare, Capture-the-Flag, and Death match. It also includes an extensive offline single-player game with an in-depth story, beginning with a simple tournament ladder and including team members with unique personalities.', 'youtube' => 'if6Vv-5AlHs', 'players' => 16, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2834], 'genres' => [1, 8], 'publishers' => [41], 'alternates' => ['Unreal Tournament 3 Black Edition'], 'uids' => nil, 'hashes' => nil }, { 'id' => 799, 'game_title' => 'Unreal Tournament 2003', 'release_date' => '2002-09-30', 'platform' => 1, 'overview' => "In 2291, consensual murder is legalized, opening the way for a previously underground event. Smaller mining companies have been running smaller matches to channel aggression, but now the Liandri Mining Corporation established a professional league, which quickly proves to be an extremely lucrative way of public entertainment. Liandri entered into the Tournament, as it is officially called, sponsoring their own team, the Corrupt. The Corrupt's leader, Xan Kriegor, quickly achieved champion status and held it for two years. In 2293, a human named Malcolm dethroned him and became champion himself. A huge media figure, Malcolm is hailed as the biggest star in human history and is worshipped as a god. His success nets great rewards for his sponsoring corporation, attracting the attention of jealous rivals both in the arenas of the Tournament and in the corridors of power a galaxy away. Liandri attempted to win back the champion title with Xan MK2 but failed (unknown to the other contestants, each member of the Corrupt is purely robotic, including Xan).\r\nNow it is 2302. The Tournament is undergoing a massive overhaul. The aging Sniper Rifle (a relic of centuries past) is removed from the Tournament as is \"Assault\" - a team-based event that forms a part of the competition. Many fans of the Tournament complain at these changes, with some combatants refusing to participate in the new format. Malcolm, shortly after his victory, hired two of his former opponents (Brock and Lauren, members of the former Iron Guard team) as teammates in his reformed Thunder Crash team. But the Axon Research Corporation, another of the four great corporations, entered the Tournament as well, sponsoring the geneboosted Juggernaut team, led by the brutal and savage Gorge.", 'youtube' => '3vGqfNXV3HM', 'players' => 16, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2834], 'genres' => [8, 14], 'publishers' => [506], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 800, 'game_title' => 'Unreal Tournament 2004', 'release_date' => '2004-03-16', 'platform' => 1, 'overview' => 'Among significant changes to gameplay mechanics and visual presentation, one of the major additions introduced by Unreal Tournament 2004 is the inclusion of vehicles and the Onslaught game type, allowing for large-scale battles.', 'youtube' => '', 'players' => 16, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2834], 'genres' => [8, 14], 'publishers' => [506], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 801, 'game_title' => 'Warcraft II: Tides of Darkness', 'release_date' => '1995-12-09', 'platform' => 1, 'overview' => "Players must collect resources, and produce buildings and units in order to defeat an opponent in combat on the ground, in the air and in some maps at sea. The more advanced combat units are produced at the same buildings as the basic units but also need the assistance of other buildings, or must be produced at buildings that have prerequisite buildings. The majority of the main screen shows the part of the territory on which the gamer is currently operating, and the minimap can select another location to appear in the larger display. The fog of war completely hides all territory which the gamer's has not explored, and shows only terrain but hides opponents' units and buildings if none of the gamer's units are present.", 'youtube' => 'https://www.youtube.com/watch?v=rFCWKRW5HDI', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1203], 'genres' => [6], 'publishers' => [47], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 802, 'game_title' => 'Warcraft III: Reign of Chaos', 'release_date' => '2002-07-03', 'platform' => 1, 'overview' => "Warcraft III, released in 2002 as the third installment in Blizzards Warcraft series, takes place in the fictional world of Azeroth. Several years before the events of the games, a demon army known as the Burning Legion intent on Azeroth's destruction corrupted a race called the Orcs, and sent them through a portal to attack Azeroth. After many years of fighting, the Orcs were defeated by a coalition of humans, dwarves and elves known as the Alliance; the surviving combatants were herded into internment camps, where they seemed to lose their lust for battle. With no common enemy, a period of peace followed, but the Alliance began to fracture. The events of Warcraft III occur after a timeskip from Warcraft II. This period was originally intended to have been documented in Warcraft Adventures, but that game was canceled in mid-development.", 'youtube' => '', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1203], 'genres' => [6], 'publishers' => [47], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 803, 'game_title' => 'Warcraft III: The Frozen Throne', 'release_date' => '2003-07-01', 'platform' => 1, 'overview' => "Illidan Stormrage has gained the allegiance of the Naga, former Night Elves who were magically mutated during The Sundering, and became strange, reptilian creatures. The Warden Maiev Shadowsong pursues her former prisoner, Illidan, across the sea, first to the Tomb of Sargeras. However, Illidan gains an artifact known as the 'Eye Of Sargeras' and wipes out some of Maiev's best soldiers. Forced to call for help, she sends a messenger back to the mainland of Kalimdor. She asks the assistance of Malfurion Stormrage and Tyrande Whisperwind, but Maiev holds a grudge against Tyrande for her actions in releasing Illidan. Although they are able to chase Illidan to Lordaeron, while helping the Blood Elven prince Kael'Thas, Tyrande delays the advance on an Undead army that causes her to be swept away downriver: upon their reunion, Maiev lied to Malfurion, claiming Tyrande was killed in order to prevent Illidan's escape. Malfurion and Maiev prevent Illidan from using the artifact called the Eye of Sargeras, defeat his army and condemn him to death. Illidan tries to justify his actions by saying his plan was to use the Eye to destroy the Icecrown Glacier and kill the Lich King, thereby destroying their common enemy in the Undead, but Malfurion accuses Illidan of having indirectly causing Tyrande's death. Kael'thas then informs him Tyrande may have survived; Maiev's treachery comes out, and the brothers Stormrage join forces to save Tyrande. At this point, Kael'Thas supposedly takes a few more days to meet up with the human forces in the city of Dalaran, the exact same city in which they stopped Illidan. Malfurion then pardons Illidan after they save Tyrande, though he does not revoke his exile. Illidan then states that he could not join the Night Elves even if Malfurion did permit it, because his master will be enraged by his failure to use the Eye properly, and will hunt him down. Illidan departs for Outland, followed by Maiev. It seems as though Maiev would chase Illidan to the depths of the world, as she would do so. Malfurion then remarks that she has become 'vengeance itself'.", 'youtube' => '', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1203], 'genres' => [6], 'publishers' => [47], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 804, 'game_title' => 'Warhammer 40,000: Dawn of War', 'release_date' => '2004-09-20', 'platform' => 1, 'overview' => "Warhammer 40,000: Dawn of War is a military science fiction real-time strategy video game developed by Relic Entertainment based on Games Workshop's popular tabletop wargame Warhammer 40,000. It was released by THQ on September 20, 2004 in North America. Since its release, three expansion packs have been released: Winter Assault in 2005, Dark Crusade in 2006, and Soulstorm in 2008. The sequel, Dawn of War II was released in February 2009.\r\n\r\nThe Game of the Year edition was released on September 21, 2005 in the USA and on September 23 in Europe, containing 4 exclusive maps. Later, the Game of the Year edition and Winter Assault were bundled in the Gold Edition in the USA, released in March 2006. In November 2006, Dawn of War and its first two expansions were released together as The Platinum Collection in the USA or as the Dawn of War Anthology in the PAL regions. More recently, in March 2008, all three expansions along with Dawn of War have been released as The Complete Collection.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7131], 'genres' => [6], 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 805, 'game_title' => 'Warcraft: Orcs & Humans', 'release_date' => '1994-01-15', 'platform' => 1, 'overview' => "The Orcs originated from another world, where the majority were bloodthirsty warriors driven by strife. However, their Warlocks remained aloof, devoted to the research of magic. The Warlocks noticed a rift between the dimensions and, after many years, opened a small portal to another world. One Warlock explored and found a region, whose Human inhabitants called it \"Azeroth\", from which the Warlock returned with strange plants as evidence of his discovery.\r\n\r\nThe Orcs enlarged the portal until they could transport seven warriors, who massacred a Human village. The platoon brought back samples of good food and fine workmanship, and a report that the Humans were defenseless. The Orcs' raiding parties grew larger and bolder, until they assaulted Azeroth's principal castle. However, the Humans had been training warriors of their own, especially the mounted, heavily-armed Knights. These, assisted by Human Sorcerors, gradually forced the Orcs to retreat through the portal, which the Humans had not discovered.\r\n\r\nFor the next fifteen years, one faction of Orcs demanded that the portal be closed. However a chief of exceptional cunning realized that the Humans, although out-numbered, had prevailed through the use of superior tactics, organization, and by magic. He united the clans, imposed discipline on their army and sought new magics from the Warlocks and Necromancers. Their combined forces were ready to overthrow the Humans.", 'youtube' => 'https://www.youtube.com/watch?v=mPvPT9wDLvQ', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1203], 'genres' => [6], 'publishers' => [47], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 806, 'game_title' => 'Warhammer 40,000: Dawn of War - Dark Crusade', 'release_date' => '2006-10-09', 'platform' => 1, 'overview' => 'As with previous Dawn of War titles, Dark Crusade is focused on the conflict part of gameplay; in order to obtain more resources players must fight over them. Each player starts off with a base and wins by fulfilling mission objectives. There are multiple tiers of technology, with each allowing for more powerful units and upgrades.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7131], 'genres' => [6], 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 807, 'game_title' => 'Fable II', 'release_date' => '2008-10-21', 'platform' => 15, 'overview' => 'Fableâ„¢ II is the true sequel to the wildly successful original that sold more than 3 million copies, offering even more choices and building on the core gameplay theme of "Fable," where a player’s every decision continually defines whom they become. "Fable II" is an action role-playing game (RPG) that truly allows players to live the life they choose in an unimaginably open world environment. Set 500 years after the original, "Fable II" will provide gamers with an epic story and innovative real-time gameplay, including a massive amount of freedom and choice to explore a vast collection of dungeons, catacombs and caves in the world of Albion.', 'youtube' => '5pouqKKjh_M', 'players' => 1, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [4989], 'genres' => [1, 2, 4], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 808, 'game_title' => 'Empire: Total War', 'release_date' => '2009-03-03', 'platform' => 1, 'overview' => "Empire: Total War is set in the 18th century, a turbulent era that is the most requested by Total War's loyal fan base and a period alive with global conflict, revolutionary fervour and technological advances. The game features themes such as the Industrial Revolution, America's struggle for independence, the race to control Eastern trade routes and the globalisation of war on land and sea. Empire: Total War sees the debut of 3D naval combat within the Total War franchise. PC Gamers intuitively command vast fleets or single ships upon seascapes rich with extraordinary water and weather effects that play a huge role in your eventual glorious success or ignominious defeat. After pummelling your enemy with cannon fire, close in to grapple their ship and prepare to board taking control your men as they fight hand to hand on the decks. Empire: Total War also sees further enhancements to the Total War series signature 3D battles and turn based campaign map. Real time battles pose new challenges with the addition of cannon and musket, challenging players to master new formations and tactics as a result of the increasing role of gunpowder within warfare. And the Campaign Map - for many the heart of Total War - will see new improved systems for Trade, Diplomacy and Espionage with agents, a refined and streamlined UI, improved Advisors and extended scope taking in the riches of India, the turbulence of Europe and the untapped potential of North America.", 'youtube' => nil, 'players' => 4, 'coop' => nil, 'rating' => 'T - Teen', 'developers' => [1891], 'genres' => [6], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 809, 'game_title' => 'LittleBigPlanet', 'release_date' => '2008-10-27', 'platform' => 12, 'overview' => "If you were to stand on LittleBigPlanet and try to imagine a more astounding, fantastic, and creative place, full of enthralling adventure, uncanny characters, and brilliant things to do... you couldn’t. All imagination is here, and what you do with it all is entirely up to you.\r\n\r\nBuild new levels and expand the environment, collect the many and varied tools and objects to make your mark on this world, or just simply enjoy the people and puzzles they’ve set.\r\n\r\nLittleBigPlanet is the manifested embodiment of your perfect dream world...", 'youtube' => 'QlRNggZoInE', 'players' => 4, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [5352], 'genres' => [5, 12, 15], 'publishers' => [19], 'alternates' => ['Little Big Planet', 'LBP', 'LittleBIGPlanet', 'Little BIG Planet'], 'uids' => nil, 'hashes' => nil }, { 'id' => 810, 'game_title' => 'Gran Turismo 5', 'release_date' => '2010-11-24', 'platform' => 12, 'overview' => 'Gran Turismo 5 is the fifth edition of the Gran Turismo sim racing video game series. It is the first game in the franchise to provide a damage model, with variations of damage depending on whether a vehicle is a "Standard" or "Premium" car. The game also features weather effects, however they are only available on certain circuits. Optional Stereoscopic-3D resolution and Karting found a place in the game.Furthermore, new visual effects have been introduced, including dynamic skid marks, dust and the ability for drivers to flash their headlights. A course editor which allows the player to create new circuits by using tools that randomly generate track-parts according to certain player-selected specifications, including the number of corners, the time of day and the number of sectors. There are a variety of themes the player can choose from to act as a base for each circuit design. Themes also have an effect on track length and highest elevation.', 'youtube' => 'l2uQ2ayvvWY', 'players' => 6, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6739], 'genres' => [7], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 811, 'game_title' => 'Kane & Lynch: Dead Men', 'release_date' => '2007-11-14', 'platform' => 1, 'overview' => "In campaign mode the player controls Kane. The player is accompanied by Lynch, and sometimes other hired mercenaries. Co-op mode is available, in which the second player controls Lynch. Though almost identical to Kane's style of gameplay, Lynch has short bursts of aggression in which hallucinates nearly all AI characters are police, some sporting an animal's head. Lynch carries a shotgun and a revolver as side arm, while Kane carries an assault rifle and standard pistol, though it is possible to swap weapons. Additional weapons such as grenades, sniper rifles and carbines can be picked up, which can be swapped between allies. The player can take cover by standing next to a wall, and can blindfire. While having hired mercenaries, the player can issue orders such as follow, move to a specific position, or attack.", 'youtube' => 'tfMBFpPbHDc', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4320], 'genres' => [8], 'publishers' => [26], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 812, 'game_title' => 'Lost Empire: Immortals', 'release_date' => '2008-03-11', 'platform' => 1, 'overview' => 'Developed by the Danish studio Pollux Gamelabs, Lost Empire: Immortals, is an in-depth 4X game with thousands of stars to explore and colonize. 6 playable races battle to dominate a vast empire, either against a challenging AI or in multiplayer over the Internet.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6728], 'genres' => [6], 'publishers' => [170], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 814, 'game_title' => 'Vampire Rain', 'release_date' => '2007-07-03', 'platform' => 15, 'overview' => "Vampire Rain (ヴァンパイアレイン Vanpaia Rein) is a survival horror stealth video game developed by Artoon. It was released for the Xbox 360 in Japan on January 25, 2007 and in North America on July 3, 2007. The game was later ported to the PlayStation 3 under the title Vampire Rain: Altered Species and was released in Japan on August 21, 2008 and in North America on September 2, 2008.\r\nCome face to face with the ultimate, most intense enemies ever seen on the Xbox 360. You are a part of a Special Forces team tasked with removing the Nightwalkers in all their gore and supernatural strength before they overrun the world - and before the public finds out about them.", 'youtube' => '', 'players' => 8, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [681], 'genres' => [1, 2, 16], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 815, 'game_title' => 'inFamous', 'release_date' => '2009-05-26', 'platform' => 12, 'overview' => "In Infamous, the player controls the protagonist Cole MacGrath, a bike messenger caught in the center of an explosion that devastates several city blocks of the fictional Empire City. The explosion sends the city into chaos while Cole finds himself with new electricity-based super powers. Though the game's story follows Cole using his new abilities to restore some semblance of order to Empire City, the player is given several opportunities to use these powers for good or evil purposes in the game's Karma system. These choices ultimately affect character growth, the reaction of the City's populace towards Cole, and finer elements of gameplay and the story.", 'youtube' => 'nJSNJDn4Puc', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8302], 'genres' => [1, 2, 12], 'publishers' => [38], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 816, 'game_title' => 'The Saboteur', 'release_date' => '2009-12-09', 'platform' => 12, 'overview' => "The player is able to explore Nazi-occupied Paris, some of the French countryside and parts of Germany.[3] Color is a key element in the gameplay. Areas which are heavily controlled by the Nazis are represented in black and white, with the exception of the irises of characters' eyes, city lights, blue symbols of the French Resistance, and various German symbols, which are bright red and complete with swastikas. In order to make that district colored (\"inspired\") again, players must weaken the German forces occupying the area. In doing so, that district's citizens regain their hope, visually represented by making the area vibrant and full of color. This also affects gameplay; in black and white areas, German soldiers are present in large numbers, making it far more likely that Sean will be detected in his rebellious activities.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [6398], 'genres' => [1, 2], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 817, 'game_title' => 'Wolfenstein', 'release_date' => '2009-08-18', 'platform' => 1, 'overview' => "Wolfenstein is a story driven first-person shooter. The story is told through cutscenes, scripted events, telegraph messages, and intelligence that the player finds scattered throughout the game. The game involves the main character, B.J. Blazkowicz, going to a fictional German town called Isenstadt, which serves as \"hub\" for the player throughout the game. Isenstadt is where the player can get missions from two different groups, or upgrade their weapons and powers at the Black Market.\r\n\r\nAside from the weapons, the player also finds a medallion called the \"Thule Medallion\". With it, the player can get many abilities. The abilities are Veil Sight (the ability to see secrets, and, once upgraded, through walls), Mire (the ability to slow down time), Shield (the ability to throw up a shield that blocks, and, once upgraded, bounces back bullets), and Empower (the ability to significantly increase the damage of the player's weapons).\r\n\r\nEvery time the player activates the Medallion, the player enters a dimension called the \"Veil\", which is a barrier between this dimension and the fictional \"Black Sun\" dimension, the occult power source the Nazis want to master. Inside the Veil, the player can see floating creatures called \"geists\". Geists can be destroyed, and destroying them releases an energy burst which can kill or stun nearby enemies. Geists are usually passive, but if the player kills one, others can become angry and attack the player in a suicidal explosion.\r\n\r\nVarious items can be collected throughout the game: Gold, Intelligence, and Tomes of Power. Gold is used as currency to buy various upgrades from the Black Market. Intelligence provides some background information about the story, and is used to unlock some of the upgrades for weapons. Tomes of Power are used to upgrade the Veil Powers.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7006], 'genres' => [1, 8], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 818, 'game_title' => 'Dynasty Warriors: Gundam', 'release_date' => '2007-08-28', 'platform' => 12, 'overview' => "Dynasty Warriors: Gundam, originally released in Japan as Gundam Musou (ã‚¬ãƒ³ãƒ€ãƒ ç„¡åŒ Gandamu MusÅ?), is a video game based on the Gundam anime series. It was developed by Omega Force and published by Bandai Namco Games. Its gameplay is derived from Koei's popular Dynasty Warriors and Samurai Warriors series.[1] The \"Official Mode\" of the game is based primarily on the Universal Century timeline, with mecha from Mobile Suit Gundam, Mobile Suit Zeta Gundam, and Mobile Suit Gundam ZZ appearing in the game,[2] as well as a few units from Mobile Suit Variations Mobile Suit Gundam 0080: War in the Pocket and Mobile Suit Gundam 0083: Stardust Memory appearing as non-playable ally and enemy units. The \"Original Mode\" of the game also features mecha from the non-UC series Mobile Fighter G Gundam, Mobile Suit Gundam Wing and ∀ Gundam. A newly designed non-SD Musha Gundam designed by Hajime Katoki is also included.[3]\r\n\r\nThe game was originally released on March 1, 2007 in Japan[4] exclusively for the PlayStation 3 with the name Gundam Musou. A North American version was released on August 28, 2007, for both the PlayStation 3 and the Xbox 360 under the name Dynasty Warriors: Gundam [5] with English localization by AltJapan Co., Ltd.[6] Dynasty Warriors: Gundam is the second next-gen Gundam game released in North America, following Mobile Suit Gundam: Crossfire. A Japanese Xbox 360 version was released in Japan on October 25, 2007 under the name of Gundam Musou International. Unlike the Japanese PlayStation 3 edition, Gundam Musou International features both Japanese and English voice overs.\r\n\r\nAn expanded port for PlayStation 2 called Gundam Musou Special was released on February 28, 2008 in Japan, featuring new scenarios and mobile suits.[7]", 'youtube' => '1SgAWzVny8E', 'players' => 2, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [4738, 6242], 'genres' => [1, 4, 10], 'publishers' => [6], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 819, 'game_title' => 'Neo Steam: The Shattered Continent', 'release_date' => '2009-06-11', 'platform' => 1, 'overview' => nil, 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => nil, 'genres' => nil, 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 820, 'game_title' => 'Overlord II', 'release_date' => '2009-06-23', 'platform' => 1, 'overview' => "Overlord II is the sequel to the warped fantasy action adventure that had players being delightfully despotic. In Overlord II, a new Overlord and a more powerful army of Minions take on an entire empire in a truly epic adventure, inspired by the rise of the Roman Empire. As the Glorious Empire conquers kingdoms and destroys any sign of magic it finds, it's time to go Minion Maximus and send in the horde. The Minions return smarter, deadlier (and funnier) and are ready to fight in large scale battles that will see their wild pack mentality squaring up to the organised legions of the Glorious Empire. As ever, they'll do anything and everything the Overlord commands of them, especially now that they can run ravage and wreck buildings and scenery. They've also learned how to ride: In Overlord II Minions mount up and ride wolves and other magical creatures around the landscape and take them into battle, making our band of merry fighters faster and fiercer than ever before.", 'youtube' => 'g6fqAKD2DGA', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9065], 'genres' => [1], 'publishers' => [16], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 821, 'game_title' => 'World in Conflict: Soviet Assault', 'release_date' => '2009-03-11', 'platform' => 1, 'overview' => nil, 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5293], 'genres' => [6], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 822, 'game_title' => 'Kingdom Under Fire II', 'release_date' => '2013-06-30', 'platform' => 1, 'overview' => "Kingdom Under Fire II is a video game set in a high fantasy setting developed by Blueside which merge real-time strategy (RTS), role-playing game (RPG) and massively multiplayer online game (MMO) genres - the game is to have a single player, and online multiplayer mode. The game follows on chronologically from Kingdom Under Fire: Circle of Doom, and is the first RTS game set in the Kingdom Under Fire universe to be released since the 2005 Kingdom Under Fire: Heroes.\r\n\r\nThe game was announced in January 2008, and has been subject to delay and changes to release platforms; A closed beta-test began on December 2011 in South Korea.\r\n\r\nIn November 2013, the developers announced that a version for the PlayStation 4 was in development.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => nil, 'genres' => nil, 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 823, 'game_title' => 'Legend of Mir 3', 'release_date' => '2005-01-01', 'platform' => 1, 'overview' => nil, 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => nil, 'genres' => nil, 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 824, 'game_title' => 'Red Steel 2', 'release_date' => '2010-03-23', 'platform' => 9, 'overview' => "The game begins as an unnamed Hero, the last member of the Kusagari Clan, is being dragged across the desert, tied to the back of a motorcycle. He manages to break free, but Payne, the leader of the Jackals - a vast gang of thugs, murderers and thieves - steals the Hero's katana. While running from the Jackals, the Hero rescues his old swordsmaster Jian who was to soon be executed by the Jackals. After the rescue, Jian allows the Hero to borrow his sword until the Hero can recover his own from Payne.", 'youtube' => 'https://www.youtube.com/watch?v=DWutufIWx_4', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9150], 'genres' => [1, 8], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 825, 'game_title' => 'Split/Second', 'release_date' => '2010-05-21', 'platform' => 1, 'overview' => 'You have made the cut to join a group of elite drivers chosen to participate in the global broadcast event known as Split/Second. Racing through a city created specifically for destruction, your goal is to become the season champ where fame, fortune and glory await. But first, you must survive a grueling 24-episode season of races in a variety of explosive locations to crush the competition and become the champion. When speed is not enough, the city is your weapon.', 'youtube' => 'WpnUzI04_1s', 'players' => 1, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [1161], 'genres' => [7], 'publishers' => [171], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 826, 'game_title' => 'Dead Rising 2', 'release_date' => '2010-09-28', 'platform' => 1, 'overview' => "Several years have passed since the Wilamette incident, and Dead Rising 2 shifts the action from the everyday world of mid-West America to the glitz and glamour of Fortune City, America's latest and greatest entertainment playground. People flock to Fortune City from around the globe to escape from reality and the chance to win big and for some, this means competing in Terror is Reality.\r\n\r\nLike millions of Americans, former national motocross champion Chuck Greene is gripped by the TV sensation that is Terror is Reality. Hosted by the flamboyant Tyrone King, Terror is Reality pits ordinary members of the public against an arena full of zombies with a simple challenge – kill more zombies than your opponents and stay alive with the winner collecting big money and the chance to come back and secure even greater prizes. So, what is it that has forced Chuck to come to Fortune City and risk his life in the modern day gladiatorial contest, is he trying to recapture the fame of his motocross days, does he have a reason to hate zombies, or is it simply the lure of big money?", 'youtube' => 'ZYooJsLi31Y', 'players' => 2, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [1221], 'genres' => [1, 2], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 827, 'game_title' => 'Resident Evil: The Darkside Chronicles', 'release_date' => '2009-11-17', 'platform' => 9, 'overview' => "The Darkside Chronicles is an on-rails shooting game. In the Resident Evil series it is the second title exclusive to the Wii platform. The game's plot revolves around the personal stories and tragedies in the series, with its main focus on retelling the events of Resident Evil 2 and Resident Evil: Code: Veronica.\r\n\r\nA new chapter called Operation Javier fleshes out the plot further and explains the motives of Resident Evil 4 villain Jack Krauser. It takes place in 2002 and is set in the waterside village of Mixcoatl, located in the South American Amparo. It tells the story of Leon S. Kennedy teaming up with Jack Krauser to investigate the connections of crime lord Javier Hidalgo to a former Umbrella researcher.\r\n\r\nJust like The Umbrella Chronicles players do not control the character's movement, but only the shooting aspect, shown from a first-person perspective. The player's partner is also shown on the screen and there is an cooperative option for two players.", 'youtube' => 'WKGUO972E1A', 'players' => 2, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [1436], 'genres' => [8], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 828, 'game_title' => 'R.U.S.E.', 'release_date' => '2010-09-07', 'platform' => 1, 'overview' => "Developed by Eugen Systems, R.U.S.E is the first strategy game where your ability to deceive and manipulate your enemies determines your nation's fate. Lead your army to victory by camouflaging your troops, luring your opponent with decoy units, sabotaging enemy logistics and much more. Strategy has never been so intuitive and deep. R.U.S.E features cutting edge graphics and effects, the incredible IRISZOOM Engine, immersive combat and a simplified interface that allows you to determine your nation's strategy and fight to defeat your enemies.", 'youtube' => nil, 'players' => 4, 'coop' => nil, 'rating' => 'T - Teen', 'developers' => [2882], 'genres' => [6], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 829, 'game_title' => 'Damnation', 'release_date' => '2009-05-26', 'platform' => 1, 'overview' => "Damnation is a third-person shooter set in a steampunk-universe with the player taking over the control of Rourke, fighting through hordes and hordes of enemies as well as jumping from roof to roof and other climbing exercises in order to accomplish his objectives like freeing a prisoner or shutting down a factory. On his side the Indian healer Yakecan and the cowboy Ramon Sepherius Zagato. Of course the enemies don't just drop dead by the sight of Rourke and his friends. Instead everyone can carry around three weapons. Two big ones like a shotgun, grenade launcher or sniper rifle and one pistol which also includes gear like the railroad-spike-gun. In addition the players have access to trip-mines that can either be thrown or planted but always have to be triggered manually. Since the levels are huge and traveling on foot sometimes is either not feasible or possible, steampunk bikes stand ready for the players to be used in two different designs. The small version carries two persons with one being the driver and the second one standing on the back shooting everything in sight. The second version allows for two gunners on the back.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1228], 'genres' => [8], 'publishers' => [16], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 830, 'game_title' => 'Medieval II: Total War: Kingdoms', 'release_date' => '2007-08-28', 'platform' => 1, 'overview' => 'Medieval II: Total War Kingdoms is the official expansion to Medieval II: Total War, presenting players with all-new territories to explore, troops to command, and enemies to conquer. Kingdoms features four new entire campaigns centered on expanded maps of the British Isles, Teutonic Northern Europe, the Middle East, and the Americas. All-new factions from the New World are also now fully playable, including the Aztecs, Apaches, and Mayans.', 'youtube' => nil, 'players' => 1, 'coop' => nil, 'rating' => 'T - Teen', 'developers' => [1891], 'genres' => [6], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 831, 'game_title' => 'Painkiller: Overdose', 'release_date' => '2007-10-26', 'platform' => 1, 'overview' => nil, 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => nil, 'genres' => [8], 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 832, 'game_title' => 'Pirates of the Caribbean: The Legend of Jack Sparrow', 'release_date' => '2003-06-30', 'platform' => 1, 'overview' => "Pirates of the Caribbean is a 2003 video game for Microsoft Windows and Xbox, developed by Akella and published by Bethesda Softworks. The Xbox version was the first U.S. console game developed in Russia. A PlayStation 2 version was also originally in development, but was later canceled.\r\n\r\nAn unrelated game by the same name was also released for mobile phones, as was a Game Boy Advance game.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => nil, 'genres' => nil, 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 833, 'game_title' => 'Siren: Blood Curse', 'release_date' => '2008-07-24', 'platform' => 12, 'overview' => "A TV crew from America arrive to research and film an exposé on the urban myth of Hanuda, the Vanished Village, where human sacrifices are said to have taken place.\r\n\r\nHanuda is a dark, eerie world, frozen in the 1970s and surrounded by a red sea. An ancient curse has been set upon the town and you, as the visitors, must save the remaining inhabitants including the beautiful Miyako. In order to survive you must defend yourself from the vicious Shibito, or living dead, and other terrifying monsters.\r\n\r\nAcross 12 chapters of horror, gamers will confront the mysteries of Hanuda in this new chapter of the the cult classic horror game. Throughout the game you will play each of the visitors to the village. The game's unique Sight-Jack System enables you to switch seamlessly between the visions of the hunted and the hunters. Blood, guts and gore are super-enhanced by amazing graphic effects, an advanced physics engine and shockingly realistic facial animations.", 'youtube' => 'PRGX5Tbj1WQ', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4441], 'genres' => [18], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 834, 'game_title' => 'Too Human', 'release_date' => '2008-08-19', 'platform' => 15, 'overview' => 'As the Cybernetic God Baldur, you get thrust into the midst of an ongoing battle that threatens the existence of mankind. An ancient machine presence has forced the Gods hand. In the first of a three part trilogy, Baldur is charged with defending mankind from an onslaught of monstrous war machines bent on eradication of human life. It takes more than brawn and raw strength to supplant the machine hordes. Utilize a sophisticated blend of seamless melee and firearms combat to vanquish foes close and far. Feel each punishing blow through advanced visual effects. Intuitive combat provides new level of accessibility: Perform Baldurs elaborate and complex combat maneuvers through the press of a button and chain together rapid-fire combos with ease. Through the use of an intuitive combat system, Too Human provides gameplay that is easy to learn and rewarding to master and introduces combinations of weapons combat on a high level. The story chronicles the ongoing struggle between Cybernetic gods, machine giants and mortal men on a massive scale never before seen. Play the role of a cybernetic god charged with protecting the human race against a relentless onslaught of machines.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7735], 'genres' => [1, 2], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 835, 'game_title' => 'Blur', 'release_date' => '2010-05-25', 'platform' => 1, 'overview' => "In Blur's career mode, the player will encounter numerous characters and many licensed cars ranging from Dodge Vipers to Lotus Exiges to Ford Transit vans fitted with F1 engines, all of which have full damage modeling and separate traits such as Acceleration, Speed, Drift, Grip and Stability. Some special car models have been designed by Bizarre Creations themselves. There are also some heavily altered versions of familiar urban environments, such as the Los Angeles river halfpipe and several parts of London. These areas were altered to make the races more enjoyable instead of the developers having to strictly abide by each twist and turn. Depending on the character(s) the player races against or tags along with in team races, they will have their own racing styles, power-up set ups, match types, locales, cars and will be apart of certain fictional servers. As the player races well, performs stunts and uses power-ups in certain ways during races, the player will gain 'fan points'. These points help the player progress through the career, purchase more cars and parts and earn more fans for the user base. During the career, challenges will take place midrace when the player drives through a fan icon. Completing these short challenges (e.g. find a secret nitro power-up) will reward the player with a fan points boost.\r\n\r\nGame provides split screen for multi player", 'youtube' => 'L88zX6qfj4Y', 'players' => 1, 'coop' => 'Yes', 'rating' => 'E10+ - Everyone 10+', 'developers' => [1131], 'genres' => [7], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 836, 'game_title' => 'Call of Juarez: Bound in Blood', 'release_date' => '2009-06-30', 'platform' => 1, 'overview' => 'The story begins with Ray and Thomas pointing their guns at each other. William laments on how things degenerated between them to the point of them becoming mortal enemies. Flash to several years ago, Ray and Thomas are fighting in the American Civil War. After they defeat the enemy, they are ordered to retreat to Jonesboro. They refuse, deserting their posts to save their home from Union troops. When they arrive, they find their mother dead. Ray promises to rebuild their house, and knowing their superior Colonel Barnsby will not let them off, they flee, taking their young brother, William, with them.', 'youtube' => 'zE4xc124Wjs', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [8593], 'genres' => [8], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 837, 'game_title' => 'Ghostbusters: The Video Game', 'release_date' => '2009-06-16', 'platform' => 1, 'overview' => "Who ya gonna call?\r\nThe game is a third-person shooter, placing players in the role of an original character simply known as \"Rookie\" (also called 'Rook', 'Newbie' and similar names by the Ghostbusters), a new recruit to the Ghostbusters team. Players control Rookie's movements as he explores the environments of each level, seeking out paranormal activities and ghosts, either alone or with up to all four of the other Ghostbusters. Players can switch to a first-person perspective by equipping the Rookie with the PKE Meter and goggles. In this mode, paranormal items are highlighted and the PKE Meter will help direct players to ghosts or haunted artifacts. Players can scan these elements to gain more information about them and receive a monetary reward. Weapons cannot be used in this mode.", 'youtube' => 'LyVGSGynYpg', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8670], 'genres' => [1], 'publishers' => [506], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 838, 'game_title' => 'Forza Motorsport 3', 'release_date' => '2009-10-27', 'platform' => 15, 'overview' => 'Forza Motorsport 3 is a racing video game developed for Xbox 360 by Turn 10 Studios. It was released in October 2009. It is the sequel to Forza Motorsport 2 and the third installment in the Forza Motorsport series. The game includes more than 400 customizable cars (More than 500 cars in the Ultimate Collection version) from 50 manufacturers and more than 100 race track variations with the ability to race up to eight cars on track at a time. These cars vary from production cars to race cars such as those from the American Le Mans Series.[1]', 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9106], 'genres' => [7], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 839, 'game_title' => 'Dirge of Cerberus: Final Fantasy VII', 'release_date' => '2006-08-15', 'platform' => 11, 'overview' => "WHEN MIDGAR DIED, SOMETHING SURVIVED.\r\n\r\nFrom the ashes of Meteorfall, a mysterious organisation has arisen. Between it and the domination of this shattered world stands an unlikely champion, the enigmatic Vincent Valentine. Taking place one year after the events of FINAL FANTASY VII ADVENT CHILDREN, this wholly new chapter in the FINAL FANTASY VII saga features familiar faces and cutting edge gunfighting action. The fate of the world will be decided in a storm of bullets!", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2808], 'genres' => [1, 2], 'publishers' => [12], 'alternates' => nil, 'uids' => [{ 'uid' => 'SLPM-66271', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SLUS-21419', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 840, 'game_title' => "Tom Clancy's Splinter Cell: Conviction", 'release_date' => '2010-04-27', 'platform' => 1, 'overview' => 'Taking place three years after the events of Splinter Cell: Double Agent, former Navy SEAL Victor Coste is held in a Black Arrow facility interrogation room as he is interviewed by an unidentified group of men. Victor begins to recount the events of Splinter Cell: Conviction in the past tense. This continues throughout the game, with each level being narrated in the past tense as the player "experiences" what happened.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9150], 'genres' => [1], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 841, 'game_title' => 'The Conduit', 'release_date' => '2009-06-23', 'platform' => 9, 'overview' => "In The Conduit, you'll find yourself at the center of a thrilling battle involving aliens, secret agents and centuries-old government conspiracies, all set against the backdrop of modern-day Washington, D.C. Built from the ground up for the Wii, the game pits you against ruthless, wily enemies who react to your moves and use the environment to their own advantage. Tailor the game to suit your personal style, and see the game's intense visuals burst to life complete with dynamic environment mapping, interactive water with real-time reflection and four-stage texture composition. Gather up to 11 additional players online for brutal multiplayer action, and incorporate the Wii Speak peripheral to enhance the immediacy of the battle.\r\n\r\nAlso Available\r\nSpecial Edition\r\n\r\nUnlockable Secret Agent Multiplayer Skin\r\nUnique All Seeing Eye Device With Custom Detailing\r\nExclusive concept art book with development insights into the world of \"The Conduit\"\r\nCompatible with Wii Speak (Sold separately)", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [3837], 'genres' => [8], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 842, 'game_title' => 'Wanted: Weapons of Fate', 'release_date' => '2009-03-24', 'platform' => 1, 'overview' => 'For centuries, a secret fraternity of assassins has brutally executed kill orders dictated by the Loom of Fate. Your destiny is to become their ultimate weapon. Kicking into action where the hit film, WANTED, left off, you are Wesley Gibson an uber assassin and heir to a legacy of power, hunted by a renegade faction of The Fraternity. Master an arsenal of deadly skills to protect the secrets of your killer coalition ... or blow them all away!', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3630], 'genres' => [1, 8], 'publishers' => [152], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 843, 'game_title' => 'God of War III', 'release_date' => '2010-03-16', 'platform' => 12, 'overview' => "God of War III is a third-person action-adventure video game developed by Santa Monica Studio and published by Sony Computer Entertainment (SCE). First released for the PlayStation 3 (PS3) console on March 16, 2010, the game is the fifth installment in the God of War series, the seventh and final chronologically, and the sequel to God of War and God of War II. Loosely based on Greek mythology, the game is set in Ancient Greece with vengeance as its central motif. The player controls the protagonist, Kratos, the former God of War, after his betrayal by his father Zeus, the King of the Olympian Gods. Reigniting the Great War, Kratos ascends Mount Olympus with his initial allies, the Titans, until he is abandoned by Gaia. Now guided by the spirit of Athena to search for the Flame of Olympus, Kratos battles monsters, gods, and Titans in a search for Pandora, the key to pacifying the Flame surrounding Pandora's Box, and to defeat Zeus. Successful, Kratos kills Zeus and ends the reign of the Olympian God", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7435], 'genres' => [1], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 844, 'game_title' => "Tom Clancy's EndWar", 'release_date' => '2009-02-24', 'platform' => 1, 'overview' => "Tom Clancy's EndWar is a real-time tactics game designed by Ubisoft Shanghai for the PlayStation 3, Xbox 360 and Windows platforms. The Nintendo DS and PlayStation Portable versions feature turn-based tactics instead of the real-time tactics of their console counterparts.[4] It was released on November 4, 2008 in the United States, November 6, 2008 in Canada, and November 8, 2008 in Europe.[2] A Windows version was released on February 24, 2009.[5]", 'youtube' => '8Bd9eZ9Z7Qc', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9176], 'genres' => [6], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 845, 'game_title' => 'Need for Speed: Shift', 'release_date' => '2009-09-15', 'platform' => 1, 'overview' => "Aimed at a hardcore gamer-style audience, Shift reverts to the touring-car simulation style of its 2007 predecessor, NFS ProStreet. Although the gameplay of these two titles are similar, Shift recreates car handling much more realistically than ProStreet, and does not contain a story. Upon starting the career mode, the player must do a lap of the track to decide on car settings. Once completed, the player is welcomed to the 'NFS Live World Series', and must earn stars in races to earn money, and unlock new races.", 'youtube' => 'VfXOAc9xSy8', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7845], 'genres' => [7, 11], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 846, 'game_title' => 'Brütal Legend', 'release_date' => '2009-10-13', 'platform' => 15, 'overview' => 'Brütal Legend is an epic action game from visionary developer Tim Schafer. Jack Black stars as Eddie Riggs, a legendary roadie summoned to a world of Heavy Metal where mountains are made of amplifiers, killer spiders spin guitar strings and Rock Legends roam the landscape. As Eddie, crush skulls with a battle axe, ravage the road in a super-charged Hot Rod and unleash the power of Rock to reign down fire from the sky - all to save humanity and become a Brütal Legend. ', 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2456], 'genres' => [1, 6], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 847, 'game_title' => 'Halo Wars', 'release_date' => '2009-03-03', 'platform' => 15, 'overview' => 'The year is 2531, twenty years prior to the events in Halo: Combat Evolved and the Covenant have found something on the planet Garvest. The UNSC ship "Spirit of Fire" is sent to investigate and stop whatever the enemy is up to. What the crew finds could be the only thing that stands between humanity and certain annihilation by the Covenant. Command large armies, lead them into battle, control their every move and use their abilities to gain the upper hand in combat.', 'youtube' => '', 'players' => 6, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [2817], 'genres' => [6], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 848, 'game_title' => 'Tekken 6', 'release_date' => '2009-10-27', 'platform' => 12, 'overview' => "Tekken 6 features bigger stages with more interactivity than its predecessors, such as walls or floors that can be broken to reveal new fighting areas. The character customization feature has been enhanced, and certain items have implications in some aspects of gameplay.\r\nA new \"rage\" system has been added, giving characters more damage per hit when their vitality is below a certain point. Once activated, a reddish energy aura appears around the character, and their health bar starts to flicker in red. The rage aura can be customized with different colors and effects to appear like fire, electricity, ice, among others. Another gameplay feature added is the \"bound\" system. Every character has several moves that, when used on an opponent that is currently midair in a juggle combo, will cause the opponent to be smashed hard into the ground, bouncing them off the floor in a stunned state and leaving them vulnerable to another combo or additional attack. As of the Bloodline Rebellion update, successfully parrying a low attack will also put a character into a bound state.", 'youtube' => 'cS0O-o9qY9I', 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [902], 'genres' => [10], 'publishers' => [6], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 849, 'game_title' => 'Section 8', 'release_date' => '2009-09-04', 'platform' => 1, 'overview' => 'Section 8 is an intense first-person shooter that gives players unprecedented strategic control over the battlefield, employing tactical assets and on-demand vehicle deliveries to dynamically alter the flow of combat. Set at the crossroads of a growing insurrection among its colonies, Earth dispatches the elite 8th Armored Infantry to turn the tide. Utilizing advanced powered armor suits, these brave volunteers are the only ones crazy enough to smash through enemy defenses and drop directly into the battlefield from 15,000 feet, earning them the nickname "Section 8."', 'youtube' => '8Zxi0PqkbJE', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8858], 'genres' => [8], 'publishers' => [67], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 850, 'game_title' => 'Prince of Persia: Warrior Within', 'release_date' => '2004-11-30', 'platform' => 1, 'overview' => "Seven years after the events of Prince of Persia: The Sands of Time, the Prince finds himself constantly hunted by a terrible beast known as the Dahaka. The Prince seeks counsel from an old wise man who explains that whoever releases the Sands of Time must die. Because the Prince escaped his fate, it is the Dahaka's mission as guardian of the Timeline to ensure that he dies as he was meant to. The old man also tells of the Island of Time, where the Empress of Time first created the Sands. The Prince sets sail for the Island in an attempt to prevent the Sands from ever being created, an act he believes will appease the Dahaka. After a battle at sea with an enemy force led by a mysterious woman in black capsizes the Prince's ship, the Prince washes ashore unconsciously onto the Island of Time.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9150], 'genres' => [1, 2], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 851, 'game_title' => 'Watchmen: The End Is Nigh', 'release_date' => '2009-07-21', 'platform' => 1, 'overview' => "The game allows players to take on the roles of either Rorschach or Nite Owl II in single player or cooperative multiplayer. Rorschach and Nite Owl are the only playable characters in the game's first episode, which comprises six \"chapters.\" Cutscenes that look like animated comic panels, similar to those seen in the Watchmen motion comics released on iTunes, bookend each chapter. Two of the film's actors, Patrick Wilson and Jackie Earle Haley, provide their voices for their characters Nite Owl and Rorschach, respectively. The game features a mix of beat-em-up and puzzle gameplay, with the two characters having different strengths and abilities. Rorschach is faster with unconventional attacks and makes use of improvised weapons like crowbars and baseball bats; Nite Owl is slower but has a solid martial arts method and uses technological devices, such as \"screecher bombs\", and the grappling gun. The characters must work cooperatively to pass puzzles and defeat enemies.", 'youtube' => nil, 'players' => 2, 'coop' => nil, 'rating' => 'M - Mature', 'developers' => [2191], 'genres' => [1, 10], 'publishers' => [152], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 852, 'game_title' => 'DiRT 2', 'release_date' => '2009-12-08', 'platform' => 1, 'overview' => 'Following on the success of the original Dirt as well as a decade of videogame development in partnership with the late Colin McRae, DiRT 2 explores various disciplines of off-road racing. Dirt 2 features a roster of contemporary off-road events, taking players to the most diverse and challenging real-world environments. This World Tour has players competing in aggressive multi-car and intense solo races at extraordinary new locations, from canyon racing and jungle trails to city stadium-based events.', 'youtube' => '', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1726], 'genres' => [7], 'publishers' => [16], 'alternates' => ['Colin McRae: DiRT 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 853, 'game_title' => 'The Witcher', 'release_date' => '2007-10-30', 'platform' => 1, 'overview' => 'Become The Witcher, Geralt, a legendary monster slayer caught in a web of intrigue woven by forces vying for control of the world. Make difficult decisions and live with the consequences in a game that will immerse you in an extraordinary tale like no other.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1532], 'genres' => [4], 'publishers' => [506], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 854, 'game_title' => "Demon's Souls", 'release_date' => '2009-10-06', 'platform' => 12, 'overview' => "King Allant the XII, the last king of Boletaria, searched tirelessly to expand his might. The Nexus, a great ice shrine nestled in the mountains, bestowed the power of the souls onto him, bringing prosperity to his kingdom. Still unsated, he returned again to the Nexus, where he foolishly awakened the Old One from its eternal slumber. This long forgotten evil, now wrought upon Boletaria, plunged the realm into darkness and fog. A mighty demon horde poured into the kingdom, devouring the souls of men. Champions from other realms learned of Boletaria's fate and sought to deliver the kingdom from evil; none would return from the cursed land. Called upon by a mysterious maiden in black, you go forth, the last hope for humanity in a place lost to demons and darkness...", 'youtube' => 'FRnIyXvonAU', 'players' => 3, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [3192], 'genres' => [1, 4], 'publishers' => [58], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 855, 'game_title' => 'Left 4 Dead 2', 'release_date' => '2009-11-16', 'platform' => 1, 'overview' => "Set in the zombie apocalypse, Left 4 Dead 2 (L4D2) is the highly anticipated sequel to the award-winning Left 4 Dead, the #1 co-op game of 2008.\r\n\r\nThis co-operative action horror FPS takes you and your friends through the cities, swamps and cemeteries of the Deep South, from Savannah to New Orleans across five expansive campaigns.\r\n\r\nYou'll play as one of four new survivors armed with a wide and devastating array of classic and upgraded weapons. In addition to firearms, you'll also get a chance to take out some aggression on infected with a variety of carnage-creating melee weapons, from chainsaws to axes and even the deadly frying pan.\r\n\r\nYou'll be putting these weapons to the test against (or playing as in Versus) three horrific and formidable new Special Infected. You'll also encounter five new “uncommon†common infected, including the terrifying Mudmen.\r\n\r\nHelping to take L4D's frantic, action-packed gameplay to the next level is AI Director 2.0. This improved Director has the ability to procedurally change the weather you'll fight through and the pathways you'll take, in addition to tailoring the enemy population, effects, and sounds to match your performance. L4D2 promises a satisfying and uniquely challenging experience every time the game is played, custom-fitted to your style of play.", 'youtube' => 'y0sJ5s7fUMQ?hd=1', 'players' => 4, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [9289], 'genres' => [1, 8, 18], 'publishers' => [13], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 856, 'game_title' => 'Combat Arms', 'release_date' => '2008-07-11', 'platform' => 1, 'overview' => "Combat Arms uses a player ranking system based on total experience, using common military ranks that players can obtain. Completing objectives, killing other players, and levelling up one's rank gives the player money in the form of Gear Points (GP), which can be used to purchase new equipment. Equipment includes weaponry, weapon attachments, and accessories for one's character.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2439], 'genres' => [1], 'publishers' => [174], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 857, 'game_title' => 'Silent Hunter 5: Battle of the Atlantic', 'release_date' => '2010-03-02', 'platform' => 1, 'overview' => 'Silent Hunter 5: Battle of the Atlantic is a submarine simulator for Microsoft Windows developed by Ubisoft Romania and published by Ubisoft. It is the fifth and latest installment of the Silent Hunter franchise and the successor of Silent Hunter 4: Wolves of the Pacific. Like Silent Hunter II and Silent Hunter III, it places the player in command of a German U-Boat during World War II, here the Battle of the Atlantic.', 'youtube' => 'I6wvDzClVNc', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => nil, 'genres' => nil, 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 858, 'game_title' => 'MotorStorm: Arctic Edge', 'release_date' => '2009-10-20', 'platform' => 11, 'overview' => "Motorstorm: Arctic Edge is an arcade racer pitting you against 8 other racers, human or AI in a competition to win in The Festival. The backdrop for the game is Alaska where you have to race on icy tracks in mountainous regions. Beside the other racers you have to take into account avalanches, broken ice bridges and a lot of other dangers on the route to victory.\r\n\r\nThe game is very fast-paced and it sees you racing around in cars, snowmobiles and trucks. You can select different wheels, exhausts, spoilers and more for your vehicles.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1058], 'genres' => [7], 'publishers' => [21], 'alternates' => nil, 'uids' => [{ 'uid' => 'SCUS-97654', 'games_uids_patterns_id' => 2 }, { 'uid' => 'SCES-55573', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 859, 'game_title' => 'Prince of Persia: The Two Thrones', 'release_date' => '2005-12-01', 'platform' => 1, 'overview' => "Prince of Persia: The Two Thrones follows the second ending of Prince of Persia: Warrior Within, in which the Prince kills the Dahaka, essentially saving Kaileena. The game opens with the Prince and Kaileena about to sail into Babylon's port. Kaileena offers narration of the events passed and the story following, similar to the Prince's role as both protagonist and narrator in The Sands of Time.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9150], 'genres' => [1], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 860, 'game_title' => 'Champions Online', 'release_date' => '2009-09-01', 'platform' => 1, 'overview' => 'Champions Online is a Massively Multiplayer Online game based on the pen & paper role-playing universe of Champions. As such, the world tries to loosely recreate the official HERO System ruleset. Compared to other MMOs, at the beginning of the character creation process you are asked to choose from a series of power frameworks, instead of classes. These will determine what powers you can use. It is even possible to combine them in the Custom Framework option. Your abilities are determined by eight characteristics: Strength, Dexterity, Constitution, Intelligence, Ego, Presence, Recovery and Endurance.', 'youtube' => '', 'players' => 16, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1959], 'genres' => [4, 14], 'publishers' => [506], 'alternates' => ['Champions Online: Free for All'], 'uids' => nil, 'hashes' => nil }, { 'id' => 861, 'game_title' => 'Guild Wars 2', 'release_date' => '2012-08-28', 'platform' => 1, 'overview' => "For generations, war and chaos raged across the land of Tyria. Five great races competed and warred against each other, struggling to tip the balance of power in their favor.\r\n\r\nThen the dragons woke.\r\n\r\nThe all-powerful beasts stirred from their millennial sleep under earth and sea. With their magical breath the dragons spread destruction and created legions of twisted slaves. A deathless dragon named Zhaitan raised the sunken nation of Orr, triggering earthquakes and tidal waves that destroyed entire cities across the Sea of Sorrows. Zhaitan's undead armies surged from the sea, hungry for the destruction of the five races of Tyria: the charr, a ferocious race of feline warriors; the asura, magical inventors of small size and great intellect; the norn, towering shapeshifters from the frigid northern lands; the sylvari, a mysterious young race of visionary plant folk; and the humans, an embattled but resilient people.\r\n\r\nNow heroes from the five races must set aside ancient rivalries and stand together against their common enemies in the sequel to the hit MMO Guild Wars. Magic, technology, and cold steel will determine the ultimate fate of the world.", 'youtube' => 'o4R5Q0ZOTa8', 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [609], 'genres' => [4, 14], 'publishers' => [18], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 862, 'game_title' => 'Castlevania: Lords of Shadow', 'release_date' => '2010-10-05', 'platform' => 12, 'overview' => "Gabriel Belmont learns of a mask with the power to raise the dead and sets out on a mission to obtain it to bring his recently murdered wife back from the dead.\r\n\r\nLords of Shadow builds upon the combat systems first explored in this series in 2003's Lament of Innocence and adds more violent kills to the mix. Inspiration for these changes seems to have come from 2005's God of War.", 'youtube' => 'RGAy6jrRUaY', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [5388], 'genres' => [1, 2, 18], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 863, 'game_title' => 'Dissidia: Final Fantasy', 'release_date' => '2009-08-25', 'platform' => 13, 'overview' => "Cosmos, the goddess of harmony. Chaos, the god of discord. Reigning from distant realms, the two gods had gathered warriors from all lands to lead them in savage war. Cosmos and Chaos were of equal strength. It was believed the conflict would last forever. However, the balance is now broken. Those who answered Chaos's call created an inexhaustible force. And under vicious attack without relent, the warriors fighting for Cosmos started to fall one by one. The conflict that has continued for eons is now about to end in Chaos's favor. The world has been torn asunder, sinking into a vortex of disorder. As for the few surviving warriors- their fates have yet to be determined.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2808], 'genres' => [4, 10], 'publishers' => [12], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 864, 'game_title' => 'Singularity', 'release_date' => '2010-06-25', 'platform' => 1, 'overview' => "Singularity takes place on a fictional island known as Katorga-12, where Russian experiments involving Element 99 took place during the height of the Cold War. In 1955, a catastrophe involving experiments attempting to form a \"Singularity\" occurred on the island, causing the island's existence to be covered up by the Russian government.", 'youtube' => 'pNQqY7VznJM', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7006], 'genres' => [8], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 865, 'game_title' => 'Star Wars: Knights of the Old Republic', 'release_date' => '2003-11-19', 'platform' => 1, 'overview' => "The story of this game takes place 4,000 years before the rise of the Galactic Empire. \r\nDarth Malak, a Dark Lord of the Sith and Darth Revan's former apprentice, has unleashed a Sith armada against the Republic. \r\nMalak's aggression has left the Jedi scattered and vulnerable; many Jedi Knights have fallen in battle and others have sworn allegiance to Malak and Revan.", 'youtube' => 'xqUqrv6t4HM', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1086], 'genres' => [4], 'publishers' => [25], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 866, 'game_title' => 'Star Wars: Knights of the Old Republic II - The Sith Lords', 'release_date' => '2005-02-08', 'platform' => 1, 'overview' => "The game takes place five years after the events of Knights of the Old Republic, in a time when the Jedi have been nearly exterminated by the Sith. The player's character, a former Jedi Knight exiled from the Jedi Order, is referred to as \"the Exile\" or \"Jedi Exile.\" \r\nThroughout the game, the player's character (canonically a female) restores a connection to the Force while, with the help of non-player character companions, trying to stop the Sith. The player makes choices that turn the Exile to either the dark side or light side of the Force, and travels to six planets to either help or hinder the Republic's efforts to bring peace and stability to the galaxy.", 'youtube' => '2ff0ziipxLg', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6195], 'genres' => [1, 4], 'publishers' => [25], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 867, 'game_title' => 'Dragon Age: Origins', 'release_date' => '2009-11-03', 'platform' => 1, 'overview' => "Dragon Age: Origins is an epic story of magic, danger and a fight for survival told by a legendary games company. BioWare, creators of Mass Effect, Baldur's Gate and Star Wars: Knights Of The Old Republic, bring you their best adventure yet. As a Grey Warden, you protect the land of Ferelden from the Darkspawn. When the demons attack the land again, you must embark on an epic quest to save Ferelden. Create your hero with detailed customisation options, make real choices that affect your path and the future of Ferelden itself, and decide how to battle the forces against you. Dragon Age: Origins is a bigger, more beautiful and deeper adventure than any you'll have ever taken before.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1086], 'genres' => [1, 2, 4], 'publishers' => [2], 'alternates' => ['Dragon Age Origins', 'Dragon Age'], 'uids' => nil, 'hashes' => nil }, { 'id' => 868, 'game_title' => 'Velvet Assassin', 'release_date' => '2009-04-30', 'platform' => 15, 'overview' => "Violette Summer managed to carry out several missions successfully before being gravely wounded by a sniper on a mission to kill Kamm, a Nazi military intelligence officer. Comatose in a hospital in France, Violette relives key moments in a series of flashbacks. \r\nHence the bulk of gameplay will take place during these flashbacks. The missions include blowing up a fuel depot on the Maginot Line, assassination of a colonel in a cathedral in Paris, stealing documents and marking a sub pen for bombers in Hamburg during Operation Gomorrah, and finding three secret agents in Warsaw.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7153], 'genres' => [1, 8], 'publishers' => [67], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 869, 'game_title' => 'Breath of Fire', 'release_date' => '1994-08-01', 'platform' => 6, 'overview' => "NOW YOU'RE PLAYING WITH FIRE!\r\nIn a distant land, peace was maintained for thousands of years by a fearful dragon clan who could transform into powerful monsters. One day they discovered a goddess who could fulfill their every wish. Greed split the clan into Dark and Light Dragons, each battling the other to win her magic.\r\n\r\nOne member of the Light Dragons, along with seven of his companions, emerged to keep the opposing forces from destroying their world. Using six magical keys, they sealed the goddess into another realm.\r\n\r\nCenturies have passed. The Dark Dragons are destroying the land in search of the keys. When they find the keys, they will once again release the magic goddess. Light Dragon... the time has come to draw your sword and fight for the future of your people.", 'youtube' => 'jg9agVIPMhI', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [4], 'publishers' => [11], 'alternates' => ['Breath of Fire Ryuu no Senshi'], 'uids' => nil, 'hashes' => nil }, { 'id' => 870, 'game_title' => 'Breath of Fire II', 'release_date' => '1995-12-03', 'platform' => 6, 'overview' => "The incredible sequel to the best-selling RPG hit Breath of Fire is here! You are the last member of the Dragon clan, fighting to rid the world of a growing evil. A cast of unusual and exciting companions joins you in your adventures across a wondrous land full of magic and mystery. You'll find strange mystic items, memorable monsters and exotic locations in your quest to conquer evil. There's strategy and spellcasting galore in the hours of compelling action and adventure that awaits you. Breath of Fire II is the ultimate in RPG excitement!", 'youtube' => 'HehkHHMhh3s', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [4], 'publishers' => [9], 'alternates' => ['Breath of Fire 2', 'Breath of Fire II Shimei no Ko', 'Breath of Fire 2 Shimei no Ko'], 'uids' => nil, 'hashes' => nil }, { 'id' => 871, 'game_title' => 'Trine', 'release_date' => '2009-07-02', 'platform' => 1, 'overview' => "Trine takes place in a forsaken and ruined kingdom. After enjoying a period of great peace, the king died without leaving an heir, plunging the kingdom into political instability. Taking advantage of the chaos, an undead army suddenly appeared and attacked, forcing the inhabitants to abandon the realm.\r\nAfter an unspecified amount of time, Trine begins with a thief searching for a legendary treasure in the Astral Academy, a derelict institution of magical studies. Unknown to her, a wizard remained at the academy to study the skies, while a knight arrived there to protect the academy. The three meet at the chamber of the ancient treasure and, touching the object at the same time, disappear.", 'youtube' => 'https://SgFxIopLANU&feature=player_embedded', 'players' => 3, 'coop' => 'Yes', 'rating' => 'E10+ - Everyone 10+', 'developers' => [3206], 'genres' => [4, 5, 15], 'publishers' => [175], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 872, 'game_title' => 'Fable III', 'release_date' => '2010-10-26', 'platform' => 15, 'overview' => "Set 50 years after the events of Fable II, the continent of Albion (where the Fable series is set) is under the control of Logan, a tyrant king and the Hero's older brother. The player's character, the \"Hero\", is forced into a quest to become a revolutionary leader to defeat Logan after he reveals his true personality to the Hero. Over the course of the first half of the game, the Hero will overthrow Logan and become ruler of Albion themselves. During the second half of the game, a strange force from Aurora, called The Darkness will threaten Albion and the player has to decide how to react to it.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4989], 'genres' => [4], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 873, 'game_title' => "Tom Clancy's Splinter Cell: Chaos Theory", 'release_date' => '2005-03-21', 'platform' => 1, 'overview' => 'The game follows the covert activities of Sam Fisher, an agent working for a black-ops branch within the NSA called "Third Echelon".', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9150], 'genres' => [1], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 874, 'game_title' => 'Afro Samurai', 'release_date' => '2009-01-27', 'platform' => 15, 'overview' => "The quest for #1 comes to the Xbox 360! Afro Samurai is an action-adventure game featuring never before seen combat mechanics, stunning visuals, and an amazing cast of characters creating a brutally fresh entertainment experience. Afro Samurai utilizes a dynamic cross-hatching art style and cut-scene paneling that makes the game look like a comic come to life while its innovative combat system gives players the ability to dynamically cut enemies at any point in the body. Starring Samuel L. Jackson & featuring a hip-hop musical score produced by The RZA of Wu-Tang clan fame, Afro Samurai blends contemporary street and Japanese culture in the stylish world reated by Takashi Okazaki and animated by revered animation studio, Gonzo. Follow the epic tale of Afro Samurai as he seeks vengeance against Justice, who murdered his father. Nothing personal... It's just revenge.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [8371], 'genres' => [1], 'publishers' => [39], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 875, 'game_title' => 'Lego Indiana Jones: The Original Adventures', 'release_date' => '2011-05-13', 'platform' => 1, 'overview' => "The game allows players to recreate moments (albeit more humorously) from the first three Indiana Jones films: Indiana Jones and the Raiders of the Lost Ark, Indiana Jones and the Temple of Doom, and Indiana Jones and the Last Crusade.\r\n\r\nHowever, the developers modified the storylines to fit the events into 6 game chapters per movie. Barnett College, Dr. Indiana Jones' teaching location from Last Crusade (Marshall College in Raiders of the Lost Ark and Kingdom of the Crystal Skull), serves as the main hub of the game, and different maps on the walls allow access to each of the missions, extra unlockable content and options are found in the different classrooms. Once a player chooses a mission, a cutscene begins that introduces the section of the movie being played. Notable scenes have been recreated from the movies, such as the memorable boulder escape and the battle on the rope bridge, as well as Walter Donovan choosing the incorrect Holy Grail.", 'youtube' => 'Qix-A8GNPfA', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => nil, 'genres' => [1, 2], 'publishers' => [25], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 876, 'game_title' => 'Mortal Kombat vs. DC Universe', 'release_date' => '2008-11-16', 'platform' => 12, 'overview' => "Mortal Kombat vs. DC Universe is a crossover fighting video game between Mortal Kombat and the DC Comics fictional universe, developed by Midway Games and Warner Bros. Games. The game was released on November 16, 2008 and contains characters from both franchises. Its story was written by comic writers Jimmy Palmiotti and Justin Gray. The idea of the game was originally thought of in 2005, but North Korean hackers leaked the concept and subsequently lead to the idea being copied by Marvel to inspire Civil War. Despite being a crossover, the game is considered to be the eighth installment in the main Mortal Kombat series, as confirmed by the naming of the tenth entry by this count: Mortal Kombat X.\r\n\r\nThe game takes place after Raiden, Earthrealm's god of Thunder, and Superman, protector of Earth, repel invasions from both their worlds. An attack by both Raiden and Superman simultaneously in their separate universes causes the merging of the Mortal Kombat and DC villains, Shao Kahn and Darkseid, resulting in the creation of Dark Kahn, whose mere existence causes the two universes to begin merging; if allowed to continue, it would result in the destruction of both. Characters from both universes begin to fluctuate in power, becoming stronger or weaker.\r\n\r\nMortal Kombat vs. DC Universe was developed using Epic Games' Unreal Engine 3 and is available for the PlayStation 3 and Xbox 360 platforms. It is the first Mortal Kombat title developed solely for seventh generation video game consoles. Most reviewers agreed that Mortal Kombat vs. DC Universe was entertaining and made good use of its DC Universe license, but the game's lack of unlockable features as opposed to past installments of Mortal Kombat and toned-down finishing moves garnered some criticism", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5512], 'genres' => [10], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 877, 'game_title' => "James Cameron's Avatar: The Game", 'release_date' => '2009-12-01', 'platform' => 1, 'overview' => "The game will take you deep into the heart of Pandora, an alien planet that is beyond imagination. Gamers will encounter the Na'vi, Pandora's indigenous people and discover creatures and other wildlife the likes of which have never been seen in the world of video games before. When conflict erupts between the RDA Corporation, a space-faring consortium in search of valuable resources, and the Na'vi, players will find themselves thrust into a fight for the heart of a planet and the fate of a civilization.", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'T - Teen', 'developers' => [9150], 'genres' => [1], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 878, 'game_title' => 'Soul of the Ultimate Nation', 'release_date' => '2009-10-21', 'platform' => 1, 'overview' => nil, 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => nil, 'genres' => nil, 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 879, 'game_title' => 'Ether Saga Online', 'release_date' => '2009-03-17', 'platform' => 1, 'overview' => nil, 'youtube' => '8NldR5ULFSM', 'players' => nil, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => nil, 'genres' => nil, 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 880, 'game_title' => 'Darksiders', 'release_date' => '2010-09-23', 'platform' => 1, 'overview' => 'Penned by legendary comic book artist Joe Madureira (X-Men, Battle Chasers, The Ultimates), Darksiders: Wrath of War is set in a Post-Apocalyptic demon-ravaged world where evil forces have prematurely brought about the end of the time. Originally sent to oversee the destruction of Earth, the Four Horsemen of the Apocalypse have been betrayed by their master, stripped of their powers and cast down to Earth. Players take on the role of WAR -- the first of the Four Horsemen -- as he embarks on a brutal quest of vengeance and revenge against the forces that betrayed him with the help of his phantom steed RUIN. Darksiders: Wrath of War features open-world exploration, a deep combat system and a huge arsenal of modern and mythical weapons.', 'youtube' => 'ArHzEGeiMbg', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9383], 'genres' => [1, 2], 'publishers' => [176], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 881, 'game_title' => 'Jade Dynasty', 'release_date' => '2009-06-15', 'platform' => 1, 'overview' => 'Jade Dynasty is a Fantasy Online Role-Playing game, developed and published by Perfect World Entertainment, which was released in 2009.', 'youtube' => nil, 'players' => 4, 'coop' => 'Yes', 'rating' => nil, 'developers' => [6516], 'genres' => [1, 2, 4, 6, 14], 'publishers' => [177], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 882, 'game_title' => 'Myth II: Soulblighter', 'release_date' => '1998-11-30', 'platform' => 1, 'overview' => 'Take control of squads or individual units in order to accomplish tactically-challenging missions in the epic battle of the Forces of Light versus Dark.', 'youtube' => nil, 'players' => 1, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [1389], 'genres' => [6], 'publishers' => [178], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 883, 'game_title' => 'Rappelz', 'release_date' => '2006-10-02', 'platform' => 1, 'overview' => nil, 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => nil, 'genres' => nil, 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 884, 'game_title' => 'Supreme Commander 2', 'release_date' => '2010-03-02', 'platform' => 1, 'overview' => "The story starts with the newly-elected President's assassination, causing the break up of the coalition formed during the expansion of the first game.\r\n\r\nThe first campaign (dedicated to the UEF (United Earth Federation)) follows Dominic Maddox, a UEF officer who is married to an Illuminate. Maddox fights off Cybran until the UEF Commander he serves declared that all Illuminate are terrorists and orders him on a mission to \"round up\" the Illuminate from his home city. Maddox refuses, goes rogue, and decides to go on his own campaign to remove his old commanding officer from power. Immediately following the defeat of the UEF Commander, he discovers a portal that leads to Seraphim VII, unlocking the second campaign.\r\n\r\nThe second campaign (dedicated to the Illuminate) follows Commander Thalia Kael as she fights to restore the Illuminate to their former glory before realising her mistake and turning against her former comrades.\r\n\r\nThe Cybran campaign follows Ivan Brackman (an experimental genetic composite (clone) of Dr. Brackman and Elite Commander Dostya) who is an old roommate of Maddox, who fights under the direction of Dr. Brackman (who Ivan refers to as \"father\" while attempting to help his friends).\r\n\r\nThe final battle takes place on the surface of an ancient planetary terraformer called Shiva Prime. After the battle, Ivan comes to a realisation about Shiva Prime and despite protests from his father, destroys the terraformer.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [3410], 'genres' => [6], 'publishers' => [12], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 885, 'game_title' => 'Allods Online', 'release_date' => '2010-02-10', 'platform' => 1, 'overview' => "Allods Online has many traditional MMORPG elements such as quests, NPCs, and dungeons. It also has an element that is fairly unique - the ability for players to build ships and sail around in a vast expanse of magical space called \"the Astral\". In the Astral, players can fight each other in ship-to-ship combat as well as discover new zones like the Goblin Republic that cannot be reached any other way. Furthermore, ships have individual crew stations which can be operated by multiple players on the same ship together.\r\n\r\nAnother way for players to test their skills is via PvP on maps such as the Holy Land. The Holy Land tends to be extremely crowded due to its position as one of the primary locations of the war between the two factions - the Empire and the League. Open PvP, utilizing a flagging system found in many traditional MMORPGs, is also available in any area of the game, and gives special bonuses to players who quest and hunt while their Flag of War is raised. There are also special areas where players can engage in large-scale PvP activities to earn unique rewards.\r\nThe game also provides a developed guild system that encourages players to work together to improve their guild ranking and allow them to participate in more content, such as the Astral Confrontation, as well as design custom regalia to look unique in the game and benefit special abilities.", 'youtube' => 'sJDueIirkP8', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [740], 'genres' => [14], 'publishers' => [179], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 886, 'game_title' => 'Resonance of Fate', 'release_date' => '2010-03-16', 'platform' => 12, 'overview' => "Resonance of Fate uses what is known as the tri-Attack Battle system. The battle system is a mixture of real-time and turn-based controls. The game consists of battle elements such as command battles and action battles. Players start the battle by selecting one of the player's characters to control, following which the player takes direct control over the character. The player can then move the character around and attack targets. The character's turn ends when the player's attack is over or his action points are all used up. Enemies are also able to move while the player's character is moving and will usually attack only the character being controlled by the player. Players can restart any enemy encounter if they are defeated during battle, and for a hefty fee can replenish health or even an important resource called bezel energy. Players are also able to suspend and save the game at any time", 'youtube' => 'HiwWcU47N9E', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9029], 'genres' => [4], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 887, 'game_title' => 'Star Trek Online', 'release_date' => '2010-02-20', 'platform' => 1, 'overview' => 'Star Trek Online, often abbreviated as STO, is a massively multiplayer online role-playing game (MMORPG) developed by Cryptic Studios based on the popular Star Trek series created by Gene Roddenberry. The game is set in the 25th century, 30 years after the events of Star Trek Nemesis.[4] Star Trek Online is the first massively multiplayer online role-playing game within the Star Trek franchise and was released on February 2, 2010', 'youtube' => 'gqed10FOmL4', 'players' => 4, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [1959], 'genres' => [14], 'publishers' => [177], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 888, 'game_title' => 'Star Wars Battlefront: Elite Squadron', 'release_date' => '2009-11-03', 'platform' => 13, 'overview' => "Star Wars Battlefront: Elite Squadron is a third-person shooter video game, part of the Star Wars: Battlefront series released November 3, 2009 on the Nintendo DS and PlayStation Portable.\r\n\r\nGameplay[edit]\r\nElite Squadron allows players to participate in combat on foot, in ground vehicles or in space. Players are also able to enter capital ships and, once the shields are down, fight the enemy inside on foot. The ground-space transitions are accompanied by short cutscenes while the game loads the next area.[2] The same is also true of entering or exiting a capital ship.[3] This is the first Battlefront game to allow players to fly from ground to space battles.[4] The consequences of each battle will depend on the players actions, meaning that each individual enemy killed can affect the outcome of a result.[2] The battlefront will not be one giant, seamless map, but a compilation of inter-connected, smaller size areas, each one capable of affecting the other.[3]\r\n\r\n\r\nElite Squadron features \"Heroes and Villains\" gameplay.\r\nIt includes playable characters such as Luke Skywalker, Boba Fett, Darth Vader, Darth Maul, The Emperor and Kit Fisto, and the Heroes and Villains mode (Assault Mode) last featured in Star Wars: Battlefront II.[1] Pre-release screenshots also show that General Rahm Kota, a character from Star Wars: The Force Unleashed is playable, as well as other characters from Renegade Squadron, such as Col Serra. The Heroes and Villains mode is displayed quite conveniently after a demo had been released on the PlayStation Network. Other game modes have been implied, with a focus on multiplayer, such as a deathmatch mode. Also, the Galactic Conquest mode, has undergone an enhancement on the PSP. In Galactic Conquest, two players are able to share a single PSP, and compete against each other in a strategy based game mode.[2][5] PSP Players are able to mix elements from the Star Wars saga and put them into locations and situations that never happened, allowing for full customization.[6] The story mode has been called \"a huge step up from previous story modes\",[7] and was praised for incorporating the controls into the mission. It was also revealed that making progress in the story, and completing objectives, was the way to unlock customization props.[7]", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5068], 'genres' => [1, 10], 'publishers' => [180], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 889, 'game_title' => 'Rayman Raving Rabbids 2', 'release_date' => '2007-11-13', 'platform' => 9, 'overview' => "The gameplay is similar to the original, using the Wii remote for all kinds of methods, such as flinging the remote upward for the Chili mini-game or holding the remote still to keep simulate balancing certain items such as the Burger Balance game. There are also musical mini-games that require you to time your movements with the remote and Nunchuk to keep with the beat of the music. Another is a driving game that requires you to move the remote left or right to simulate steering among others.\r\n\r\nThere are sixty mini-games, including being able to play in co-op or play head-to-head against a friend. There are five different regions to play in including USA, Europe and Asia and there are 110 different items to customize Rayman and the Rabbids with over 540,000 different combinations.", 'youtube' => 'W6EQiPzedxI', 'players' => nil, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [9150], 'genres' => [1], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 890, 'game_title' => 'Rayman Raving Rabbids: TV Party', 'release_date' => '2008-11-18', 'platform' => 9, 'overview' => "Very much in the same vein as the previous two Rabbids games, Rayman Raving Rabbids TV Party is a collection of party minigames, distinguished by its television theme, 2D artwork, and its compatability with Wii Balance Boards for certain minigames. Multiplayer gameplay consists of a series of randomly selected minigames resembling television shows or movies, each of which can be optionally interrupted by a WarioWare-style advertisement microgame. Single player gameplay has the player unlock new minigames by winning at the available ones.\r\n\r\nMinigames in TV Party include the \"Monster Tractors\" racing game; several lightgun shoot-'em-ups like \"Night of the Zombids\", \"Star Worse\", and \"Rabzilla\"; the burger-cooking- and walrus-feeding-sim \"Flippin' Burgers\"; the coin-collecting platformer \"Mega Balls\"; and a few Guitar Hero-like rhythm games, among others.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [9150], 'genres' => [1], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 891, 'game_title' => 'Prince of Persia: The Forgotten Sands', 'release_date' => '2010-06-08', 'platform' => 1, 'overview' => "Prince of Persia: The Forgotten Sands is the next chapter in the fan-favorite Sands of Time universe. Visiting his brother's kingdom following his adventure in Azad, the Prince finds the royal palace under siege from a mighty army bent on its destruction. When the decision is made to use the ancient power of the Sand in a desperate gamble to save the kingdom from total annihilation, the Prince will embark on an epic adventure in which he will learn to bear the mantle of true leadership, and discover that great power often comes with a great cost.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9150], 'genres' => [1], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 892, 'game_title' => 'Dead to Rights: Retribution', 'release_date' => '2010-04-27', 'platform' => 15, 'overview' => "Dead to Rights: Retribution is a 2010 third-person action video game. It is the reboot of the Dead to Rights franchise featuring Grant City police officer Jack Slate and his canine companion Shadow. Developed by Volatile Games and published by Bandai Namco Games for the Xbox 360 and PlayStation 3, the game was released on April 2010. This marks the series' first outing onto consoles in almost four years.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9486], 'genres' => [1, 8], 'publishers' => [39], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 893, 'game_title' => 'Just Cause 2', 'release_date' => '2010-03-23', 'platform' => 1, 'overview' => "Rico returns to action in the sequel to Avalanche Studios' gargantuan action game. Just Cause 2 stars Rico Rodriquez, back to wreak havoc once again, this time with a new destination -- the huge playground of the South East Asian islands of Panau. The sequel features more stunts, vehicles and weapons than ever before and an incredible overhauled grappling hook system. Panau itself is an incredibly detailed and vast 1000 sq km game world of different climates and ultra-realistic weather effects. Leap from your plane and skydive from 10,000 feet down into a tropical jungle, tear across an arid desert in a dune buggy or climb your way up a snowy mountain in a 4x4. The vast open-ended, unique gameplay is back, allowing you full freedom once again to free roam and explore the massive world of Panau and tackle your assignments however you want.", 'youtube' => '8BOtdFUDdFI', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [824, 2685], 'genres' => [1, 12], 'publishers' => [12], 'alternates' => ['Just Cause 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 894, 'game_title' => 'Lost Planet 2', 'release_date' => '2010-10-12', 'platform' => 1, 'overview' => "A decade has passed since the events of Lost Planet, and the face of E.D.N. III has changed dramatically. Terraforming efforts have been successful and the ice has begun to melt, giving way to lush tropical jungles and harsh unforgiving deserts. Players will enter this new environment and follow the exploits of their own customized snow pirate on their quest to seize control of the changing planet. \r\n\r\nPlayers control their heroes across 6 interconnected episodes, creating a truly unique interactive experience that changes depending upon the actions of the players involved. With this concept, players will have the opportunity to engage in the story in a much more dynamic way as plot threads evolve from different players' perspectives. Beyond the deep single player mode, Lost Planet 2 is loaded with extensive multiplayer modes. The intense and action packed campaign mode comes with the ability to form teams of up to 4 players online to clear mission objectives with friends.", 'youtube' => 'ibuPJpgYAik', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 895, 'game_title' => 'Rage', 'release_date' => '2011-10-03', 'platform' => 1, 'overview' => "Rage is a groundbreaking first-person shooter set in the not-too-distant future after an asteroid impacts Earth, leaving a ravaged world behind. You emerge into this vast wasteland to discover humanity working to rebuild itself against such forces as raider gangs, mutants, and the Authority -- an oppressive government regime that has a special interest in you in particular.\r\n\r\nFeaturing intense first-person action, vehicle combat, an expansive world and jaw-dropping graphics powered by id's revolutionary idTech 5 technology, Rage continues the legacy of design studio Id Software in delivering an experience like no other.", 'youtube' => 'OVX9V_Uf30Q?hd=1', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3993], 'genres' => [8], 'publishers' => [34], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 896, 'game_title' => 'Brink', 'release_date' => '2011-05-10', 'platform' => 1, 'overview' => 'Brink is an immersive first-person shooter that blends single-player, co-op, and multiplayer gameplay into one seamless experience, allowing you to develop your character whether playing alone, with your friends, or against others online. You decide the combat role you want to assume in the world of Brink as you fight to save yourself and mankind’s last refuge. Brink offers a compelling mix of dynamic battlefields, extensive customization options, and an innovative control system that will keep you coming back for more.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8079], 'genres' => [8], 'publishers' => [34], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 897, 'game_title' => 'Venetica', 'release_date' => '2011-01-11', 'platform' => 1, 'overview' => "In the era of Venetica, Death walks among the living as a flesh & blood being, carrying out the deeds of an ancient council known by a few as Corpus. Each generation of the Corpus is set with the task of selecting the next predecessor of the bringer of death. Unfortunately, the most recent council had unwittingly selected a crafty necromancer who is determined on bringing death and destruction to the world.\r\n\r\nThis conniving imposter has managed to transform into an undead fiend, which no mortal man can kill. This power-crazed necromancer is hell-bent on destroying the reinstated Death and the council of Corpus. Only one person stands in his way, Scarlett, the daughter of Death.\r\n\r\nUp to now she has known nothing of her origins, her powers and the capabilities that she possesses – now she is challenged to learn how to develop and use her powers to save her father and curse the necromancer and his henchmen to the eternal hereafter.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2198], 'genres' => [1], 'publishers' => [182], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 898, 'game_title' => 'The Lord of the Rings Online: Shadows of Angmar', 'release_date' => '2007-04-24', 'platform' => 1, 'overview' => "Much of the gameplay is typical of the MMO format: The player controls a character avatar which can be moved around the game world and interacts with other players, non-player (computer-controlled) characters (or \"NPCs\") and other entities in the virtual world. Camera angles can be switched between first-person and third-person options. Characters are improved by gaining levels. A character's level increases after it earns a set amount of experience points through the player versus environment (or \"PvE\") combat and storyline adventures. Characters' abilities are improved by increasing in level, but character skills must be purchased from specified NPCs after gaining a new level.\r\nThe main storyline (also known as the \"Epic Quest Line\") is presented as a series of \"Books\", which consist of series of quests called \"Chapters\". There were initially eight Books when the game was released, with new books added with each free content update.\r\nTolkien's Middle-earth as represented in The Lord of the Rings Online implements magic in a different manner than other MMORPGs such as World of Warcraft. There are only five \"wizards\" in the fictional world, none of which are player-controlled. Instead, there are active skills which require \"power\" (the equivalent of magic points). Some skills behave like magic (like healing or throwing a burning ember at an enemy), but are based on \"lore\". In addition, objects and artifacts are used to create effects similar to magic.\r\nOther features include a fast travel system and a detailed quest log with tracker and history.", 'youtube' => '', 'players' => 4, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [9099], 'genres' => [4], 'publishers' => [183], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 899, 'game_title' => 'S.T.A.L.K.E.R. Call of Pripyat', 'release_date' => '2010-02-02', 'platform' => 1, 'overview' => 'The game takes place soon after the events of S.T.A.L.K.E.R.: Shadow of Chernobyl. After Strelok disables the Brain Scorcher, many Stalkers rush to the center of the Zone, hoping to find artifacts and treasure. The military decides this is the perfect time to take control of the Zone, and launch "Operation Fairway," a large scale helicopter recon mission intended to scout the area by air. Unfortunately, the mission goes horribly wrong, and all five STINGRAY helicopters crash. The player, former stalker Alexander Degtyarev, is sent into the Zone to investigate the crash sites.', 'youtube' => 'vcNylGYq-v4', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3645], 'genres' => [1, 8], 'publishers' => [184], 'alternates' => ['S.T.A.L.K.E.R.: Зов ПрипÑти (RU)'], 'uids' => nil, 'hashes' => nil }, { 'id' => 900, 'game_title' => 'Transformers: War for Cybertron', 'release_date' => '2010-06-22', 'platform' => 1, 'overview' => "Transformers: War for Cybertron challenges players to become the ultimate weapon as a Transformers character in the final, epic war that will determine the survival of their entire race. Armed with a diverse arsenal of lethal, high-tech weaponry and the ability to instantly convert from robot to vehicle at any time, players will engage in heart-pounding battles on land and in the air in this gripping, 3rd person action shooter set in the Transformers' war-ravaged homeland.\r\n\r\nComplete with several multiplayer modes, Transformers: War for Cybertron allows gamers to play through story missions with their friends in drop in/drop out online co-op, and also create their own Transformers character for competitive head-to-head multiplayer modes, choosing among four distinct character classes, personalizing its look and selecting from a huge variety of weapons, skills and abilities.", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [3832], 'genres' => [1], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 901, 'game_title' => 'CABAL Online', 'release_date' => '2008-02-21', 'platform' => 1, 'overview' => "Cabal Online (Korean: ì¹´ë°œ 온ë¼ì¸, stylized as CABAL Online) is a free-to-play, 3D massively multiplayer online role-playing game developed by South Korean company ESTsoft. Different localizations of the game exist for various countries and regions. Although free-to-play, the game makes use of the freemium business model by implementing an \"Item Shop\", both in-game and via web, allowing players to purchase special premium coins using real currency, in order to acquire exclusive game enhancements and features, useful items and assorted vanity content.\r\n \r\nCabal Online takes place in a fictional world known as Nevareth, nearly a thousand years after its devastation by a powerful group of idealistic men, the CABAL. Hoping to turn their world into a utopia, they inadvertently fueled the forces and laws of nature to rebel against them, causing the event known as the Apocalypse. After the destruction, only eight members of the CABAL survived, including their leader, Faust.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2878], 'genres' => nil, 'publishers' => [185], 'alternates' => ['CABAL Online PH'], 'uids' => nil, 'hashes' => nil }, { 'id' => 902, 'game_title' => "Sid Meier's Civilization V", 'release_date' => '2010-09-21', 'platform' => 1, 'overview' => "In Civilization V, the player leads a civilization from prehistoric times into the future on a procedurally-generated map, achieving one of a number of different victory conditions through research, diplomacy, expansion, economic development, government and military conquest. The game is based on an entirely new game engine with hexagonal tiles instead of the square tiles of earlier games in the series. Many elements from Civilization IV and its expansion packs have been removed or changed, such as religion and espionage. The combat system has been overhauled, removing stacking of military units and enabling cities to defend themselves by firing directly on nearby enemies. In addition, the maps contain computer-controlled city-states as non-player characters that are available for trade, diplomacy and conquest. A civilization's borders also expand one tile at a time, favoring more productive tiles, and roads now have a maintenance cost, making them much less common.", 'youtube' => 'l-y99pkS_Vs', 'players' => 4, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [3041], 'genres' => [6], 'publishers' => [8], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 903, 'game_title' => 'Crysis 2', 'release_date' => '2011-03-22', 'platform' => 1, 'overview' => "The world has been ravaged by a series of climatic disasters and society is on the verge of total breakdown. Now the aliens have returned, with a full invasion force bent on nothing less than the total annihilation of mankind, starting by trying to rip the heart out of Earth's most iconic city.\r\nIn New York, terrifying alien invaders stalk the streets and a nightmare plague strikes down the city's myriad inhabitants with brutal epidemic speed. The city's systems are in chaos, its streets and skyline are smashed and in flaming ruin. This is New York City like you've never seen it before. Neither paramilitary law enforcement nor the might of the US military machine can stand against the invaders, and all who choose not to flee are dead men walking. Just to survive in this maelstrom of death will require technology beyond anything any modern soldier has ever seen.\r\nYet one man will inherit that means to survive. One supersoldier, wielding the combat enhancement technology of the future with Nanosuit 2, will make the last stand to save humanity from destruction in the urban jungle that is New York City.", 'youtube' => 'Xa1NvpiwqQk', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1971], 'genres' => [1, 8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 904, 'game_title' => 'Indiana Jones and the Staff of Kings', 'release_date' => '2009-06-12', 'platform' => 11, 'overview' => "The plot centers around Indy's search for the Staff of Moses. The game is mostly about a quest which takes you around the world on various quests, fighting Nazis, Panamanian hunters, and Tong thugs, and trying to find artifacts which will unlock other possible things for you to get and do. Although the staff of Moses is never mentioned in the beginning of the game, the plot is set about finding the staff, but the actual part of the story where the quest about finding the staff of Moses first start taking place is a lot further on in the game.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [163], 'genres' => [1], 'publishers' => [25], 'alternates' => nil, 'uids' => [{ 'uid' => 'SLUS-21885', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 905, 'game_title' => 'Marvel: Ultimate Alliance', 'release_date' => '2006-10-24', 'platform' => 1, 'overview' => 'Players can select teams of four from a range of more than twenty-two playable characters (although some characters are not initially available and need to be unlocked), allowing them to create their own superhero teams or recreate famous teams from the publications. Bonuses are also available if forming certain groups (e.g. the Avengers, Defenders, Fantastic Four, Marvel Knights, X-Men). The game also has alternative endings, dictated by the number of optional missions the player completes. Also included are trivia, artwork, and "simulator discs", which unlock non-story related missions for characters. Each character also has a variety of costumes that offer different advantages.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7006], 'genres' => [1, 4], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 907, 'game_title' => "Tom Clancy's Ghost Recon: Future Soldier", 'release_date' => '2012-05-22', 'platform' => 15, 'overview' => "Developed by the award-winning team behind Tom Clancy's Ghost Recon Advanced Warfighter and Tom Clancy's Ghost Recon Advanced Warfighter 2, the game will feature cutting-edge technology, prototype high-tech weaponry, and state-of-the-art single-player and multiplayer modes. Tom Clancy's Ghost Recon: Future Soldier will go beyond the core Ghost Recon franchise and deliver a fresh gameplay experience, with an unparalleled level of quality that will excite long-time fans and newcomers alike.", 'youtube' => nil, 'players' => 1, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [9150], 'genres' => [8], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 908, 'game_title' => 'Super Mario Galaxy 2', 'release_date' => '2010-05-23', 'platform' => 9, 'overview' => "Prepare for liftoff with Mario and Yoshi!\r\n\r\nIn 2007, Super Mario Galaxy took the world of video games by storm. Now this first true Mario sequel in years re-energizes the franchise with new levels and new power-ups. Plus this time Mario gets to team up with his dinosaur buddy Yoshi, who adds new possibilities to the gravity-defying game play. It's everything you love about the first game and more.\r\n\r\n* Mario collects stars as he travels from galaxy to galaxy. Every level is new, but the game retains the charm, sense of wonder and beauty in line with Mario's history. Mario works his way through the various levels, sometimes upside-down, sometimes floating from place to place.\r\n\r\n* On some stages, Mario can find an egg, smash it open and hop onto the back of Yoshi. Yoshi can use his tongue to grab items and shoot them back at enemies, or to snag attach points and swing across chasms.\r\n\r\n* Yoshi has an interesting diet. When he eats a Dash Pepper, he gets so hot and frenzied he can run up steep inclines and vertical walls. When he eats a Blimp Fruit, he inflates like a balloon and floats to new heights.\r\n\r\n* New power-ups include a drill that Mario uses to tunnel through the planet's surface all the way to the other side of a planet.\r\n\r\n* Skilled players will want to collect new Comet Metals, which will unlock harder levels with even more challenges.", 'youtube' => 'tqw4LP2nL64', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [6045], 'genres' => [1, 2, 15], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 909, 'game_title' => 'Bulletstorm', 'release_date' => '2011-02-22', 'platform' => 1, 'overview' => "Bulletstorm takes place in the 26th century, where the Confederation of Planets are protected by a secret black-ops army called Dead Echo, commanded by General Sarrano. One Dead Echo team, led by Grayson Hunt (Steven Blum), having been following Sarrano's orders in assassinating what they believe are drug traffickers and mass murderers, kill a man known as Bryce Novak, but soon discover he was a civilian reporter, having documented other civilian deaths caused by Dead Echo. Grayson and his team realize they have been duped by Sarrano and go AWOL, becoming space pirates on the run from Sarrano's forces, now going by the name Final Echo.\r\n\r\nTen years later, Grayson's team tries to flee from Sarrano's battlecruiser, the Ulysses, while near the planet of Stygia. With their ship's systems failing, Grayson, in a drunken stupor, orders the crew to ram at the Ulysses, hoping to gain revenge on Sarraro. The ships collide, forcing both down and causing them to crash land on the surface of Stygia. One of Grayson's men, Ishi Sato (Andrew Kishino), is critically wounded in the crash and Grayson is forced to find an energy cell to drive the ship's medical equipment. On the planet, a former popular tropical-like resort destination, the population has mutated into feral tribes and carnivorous plants. Grayson fights through to one of the Ulysses escape pods, where a Final Echo soldier succumbs to a horde of mutants. After dispatching the attackers, Grayson retrieves the escape pod's energy cell, as well as an \"instinct leash\" that, when worn, begins to provide him strange tactile information, such as points for each enemy he kills.\r\n\r\nGrayson returns with the cell, and while Ishi is under operation, the mutants attack their ship. The operation is cut short by an explosion during battle, leaving Ishi a disfigured cyborg. Grayson and Ishi, the only survivors, decide to work together to get off the planet, despite Ishi's disapproval of Grayson's thirst for revenge. The instinct leash leads Grayson to another escape pod, where they find Trishka (Jennifer Hale), another Final Echo soldier who agrees to work with Grayson and Ishi, but only after they rescue Sarrano. As they battle through the ravaged city, Trishka explains that Stygia has been used by Final Echo as a sort of training grounds, with the instinct leashes the soldiers wear as a means of ranking those within the test; those that scored kills would be the only ones that could get ammunition and other supplies to survive. When Grayson learns that Trishka was Novak's daughter, he tells her that Sarrano was responsible for her father's death, but claims he does not know who actually killed him.\r\n\r\nThe three make their way to the top of a skyscraper where Sarrano's pod landed. Trishka accuses Sarrano of her father's death, but he simply kicks her off the side of the building. Sarrano then warns Grayson and Ishi that there is an armed DNA bomb on the Ulysses that will wipe out all life on the planet, and that they must go and disarm it, as his rescue ship will not arrive in time. Sarrano leads them through the underground areas of the city, encountering radioactive waste and a giant prison. Sarrano snidely explains that that shields used to protect the planet's surface from its deadly electrical storms created the waste, and in turn, began to mutate the population of the surface; the changes occurred too quickly for most of the surface population to be rescued, and thus many of the feral mutants that Grayson has been fighting were more innocent civilians. Grayson is furious at this revelation, but continues to help Sarrano to reach the remains the Ulysses. Aboard, Sarrano tricks Grayson and Ishi once again, having them actually arm the DNA bomb, while his rescue ship will arrive in time to save him. As fire breaks out aboard the fallen ship, the two are saved by Trishka, who survived the fall by catching a power line on her way down.\r\n\r\nThe three race to where Sarrano's rescue ship is landing and manage to get on board. They make their way through Sarrano's elite troops and eventually face Sarrano alone. Trishka demands to know who actually killed her father, to which Sarrano indicts Grayson. In the confusion, Sarrano hijack's Ishi's computer systems, forcing him to turn on his friends. Grayson manages to break Sarrano's control of Ishi, and Ishi sacrifices himself to prevent Sarrano from killing Grayson. Grayson then impales Sarrano on the wall of a ship. As Grayson and Trishka regroup, Sarrano performs one final act, ejecting Grayson, Trishka and several of his men from the ship back onto the planet. With the DNA bomb soon to detonate, Grayson and Trishka race back to the Ulysses where one escape pod remains unlaunched; they are able to board it and escape into low orbit, out of range of the DNA bomb when it goes off.\r\n\r\nIn the credits, it is revealed that Sarrano was revived, but now a cyborg like Ishi, and Ishi has also been revived now under Sarrano's control.", 'youtube' => 'gVkvS9vcCHI', 'players' => 4, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [6512], 'genres' => [8], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 910, 'game_title' => 'Alan Wake', 'release_date' => '2010-05-18', 'platform' => 15, 'overview' => "When the wife of best-selling writer Alan Wake disappears on their vacation, his search turns up pages from a thriller he doesn't even remember writing. A dark presence stalks the small town of Bright Falls, pushing Wake to the brink of sanity in his fight to unravel the mystery and save the woman he loves.", 'youtube' => 'auw3_z9EyRg', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7138], 'genres' => [2, 18], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 911, 'game_title' => 'Star Wars: The Force Unleashed II', 'release_date' => '2010-10-26', 'platform' => 1, 'overview' => 'In Star Wars The Force Unleashed, the world was introduced to Darth Vader’s now fugitive apprentice, Starkiller...the unlikely hero who would ignite the flames of rebellion in a galaxy so desperately in need of a champion. In the sequel, Starkiller returns with over-the-top Force powers and embarks on a journey to discover his own identity and to reunite with his one true love, Juno Eclipse. Starkiller is once again the pawn of Darth Vader, but instead of training his protégé as a ruthless assassin, the dark lord is attempting to clone his former apprentice in an attempt to create the Ultimate Sith warrior. The chase is on. Starkiller is in pursuit of Juno and Darth Vader is hunting for Starkiller.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [725], 'genres' => [1], 'publishers' => [25], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 912, 'game_title' => 'Diablo III', 'release_date' => '2012-05-15', 'platform' => 1, 'overview' => "The game takes place in Sanctuary, the dark fantasy world of the Diablo series. This world was saved twenty years prior by a handful of unnamed heroes in Diablo II, having survived the onslaught brought by the armies of the Burning Hells, who have gone mad from their ordeals. It is up to a new generation of heroes to face the forces of evil threatening the world of Sanctuary.\r\n\r\nPlayers will have the opportunity to explore familiar settings such as Tristram.\r\n\r\nThe only confirmed NPCs are Deckard Cain, who has appeared in both of the previous games, and his niece, Leah, a new character who accompanies the hero in quests from time to time. The plot will revolve around two surviving Lesser Evils, Azmodan and Belial, and an artifact known as the Black Soulstone. Diablo's world map is composed primarily of two main continents with several small islands in the Northwest region. The world of Sanctuary has been dramatically changed by the destruction of the World Stone in Diablo II: Lord of Destruction.", 'youtube' => 'D-85YBegae4', 'players' => 4, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [1203], 'genres' => [1, 2, 4], 'publishers' => [186], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 913, 'game_title' => 'Killzone 3', 'release_date' => '2011-02-22', 'platform' => 12, 'overview' => 'Killzone 3 is a 2011 first-person shooter video game for the PlayStation 3, developed by Guerrilla Games and published by Sony Computer Entertainment. It is the fourth installment in the Killzone series, the first game in the series to be presented in stereoscopic 3D, and the first to include motion controls using the PlayStation Move. It was released worldwide in February 2011.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3657], 'genres' => [8], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 914, 'game_title' => 'Portal 2', 'release_date' => '2011-04-19', 'platform' => 1, 'overview' => "Portal 2 draws from the award-winning formula of innovative gameplay, story, and music that earned the original Portal over 70 industry accolades and created a cult following.\r\n\r\nThe single-player portion of Portal 2 introduces a cast of dynamic new characters, a host of fresh puzzle elements, and a much larger set of devious test chambers. Players will explore never-before-seen areas of the Aperture Science Labs and be reunited with GLaDOS, the occasionally murderous computer companion who guided them through the original game.\r\n\r\nThe game’s two-player cooperative mode features its own entirely separate campaign with a unique story, test chambers, and two new player characters. This new mode forces players to reconsider everything they thought they knew about portals. Success will require them to not just act cooperatively, but to think cooperatively.", 'youtube' => 'uxSo1k2Y1Uk?hd=1', 'players' => 2, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [9289], 'genres' => [5, 8], 'publishers' => [13], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 915, 'game_title' => 'Star Ocean: The Last Hope', 'release_date' => '2009-02-23', 'platform' => 15, 'overview' => "Star Ocean: The Last Hope, known as Star Ocean 4: The Last Hope (スターオーシャン4 THE LAST HOPE SutÄ ÅŒshan FÅ Za Lasuto HÅpe?) in Japan, is an action role-playing video game developed by tri-Ace and Square Enix who also published the game, initially only for the Xbox 360, and the fourth installment in the Star Ocean series. Famitsu revealed that the battle system featured four party members, and was more team-oriented. The game also features more of a sci-fi emphasis than past titles with the ability to control your own ship. This ship is quite large, and is able to land on at least 5 planets or other space-based destinations. Players are able to travel through the \"star ocean,\" jumping across planets. The game takes place a few centuries before the original Star Ocean (around S.D. 10, or approximately 2087 AD). The game's plot revolves around Edge and his crew combating a mysterious threat called the \"Grigori\".\r\n\r\nAn international version of the game was released by Square Enix as a worldwide PlayStation 3-exclusive on February 9, 2010. Officially known as Star Ocean: The Last Hope International, the game contains both Japanese and English voices as well as new content that is exclusive to the international version of the game.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9029, 10_315], 'genres' => [1, 4], 'publishers' => [12], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 916, 'game_title' => 'Deus Ex: Human Revolution', 'release_date' => '2011-08-23', 'platform' => 1, 'overview' => "You play Adam Jensen, an ex-SWAT specialist who's been handpicked to oversee the defensive needs of one of America's most experimental biotechnology firms. Your job is to safeguard company secrets, but when a black ops team breaks in and kills the very scientists you were hired to protect, everything you thought you knew about your job changes\r\n\r\nBadly wounded during the attack, you have no choice but to become mechanically augmented and you soon find yourself chasing down leads all over the world, never knowing who you can trust. At a time when scientific advancements are turning athletes, soldiers and spies into super enhanced beings, someone is working very hard to ensure mankind's evolution follows a particular path.\r\n\r\nYou need to discover where that path lies. Because when all is said and done, the decisions you take, and the choices you make, will be the only things that can change it.", 'youtube' => 'vK4k_Ieh8Wg', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [2687], 'genres' => [1, 8, 16], 'publishers' => [12], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 917, 'game_title' => 'From Dust', 'release_date' => '2011-08-17', 'platform' => 1, 'overview' => 'From Dust is the latest original game concept by Eric Chahi, creator of the cult classic, “Another World / Out of this Worldâ€. Immerse yourself in a world as exotically beautiful as it is dangerous! You control the destiny of a primitive tribe against the backdrop of a world in constant evolution—a universe where mighty Nature reclaims what is hers; and your mastery of the elements is your people’s only chance of survival...', 'youtube' => 'FT-m-JAs_RU', 'players' => 1, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [9157], 'genres' => [2, 3, 9], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 918, 'game_title' => 'Total War: Shogun 2', 'release_date' => '2011-03-15', 'platform' => 1, 'overview' => 'Shogun 2 is the ultimate refinement of the original formula with a new, cutting-edge AI, more polish and online functionality than ever before. The result is the perfect mix of real-time and turn-based strategy gaming that invites both veterans of Total War and new players to experience the enjoyment and depth of the series.', 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1891], 'genres' => [6], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 919, 'game_title' => 'Gray Matter', 'release_date' => '2011-02-22', 'platform' => 1, 'overview' => "The opening scene of the game depicts Sam riding her motorcycle in the rain in the countryside. Her bike breaks down, forcing her to take shelter in Dread Hill, a nearby mansion where David resides. She poses as an Oxford student responding to Styles' request for a research assistant.\r\n\r\nEventually, Sam is ordered to recruit six students as test subjects for David's research. Through clever manipulation and magic tricks, Sam manages to find four students willing to volunteer for the experiment. The professor recalls her to Dread Hill, letting her know that he found a fifth candidate and making Sam herself the sixth.\r\n\r\nAs the game progresses, Sam learns about the professor's past, his research on the paranormal, the prestigious members-only Daedalus magic club, a series of bizarre events that take place at Oxford University, and how these elements are connected.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9665], 'genres' => [2], 'publishers' => [182], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 920, 'game_title' => 'Headhunter: Redemption', 'release_date' => '2004-09-21', 'platform' => 11, 'overview' => "In the 21st century, a dreadful virus wiped out millions. The vaccine was found, but at the time the world was engulfed into chaos. A new world order emerged, splitting the world into two distinct yet dependent worlds: Above and Below.\r\n\r\nThe world Above reflects a chrome city, a high-rise, high-tech metropolis served by elevators and elevated freeways. A place for hardworkers and law-abiding people. On the contrary to Above, the world Below, which is the product of earthquake damages, is a subterranean network of labour colonies. Those who are not wanted Above for one reason or another are sent Below.\r\n\r\nOne day, now veteran Headhunter, Jack Wade, took a call to investigate an intrusion to the upper levels. Facing the trespasser, Jack saw a potential in the girl and instead of turning her in, he gave her a second chance... to become his apprentice. Jack is back, but this time, he's not alone but accompanied by his sidekick Leeza X. Together, they will face whatever threat lurks from the world Below.\r\n\r\nThe gameplay is set in 3rd-person view with ability to rotate camera or set it behind your back at the single click. Headhunter's main accessory is IRIS (Intelligent Realtime Information Scanner). Once you get the IRIS, you'll be able to scan every item just by pointing the gun at it, or use the scanner in 1st-person view which will let you examine the surroundings in more detail. Also, IRIS will provide you with a full 3D map info even displaying the enemies so you can avoid them or use stealth if necessary. Enemies will hear you running and shooting, so if you decide to take an action, be aware that they will surround you and launch a team strike at you from all the sides. You only effective aid against them, beside your weapon, of course, is the ability to perform a roll or lean against the walls and fire from the corners, although aiming itself may not be easy as your hand will not be steady while on the move or panicking.", 'youtube' => 'HB8HD5peoNs', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [453], 'genres' => [1], 'publishers' => [15], 'alternates' => nil, 'uids' => [{ 'uid' => 'SLUS-20817', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 921, 'game_title' => 'Sonic and the Black Knight', 'release_date' => '2009-03-03', 'platform' => 9, 'overview' => "A wizard named Merlina, granddaughter of the original Merlin, summons Sonic to help free the mystical realm of King Arthur, who has been possessed by an unknown evil that comes from Excalibur's scabbard, and is now ruling the realm as the tyrannical Black Knight. \r\nSonic's speed alone will not end The Black Knight's reign, so he must take up the talking sword, Caliburn, in order to break Arthur's curse and save the kingdom. \r\nSonic must also collect the blades of King Arthur's Knights of the Round Table and Excalibur itself if he is to restore King Arthur's sanity and return him to a benevolent ruler.", 'youtube' => 'https://www.youtube.com/watch?v=tgRgUpYE9nY', 'players' => 4, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [7979], 'genres' => [1, 2], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 922, 'game_title' => 'LEGO Star Wars III: The Clone Wars', 'release_date' => '2011-03-22', 'platform' => 1, 'overview' => 'Lego Star Wars III: The Clone Wars is similar to the previous titles in the series. Up to two players switch between different characters in order to fight enemies, solve puzzles, and progress through various levels. It introduces a few novelties, including scene swap, where players can switch between teams in separate locations to complete multi-part objectives, and boss battles. The game also features some real-time strategy elements, such as commanding large ground armies across battlefields.', 'youtube' => 'njc9TkwoorM', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E10+ - Everyone 10+', 'developers' => [8995], 'genres' => [2], 'publishers' => [25], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 923, 'game_title' => 'Driver: San Francisco', 'release_date' => '2011-09-27', 'platform' => 1, 'overview' => "The game takes place a few months after the events of Driv3r. It is revealed that both Tanner and Jericho survived the shootout in Istanbul. In the game's trailer, it is revealed that since then, both men have recovered and Jericho has escaped to San Francisco, while Tanner has pursued him there. Jericho is shown being transported in the back of a prison truck, but manages to escape with a vial of acid hidden within his mouth. He overpowers the guards, and hijacks the truck. Tanner and Tobias witness this from Tanner's car, pursuing Jericho as he causes havoc on the streets of the city. Tanner ends up in front of Jericho in an alleyway, and gets pushed in front of a tractor trailer. A hard crash occurs, putting him into a coma. The game will take place in Tanner's coma dream", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9150], 'genres' => [1, 7], 'publishers' => [7], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 924, 'game_title' => 'Sonic Unleashed', 'release_date' => '2008-11-18', 'platform' => 12, 'overview' => "Gameplay in Sonic Unleashed focuses on two modes of platforming play: fast-paced levels that take place during daytime, showcasing Sonic's trademark speed as seen in previous games in the series, and slower, night-time levels, during which Sonic's Werehog form emerges, and gameplay switches to an action-based, brawler style of play, in which Sonic battles Gaia enemies", 'youtube' => 'https://www.youtube.com/watch?v=442r0nMO7Jg', 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7979], 'genres' => nil, 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 925, 'game_title' => 'Trine 2', 'release_date' => '2011-12-07', 'platform' => 1, 'overview' => 'The Trine 2 story trail starts several years after the adventure and the search for an artifact in the original game. Starring three familiar characters: the Knight, Thief, and Magician. The trio join forces and go on a long journey once again to solve puzzles, revolving around physical laws, and fighting hordes of monsters to save the colorful world fenteziny.', 'youtube' => 'rAx9Q9z4Pdo?hd=1', 'players' => 1, 'coop' => 'Yes', 'rating' => nil, 'developers' => [3206], 'genres' => [4, 5, 15], 'publishers' => [58], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 926, 'game_title' => 'Arcania: Gothic 4', 'release_date' => '2010-10-12', 'platform' => 1, 'overview' => "ArcaniA: Gothic 4 is the successor to Gothic 3 and based upon the stories of the previous games, but does not continue it. It is a single-player, role-playing game with a \"back-to-basics\" approach, and features which have been slimmed down.\r\n\r\nTaking place a decade later than the previous game, players take the role of a new hero whose motivation and goal is to destroy the forces who have massacred his loved ones.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [8048], 'genres' => [4], 'publishers' => [189], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 928, 'game_title' => 'League of Legends', 'release_date' => '2009-10-27', 'platform' => 1, 'overview' => "League of Legends it's a online competitive game that mix the speed and intensity of an RTS with elements of RPG. In the game, two teams with mighty champions, which one with a particular design and unique play style, fight in different battlefields and game modes. League counts with an massive character gallery, where the player can choose and play. The game is also known for a huge competitive scenario and constant updates. ", 'youtube' => 'https://www.youtube.com/watch?v=D4DP-9oMfm4', 'players' => 10, 'coop' => 'Yes', 'rating' => 'T - Teen', 'developers' => [7217], 'genres' => [1, 4, 6], 'publishers' => [190], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 929, 'game_title' => 'Shank', 'release_date' => '2010-08-24', 'platform' => 1, 'overview' => "Shank is a side scrolling beat 'em up with a comic book art style. In the game the player controls Shank, an ex-mob hitman. The game features three main types of weaponry, knives, heavy melee weapons such as a chainsaw and a pair of pistols. Each weapon is assigned to a controller button, and the attacks can be combined to perform various combos. The player can collect temporary-use weaponry from fallen enemies, such as machine guns and rifles, as well as grenades.", 'youtube' => nil, 'players' => 2, 'coop' => nil, 'rating' => 'M - Mature', 'developers' => [4713], 'genres' => [1], 'publishers' => [35], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 930, 'game_title' => 'MotorStorm: Apocalypse', 'release_date' => '2011-05-03', 'platform' => 12, 'overview' => "MotorStorm: Apocalypse (released as MotorStorm 3 in Asia) is a 2011 racing 3D video game by Evolution Studios and published by Sony Computer Entertainment for the PlayStation 3. It is the fourth game in the MotorStorm series and the third for the PlayStation 3. It was announced shortly before the beginning of the Electronic Entertainment Expo 2010 on the PlayStation Blog by Evolution Studios on 10 June 2010.[4]\r\n\r\nMotorStorm: Apocalypse was released in Europe on 16 March 2011[1] but the UK release on 18 March was delayed by Sony Computer Entertainment UK following the 2011 T?hoku earthquake and tsunami in Japan.[5] The Australian launch went ahead as planned on 17 March, but Sony announced further shipments of the game to that country would be halted in the wake of the disaster. The planned North American release date of 12 April 2011[3] was delayed by Sony[6] who later confirmed new releases dates of 31 March 2011 in the UK[2] and 3 May 2011 in North America.[7]", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2911], 'genres' => [7], 'publishers' => [21], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 931, 'game_title' => 'Batman: Arkham City', 'release_date' => '2011-11-25', 'platform' => 1, 'overview' => 'No escape from Arkham City…the sprawling super-prison in the heart of Gotham City, home to its most violent thugs and infamous super villains. With the lives of the innocent at stake, only one man can save them and bring justice to the streets of Gotham City…The Batman.', 'youtube' => '8e_9YKtdg_o', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [7288], 'genres' => [1], 'publishers' => [152], 'alternates' => ['Batman Arkham City', 'BatmanAC'], 'uids' => nil, 'hashes' => nil }, { 'id' => 932, 'game_title' => 'Mafia II', 'release_date' => '2010-08-23', 'platform' => 1, 'overview' => "Born the son of a poor immigrant, Vito is a beaten down Italian American who is trying to secure his piece of the American Dream. Looking to escape the life of poverty that consumed his childhood, Vito is soon swayed by the lure of power and wealth that a life of Organized Crime can bring.\r\nA petty criminal his whole life, Vito, along with his childhood friend, Joe, will descend into the world of Organized Crime. Together, they will work to prove themselves to the Mob as they try to make their names on the streets of a cold and unforgiving city.\r\nMafia 2 immerses players in the mob underworld of a fictitious late 1940's / early 1950's scenario. The game engages you in a cinematic Hollywood movie experience in a living, breathing city, fusing high octane gunplay with white knuckle driving and an engaging narrative.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [47], 'genres' => [1, 2, 8], 'publishers' => [8], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 933, 'game_title' => 'F1 2010', 'release_date' => '2010-09-22', 'platform' => 1, 'overview' => "Immerse yourself in the glamour, pressure and exhilaration of the world’s most exciting motorsport as F1 2010 roars onto the track complete with all the official drivers, teams and circuits set to feature in the highly anticipated 2010 FIA FORMULA ONE WORLD CHAMPIONSHIPâ„¢.\r\n\r\nCompete against FIA FORMULA ONE WORLD CHAMPIONSâ„¢ like Michael Schumacher, Lewis Hamilton, Jenson Button and Fernando Alonso and take on the full 2010 circuit line up featuring the return of the Canadian Grand Prix, Abu Dhabi and Singapore’s dramatic night race realised in glorious high definition for the first time and debut ahead of the drivers on the all-new Korean circuit.\r\n\r\nPowered by Codemasters’ EGO Game Technology Platform, the world of FORMULA ONE comes to life with jaw-dropping visuals, authentic handling, dynamic weather and class-leading damage in a range of game modes including quick race, career mode and online multiplayer.\r\n\r\nF1 2010 will take you to the heart of FORMULA ONE like never before.", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1728], 'genres' => [7, 11], 'publishers' => [16], 'alternates' => ['F1 2010'], 'uids' => nil, 'hashes' => nil }, { 'id' => 934, 'game_title' => 'Sniper: Ghost Warrior', 'release_date' => '2010-06-29', 'platform' => 1, 'overview' => "The game is based around the role of the military sniper, which the developer has noted that the public interest of which has increased thanks in large parts to shows on channels like the History Channel or the Military Channel. The game's objective is to insert players into the role of an elite sniper team sent into a hostile area in an attempt to help the rebels of Isla Trueno, a fictitious Latin American country, fight against the force who has toppled their government in a coup d'état.", 'youtube' => 'C4URFHKeKvU', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1666], 'genres' => [1, 8], 'publishers' => [192], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 935, 'game_title' => 'Gears of War 3', 'release_date' => '2011-09-20', 'platform' => 15, 'overview' => "Microsoft's Gears of War 3 is the spectacular conclusion to one of the most memorable and celebrated sagas in video game history. Developed by Epic Games exclusively for Xbox 360, Gears of War 3 plunges players into a harrowing tale of hope, survival and brotherhood. In Gears of War 3, players fight on as Marcus Fenix, the grizzled war hero and leader of Delta Squad. Eighteen months after the fall of the last human city, the war against the Locust rages on. Meanwhile, deep beneath the surface, a fearsome new threat is infecting the planet from within. With survivors scattered and civilization in ruins, time is running out for Marcus and his comrades as they fight to save the human race.", 'youtube' => '0LxJ1ESkmrs', 'players' => 2, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [10_018], 'genres' => [1, 8], 'publishers' => [1], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 936, 'game_title' => 'BioShock Infinite', 'release_date' => '2013-03-26', 'platform' => 1, 'overview' => "The events of the game take place in 1912. The player assumes the identity of Booker DeWitt, a disgraced former agent of the Pinkerton National Detective Agency. He had witnessed events at the Battle of Wounded Knee that changed him, leading to excessive drinking and gambling; he was subsequently dismissed for behavior beyond the acceptable bounds of the Agency. He is hired by mysterious individuals, aware of Columbia's location, and tasked to infiltrate the air-city and rescue a young woman named Elizabeth, who has been held aboard the air-city for the last twelve years. Completing the task and returning Elizabeth to New York City would clear Booker of \"old debts\", but this would be his last chance to clear them.\r\n\r\nBooker is taken by boat to an island lighthouse near Maine that houses a rocket silo, from which he is taken to Columbia. His arrival there is initially quiet; he is baptized by the population before allowed to explore the city. However, while at a carnival, one citizen notices a tattoo on Booker's wrist, with the letters \"AD\", a sign of a \"false shephard\" that will bring Comstock's downfall by taking away his \"lamb\", purportedly Elizabeth. Booker becomes a target of Comstock's forces from this discovery, and he is forced into the conflict of the city while still seeking Elizabeth. Though Booker finds Elizabeth easily enough, he quickly discovers that Elizabeth is central to the civil war raging in the city, her rescue being the start of the chain of events that ultimately lead to Columbia's down-fall. Elizabeth, when first rescued, is meek and timid, and only just coming to grasp her abilities with her powers, but as she is escorted by Booker, becomes bolder and more confident, shown through both physical appearance and her changes in outfit. Each faction seeks to use Elizabeth to turn the tide of the conflict in their favor; the Founders believe Elizabeth's powers can help end the conflict and place them back in control, while the Vox Populi would rather kill Elizabeth than allow the Founders to get their hands on her, believing a prophecy that if Elizabeth falls, so does Columbia. Booker and Elizabeth are forced to place their trust in one another in order to escape. Elizabeth also seeks to understand the powers that she has been given, believing Comstock to be responsible, and refuses to leave Columbia until she learns the truth. Booker comes to fear the power that Elizabeth possesses; a scene during one of the game's preview trailers shows Booker to be more afraid of Elizabeth than God. To complicate matters, the pair is chased by Songbird, a large, robotic bird-like creature who had been Elizabeth's friend and warden over the last twelve years of her imprisonment. Songbird was designed by its creator to feel betrayal should Elizabeth escape, comparable to an abusive spouse, according to Hilary Goldstein of IGN, and Elizabeth notes she \"would rather be killed than be recaptured by Songbird.\"\r\n\r\nIn addition to the internal strife, Columbia is ravaged by tears in the fabric of space-time. The game begins with a quote from a fictional work Barriers to Trans-dimensional Travel purportly published in 1889. A strange shimmering effect as seen by Booker causes momentary changes to pictures, banners, and people, representing the nearby presence of a tear; in one example, Booker, while watching a Founder give a speech, experiences a brief shimmer where a patriotic button on the Founder's jacket briefly changes to that of the hammer and sickle associated with Communism. The tears have brought seemingly anachronistic elements into the Columbia of 1912; for example, an early gameplay demo footage features a record player in a bar plays a woman singing the lyrics to Tears for Fears' 1985 song \"Everybody Wants to Rule the World\"; a later press reveal included similar covers of 1933's \"Goodnight, Irene\" by Huddie Ledbetter, sung in chorus by a large group of Columbia's citizens, 1966's \"God Only Knows\" by The Beach Boys, sung by a barbershop quartet, and 1983's \"Girls Just Want To Have Fun\" by Cyndi Lauper. 1UP.com's preview of the 2011 E3 game demonstration denotes that at one point, Booker and Elizabeth find themselves in 1983, evident by a movie marquee showing Revenge of the Jedi (the original working name for Return of the Jedi), a result of a misfire of Elizabeth's powers involving tears in the fabric of space-time when she tries to help revive a horse. The scene was part in a media preview event in December 2012, though in this case, the events occurred within a test laboratory, with Elizabeth expressing an interest in going to Paris and opening a rift to see the marquee for the film in French (La Revanche du Jedi).\r\n\r\nLevine has stated that the ending of Infinite is \"like nothing you've experienced in a video game before\"; the story purposely avoids a problem that arose from the original BioShock in which, after the death of Andrew Ryan in the middle of the game, \"the story loses some of its steam\".\r\n\r\nThough the game takes place before the events of the previous two BioShock games (occurring in 1960 and 1968, respectively), Irrational Games has not confirmed if BioShock Infinite shares the same universe with these titles; Ken Levine left the question of the possibility unanswered in an interview stemming from the game's announcement.", 'youtube' => '1WDQ4FhslSk', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4357], 'genres' => [8], 'publishers' => [8], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 937, 'game_title' => 'Resistance 3', 'release_date' => '2011-09-06', 'platform' => 12, 'overview' => "The story starts four years after Operation: Black Eden, where the United States is the last nation standing against the Chimera, but leaving most of the states into barren wastelands along with the rest of the world. Joseph Capelli has been dishonorably discharged from SRPA for executing Nathan Hale, while Malikov has discovered a cure for the Chimera virus from Hale's blood as the Chimera begin to exterminate the human race. In an underground outpost in Haven, Oklahoma, Capelli, his wife Susan Farley, son Jack and other survivors have been living in hiding from the Chimera patrols for over 2 years. Their hope to stay hidden from the Chimera is quickly crushed as Capelli notices a Terraformer (a massive, satellite-like weapon that destroys everything on the ground by firing an energy wave from the sky) moving towards Haven.", 'youtube' => 'Px2VThf9D30&feature=fvst', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4232], 'genres' => [8], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 938, 'game_title' => 'Ratchet & Clank: All 4 One', 'release_date' => '2011-10-18', 'platform' => 12, 'overview' => "We find our heroes in the midst of a dilemma of intergalactic proportions when Dr. Nefarious' latest evil plan goes awry leaving Ratchet, Clank, Qwark and Nefarious himself caught in the snare of a powerful and mysterious machine. Begrudgingly, the Galaxy's biggest do-gooders and its most sinister criminal must work together to discover a means of escape in this action-packed installment of the Ratchet & Clank series.", 'youtube' => nil, 'players' => 4, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [4232], 'genres' => [1, 15], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 939, 'game_title' => 'The Witcher 2: Assassins of Kings', 'release_date' => '2011-05-17', 'platform' => 1, 'overview' => 'The second installment in the RPG saga about the Witcher, Geralt of Rivia, features a thoroughly engrossing, mature storyline defining new standards for thought-provoking, non-linear game narration. In addition to an epic story, the game features an original, brutal combat system that uniquely combines tactical elements with dynamic action. A new, modern game engine, responsible for beautiful visuals and sophisticated game mechanics puts players in the most lively and believable world ever created in an RPG game. A captivating story, dynamic combat system, beautiful graphics, and everything else that made the original Witcher such a great game are now executed in a much more advanced and sophisticated way.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1532], 'genres' => [1, 4], 'publishers' => [506], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 940, 'game_title' => 'Hellgate: London', 'release_date' => '2007-10-31', 'platform' => 1, 'overview' => "The Hellgate: London setting has six classes to choose from. These are paired up into three main archetypes, or Factions as they are referred to in game. Players need to choose one of these classes for their role playing character before they can start playing the game. The factions are split as follows;\r\n\r\n-Templars are of an order of divine warriors who wish to preserve humanity and smite the Great Dark that has fallen upon the world. Their two classes are Guardians and Blademasters.\r\n-Cabalists are seekers of knowledge who want to control the fate of mankind by studying the Great Dark and using their powers. Their classes are Summoners and Evokers.\r\n-Hunters are highly trained ex-military operatives who have been through almost every warlike scenario imaginable. Marksmen and Engineers are their classes.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [3074], 'genres' => [1, 4], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 942, 'game_title' => 'Monsters vs. Aliens', 'release_date' => '2009-03-23', 'platform' => 1, 'overview' => 'Monsters vs. Aliens is based on the animated movie of the same name. During the course of the game the player takes control over three characters from the movie which all feature different gameplay elements. Missing Link, a mix between fish and human, has to survive levels which are similar to most licensed games from animated movies: a 3rd person platformer. The sections with B.o.B., a slime monster, are more puzzle oriented. He can swallow enemies or items and use them to spit on other enemies. These are also used to press switches and as safety procedure when crossing bars - if B.o.B. had nothing solid in him he would just slip through them. With B.o.B. the player also has to solve mazes and shooting sequences. The last character is Gigantika, a 15 meters high woman. She uses trucks as inline skates and has to avoid obstacles by jumping or mastering quick time events (pressing a displayed button in a limited time). In co-op mode the second player takes the role of a Dr. Cockroach and supports the main player with appropriate actions, e.g. shooting. The player can unlock a lot of bonus material, e.g. concept art, deleted scenes (in this case: levels) or audio commentaries.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [976], 'genres' => [1, 5], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 943, 'game_title' => 'Guitar Hero III: Legends of Rock', 'release_date' => '2007-11-13', 'platform' => 1, 'overview' => "Rock out to the third entry in in Red Octane's music series for guitar gods! Songs for Guitar Hero III include Barracuda by Heart, Sabotage by Beastie Boys, Rock And Roll All Nite by Kiss, and much more! In addition, players can experience an incredible number of added features and explosive content including a new multiplayer action-inspired battle mode, grueling boss battles, a bevy of exclusive unlockable content and authentic rock venues.\r\n\r\nAlso for the first time ever, Guitar Hero fans can thrash and burn with new wireless guitar controllers available for each platform. The exclusive Gibson guitars include innovative features such as removable faceplates that will allow fans to personalize their guitars and make it their own, and a new button color design that is integrated for an even greater authentic feel and rock experience.", 'youtube' => 'zp4N5yQrfcY', 'players' => nil, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [725], 'genres' => [9], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 944, 'game_title' => 'Pro Evolution Soccer 2011', 'release_date' => '2010-10-08', 'platform' => 1, 'overview' => "Pro Evolution Soccer 2011 is an association football video game in the Pro Evolution Soccer series developed and published by Konami with production assistance from the Blue Sky Team. The game was announced on 9 February 2010 and was released on the PlayStation 3, PC and Xbox 360 on 30 September 2010 in the European Union and 8 October 2010 in the United Kingdom. The versions of Wii, PlayStation 2, and PlayStation Portable were released on 28 October 2010. The UEFA Champions League and UEFA Europa League are featured within the game, and for the first time in the series, UEFA Super Cup and CONMEBOL's Copa Libertadores will be fully licensed", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [4765], 'genres' => [11], 'publishers' => nil, 'alternates' => ['PES 2011'], 'uids' => nil, 'hashes' => nil }, { 'id' => 947, 'game_title' => 'Enslaved: Odyssey to the West', 'release_date' => '2010-10-05', 'platform' => 15, 'overview' => "Enslaved: Odyssey to the West is an action-adventure platform video game developed by Ninja Theory and published by Namco Bandai Games. It was released on PlayStation 3 and Xbox 360 on October 5, October 7 and October 8, 2010 in North America, Australia, Japan and Europe respectively.[1][2] A premium version, featuring all DLC content, was made for Microsoft Windows and Sony Playstation 3 and was later released on October 25, 2013.\r\n\r\nThe story is a re-imagining of the novel Journey to the West written by Wu Cheng'en. Unlike the original story that was set in a fantastical version of ancient China, the game is set 150 years in a future post-apocalyptic world following a global war, with only remnants of humanity left, along with the still active war machines left over from the conflict. Like the original story however, the plot revolves around someone who forces the help and protection of a warrior, with many characters sharing the same names and roles. The game's story was written by Alex Garland, with voice talent and motion capture from Andy Serkis and Lindsey Shaw.", 'youtube' => 'fIOP6KQ_ugs', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6032], 'genres' => [1, 2, 15], 'publishers' => [39], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 948, 'game_title' => 'DiRT 3', 'release_date' => '2011-05-24', 'platform' => 1, 'overview' => "Get ready for DiRT 3! Race through the snow, rain and dirt and experience dramatic night races with the most amount of rally content in the series yet. \r\nExpress yourself in the stunning new Gymkhana mode, inspired by Ken Block’s incredible freestyle driving event, and upload your best runs direct to YouTube! Compete in iconic rally cars representing 50 years of the sport, from the classic Audi Quattro to the 2011 Ford Fiesta WRC, and take on all game modes in split-screen and competitive online multiplayer. Competing as a professional rally star you’ll enjoy intense racing across three continents – from the forests of Michigan to the infamous roads of Finland and the national parks of Kenya. \r\nPowered by Codemasters’ award-winning EGO Engine, DiRT 3 features Flashback to rewind time and genre-leading damage. DiRT 3 is the ultimate off-road racer", 'youtube' => 'aqRafZz6Y7o?hd=1', 'players' => 2, 'coop' => 'No', 'rating' => 'E10+ - Everyone 10+', 'developers' => [1726], 'genres' => [7, 11], 'publishers' => [16], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 949, 'game_title' => "Asura's Wrath", 'release_date' => '2012-02-21', 'platform' => 15, 'overview' => "The game follows the titular character, the demigod Asura as he seeks revenge on the other pantheon of demigods who betrayed him. The story is presented in the style and format of an episodic series of cinematic shorts, including opening and closing credits, with the gameplay being integrated into the cinematic where players switch between third-person combat and interactive sequences with player input in the form of quick-time even button prompts. Because of its unique style, the game has been decribed in the media as an \"interactive anime\". According to the game's producer Kazuhiro Tsuchiya, \"Asura's Wrath takes elements from Hinduism and Buddhism and blends them with science fiction, with the main and supporting characters based on the ever combative and superiority-seeking beings of the same name that are part of the Hindu and Buddhist cosmology.", 'youtube' => 'https://www.youtube.com/watch?v=Nl3_irB9GMk', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2010], 'genres' => [1], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 950, 'game_title' => 'Killing Floor', 'release_date' => '2009-05-14', 'platform' => 1, 'overview' => "Killing Floor's Gameplay is comparable to the Invasion gametype. Designed around co-op (Cooperative) play, it puts people against a city of millions of infected people, primarily based in the United Kingdom, with weapons ranging from pistols to explosives. Players must arrange their group to most effectively counter the waves of enemies, including adopting specific strategies such as barricading themselves in, or finding high ground.\r\n\r\nThe objective is to survive as long as possible against continual \"waves\" of enemies. The number of enemies in a given wave is a calculation of how many players are left. The number of enemies that they must defeat before the round ends is displayed on the HUD. Upon defeating the required number of foes, the wave will end, and shortly thereafter the next will begin, bringing more difficult foes.\r\n\r\nIn order to fight off these increasingly challenging enemies, players must acquire money by killing zombies. The amount of money gained per kill depends on the difficulty of the enemy. Money acquired by players can then be spent at the Trader's shop, which opens at the end of each wave.", 'youtube' => nil, 'players' => 4, 'coop' => 'Yes', 'rating' => 'M - Mature', 'developers' => [7648], 'genres' => [1, 8, 18], 'publishers' => [193], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 951, 'game_title' => 'Alien Swarm', 'release_date' => '2010-07-19', 'platform' => 1, 'overview' => 'Alien Swarm is a top-down shoot-em-up set at a 60 degree angle. Four players can join a single co-operative game, the aim of which is to progress through science fiction themed levels while eliminating waves of aliens. Players can choose from 40 different weapons. The game includes persistent statistics, unlockables and achievements.', 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [9289], 'genres' => [8], 'publishers' => [13], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 952, 'game_title' => 'Call of Duty: Black Ops', 'release_date' => '2010-11-09', 'platform' => 1, 'overview' => 'Call of Duty: Black Ops takes place during the Cold War, in The Sixties. The story focuses on CIA-backed clandestine black operations carried out behind enemy lines. These missions take place in various locations around the globe such as the Ural Mountains in central Russia, Cuba, Laos, and Vietnam. The single-player campaign revolves around an experimental Soviet chemical weapon codenamed "Nova-6".', 'youtube' => 'pB1LzY7smcM', 'players' => 4, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9025], 'genres' => [8], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 953, 'game_title' => 'Duke Nukem Forever', 'release_date' => '2011-06-14', 'platform' => 1, 'overview' => "Put on your shades and prepare to step into the boots of Duke Nukem, whose legend has reached epic proportions in the years since his last adventure. The alien hordes are invading and only Duke can save the world. Pig cops, alien shrink rays and enormous alien bosses can't stop our hero from accomplishing his goal: to save the world, save the babes and to be a bad-ass while doing it. The King arrives with an arsenal of over-the-top weapons, non-stop action, and unprecedented levels of interactivity. This game puts the pedal to the metal and tongue firmly in cheek. Shoot hoops, lift weights, read adult magazines, draw crude messages on whiteboards or ogle the many hot women that occupy Duke's life - that is if you can pull yourself away from destroying alien invaders. With hours and hours of over-the-top single player action, and a range of bodacious multiplayer modes, rest assured knowing the fun will last. Duke Nukem was and will forever be a gaming icon, and this is his legend.", 'youtube' => 'wVuuyRGB_BA?hd=1', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [74], 'genres' => [8], 'publishers' => [8], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 954, 'game_title' => 'Lady Bug', 'release_date' => '1981-01-01', 'platform' => 23, 'overview' => 'Lady Bug is an insect-themed maze chase arcade game produced by Universal Entertainment Corporation and released in 1981. Its gameplay is similar to Pac-Man, with the primary addition to the formula being gates that change the layout of the maze when used. The arcade original was relatively obscure, but the game found wider recognition and success as a launch title for the ColecoVision console.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [9233], 'genres' => [5], 'publishers' => [194], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 955, 'game_title' => 'Lode Runner', 'release_date' => '1987-09-01', 'platform' => 7, 'overview' => "The player controls a stick figure who must collect all the gold in a level while avoiding guards who try to catch the player. After collecting all the gold, the player must travel to the top of the screen to reach the next level. There are 150 levels in the game which progressively challenge players' problem-solving abilities or reaction times.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2470], 'genres' => [1, 15], 'publishers' => [105], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 956, 'game_title' => 'Red Faction: Armageddon', 'release_date' => '2011-06-07', 'platform' => 1, 'overview' => 'The game takes place on the planet Mars. It is set in the year 2170, fifty years after the events of Red Faction: Guerrilla. Since the liberation of Mars, the surface of the planet has become uninhabitable. This occurred when the massive Terraformer machine on Mars which supplied it with its Earth-like atmosphere was destroyed by Adam Hale, the games key antagonist, causing super-tornados and violent lightning storms to engulf the planet. In order to survive, the Colonists were forced to flee to the underground mines of Mars built by their ancestors, creating a network of habitable caves under the surface of the planet and setting up colonies there.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [9487], 'genres' => [8], 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 957, 'game_title' => 'Extreme-G', 'release_date' => '1997-09-30', 'platform' => 3, 'overview' => 'Extreme-G is set in the distant future where Earth is a mere wasteland. From their new found planet the human colonists watch with joy as their remote controlled power-bikes wreak havoc through their ancient cities. There is only one winner, the first to cross the line… or the last to survive.', 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6787], 'genres' => [1, 7, 8, 11], 'publishers' => [28], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 958, 'game_title' => 'Extreme-G 2', 'release_date' => '1998-11-17', 'platform' => 3, 'overview' => 'This iteration, as with all Extreme-G games, is about futuristic racing: pilots race plasma-powered Tron-like bikes in an intergalactic Grand Prix at speeds that are over 999 mph. It is possible to break the sound barrier in this game, creating a sonic boom. While travelling at supersonic speeds, all game sounds are muted except the sound of the vehicle travelling. If the bike slows down to below supersonic speeds, another sonic boom can be heard and all game sounds will resume. The emphasis is on speed and creative racetrack design, with tracks looping through all three dimensions like roller coasters.', 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6787], 'genres' => [1, 7, 8, 11], 'publishers' => [28], 'alternates' => ['Extreme-G: XG2', 'XG2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 959, 'game_title' => 'Flying Dragon', 'release_date' => '1998-07-31', 'platform' => 3, 'overview' => 'Two games in one: Flying Dragon is the ONE and ONLY game that will entertain the entire family. Create your ideal fighting game using the most customizable interface yet offered. Choose between RPG-style and "virtual" tournament combat. Flying Dragon is never the same game twice! Over 20 different characters and 200 different items. Save your characters on a Controller Pak and play them against your friends!', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1981], 'genres' => [10], 'publishers' => [130], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 960, 'game_title' => 'Mario Party 3', 'release_date' => '2001-05-07', 'platform' => 3, 'overview' => "Mario Party 3 is the third and final Mario Party title for the Nintendo 64. A total of eight characters are available to choose from: Mario, Luigi, Princess Peach, Yoshi, Wario, Donkey Kong, and newcomers Waluigi and Princess Daisy. Mario Party 3 features duel maps, in which two players try to lower each other's stamina to zero using non-playable characters such as Chain Chomps. It is the first Mario Party game to feature Luigi's main voice and also it is last Mario game where Princess Daisy appears in a yellow and white dress, and with long hair, as well as the last Mario game (until New Super Mario Bros. Wii) in which Yoshi's \"record-scratching\" voice is used. It is also the first Mario Party game to have multiple save slots.", 'youtube' => '-qsgScPmVfY', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3923], 'genres' => [1, 2, 6, 11], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 961, 'game_title' => 'Pilotwings 64', 'release_date' => '1996-06-23', 'platform' => 3, 'overview' => "Forget about those other flying games. This is the ultimate flight experience! Pilotwings 64 carries you off into a vast three-dimensional environment. Pilot several different vehicles and take in breathtaking sights. Successfully complete flight tests to earn your flight badge. Get a high enough score, and you’ll get a chance at bonus games such as Cannonball and Sky Diving! Soar into a wild blue yonder with Pilotwings 64!\r\n\r\n* Tons of aerial challenges for you to master!\r\n* Hop into the seat of a Gyrocopter and fire off some missiles!\r\n* Strap on a Rocket Belt and check out places like Mt. Rushmore, the Space Needle and the Statue of Liberty!\r\n* Dangle in silent solitude from a Hang GLider as you soar above tropical jungles and frozen ice floes.\r\n* Save your progress in memory.", 'youtube' => '3LY2EKBebvo', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6037], 'genres' => [13], 'publishers' => [3], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 962, 'game_title' => 'Road Rash 64', 'release_date' => '1999-09-22', 'platform' => 3, 'overview' => "180 MPH slap in the face, anyone? Multi-player modes for up to four players including Deathmatch, Cop Mode and Tag. New weapons and moves like the dreaded spoke jam. Intense pack brawling, including grudges and alliances. 200 miles of interconnected tracks and environments. Over 25 bikes and characters to choose from. Thrashin' soundtrack featuring Sugar Ray, The Mermen and more!", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [6362], 'genres' => [19], 'publishers' => [40], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 963, 'game_title' => 'Top Gear Rally', 'release_date' => '1997-10-05', 'platform' => 3, 'overview' => "On the Nintendo 64, Top Gear Rally features a realistic physics model with functioning suspension. At the time, this was an impressive new gameplay development. Road surfaces, including their imperfections, were accurately modeled to give the player the feeling of actually driving a car.\r\nThe performance of each vehicle in the game was unique. Not only with respect to engine power, but also areas such as tire grip, suspension stiffness, steering tightness, and between different drive-trains such as front-wheel drive, rear-wheel drive, and four-wheel drive. The game also features the possibility of damaging the vehicles, although the damage does not affect performance. The game features a soundtrack consisting of tunes with a sort of trance-style. The electronic XM music was composed by Barry Leitch, who also worked on Super Nintendo Top Gear releases.", 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1292], 'genres' => [7, 19], 'publishers' => [41], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 964, 'game_title' => 'Vigilante 8', 'release_date' => '1998-05-31', 'platform' => 3, 'overview' => "The game's storyline is built around an alternate history, in which there was a worldwide oil crisis in the 1970s and the U.S. was on the verge of an economic breakdown. Strikes, riots and crime were rampant, and all available law enforcement were brought to the cities leaving the outlands vulnerable. A foreign multinational oil consortium, Oil Monopoly Alliance Regime (OMAR), was determined to monopolize the world oil trade. The U.S. was the last country that stood in their way and they were prepared to go to any length to bring the U.S. to its knees.\r\nOMAR hired Sid Burn, a professional terrorist, to push the U.S. economy over the edge. Sid began to organize his troops in the remote areas of the southwest. Calling themselves the \"Coyotes,\" they began to target oil refineries, commercial installations and other vital industry throughout the region. With the law enforcement in the cities, some desperate civilians began to take the law into their own hands. Led by a trucker named Convoy and referred to simply as the \"Vigilantes,\" this oddball group soon became a major hindrance to Sid.\r\nMeanwhile, the U.S. government, feeling more vulnerable than ever, was intensifying its research and development of a new military arsenal. The most advanced weaponry, rumored to be based on UFO technology, was located at Site-4, a secret facility at Papoose Lake. This information was not lost on Sid, and the Coyotes ambushed the facility. However the Vigilantes unexpectedly appeared to stop them and as a result, both parties found themselves in possession of the world's most advanced weaponry.\r\nWhat followed were no ordinary skirmishes. Auto clashes ensued all over the land, from Colorado's Rockies to California's farmlands, only to culminate in a battle like no other. To this day the events which took place are only a matter of speculation.", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [5102], 'genres' => [1, 8, 19], 'publishers' => [33], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 965, 'game_title' => 'Shadow of the Beast II', 'release_date' => '1994-06-07', 'platform' => 21, 'overview' => 'Combining non-stop battle action with perplexing puzzle solving, Shadow of the Beast II thrusts you into a dark and mysterious world where wits and combat-hardened game playing skills are your only defense. Take the action to the limit as you fight a relentless onslaught of monsters and ogres. Bashing them into submission, you make your way through a labyrinth of adventure and enter final confrontation with the Beast Mage!', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7109], 'genres' => [1], 'publishers' => [135], 'alternates' => ['Beast II'], 'uids' => nil, 'hashes' => nil }, { 'id' => 966, 'game_title' => 'Exo-Squad', 'release_date' => '1995-05-19', 'platform' => 36, 'overview' => 'The player alternatively assumes the roles of three members of the Able Squad: Lt. J.T. Marsh, Sgt. Rita Torres and Wolf Bronsky.', 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [558], 'genres' => [8], 'publishers' => [144], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 967, 'game_title' => 'Golden Axe II', 'release_date' => '1991-12-26', 'platform' => 18, 'overview' => 'The three playable characters from the first Golden Axe, Ax Battler, Tyris Flare, and Gilius Thunderhead, return in Golden Axe II to fight the new evil forces led by Dark Guild. The game features a total of seven levels: six scrolling levels and a final end of game boss battle against Dark Guild.', 'youtube' => 'LI-jS0iraxo', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [1], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 969, 'game_title' => 'Pirates! Gold', 'release_date' => '1993-01-01', 'platform' => 18, 'overview' => "Pirates! is a single-player game. The player receives a letter of marque authorizing service as a privateer for Spain, the Dutch Republic, England, or France in the Caribbean. The player's loyalties may change over the course of the game; he may also hold rank with multiple countries and may turn to piracy at any time. Gameplay is open-ended; the player may choose to attack enemy ships or towns, hunt pirates, seek buried treasure, rescue long-lost family members, or even avoid violence altogether and seek to increase his wealth through trade. The game also has no predetermined end, although as time goes on, it becomes more difficult to recruit crew members. Also, as the player character ages, fighting becomes more difficult, and deteriorating health will eventually force the character into retirement. The game ends when the player retires, at which point he is given a position in his future life, from beggar to King's adviser, based on accumulated wealth, land, rank, marital status, and other accomplishments.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5483], 'genres' => [1, 2, 6], 'publishers' => [196], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 970, 'game_title' => 'Smash T.V.', 'release_date' => '1991-09-01', 'platform' => 7, 'overview' => "Moving from one room to the next within the studio/arena, players have to shoot down hordes of enemies as they advance from all sides, while at the same time collecting weapons, power-up items, and assorted bonus prizes until a final show down with the show's host where you are finally granted your prizes, your life and freedom. One of the enemies is fat and is named Mr. Shrapnel who roams aside of the walls of some rooms and after a short period of time he explodes. In the NES version, he is replaced by a giant rolling bomb.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9635], 'genres' => [8], 'publishers' => [197], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 971, 'game_title' => 'Streets of Rage', 'release_date' => '1991-08-02', 'platform' => 18, 'overview' => "Axel, Adam and Blaze - ex-cops, the solution to punk pollution. The city's a war zone, and they're going out two at a time to give the gangs a kick in the guts. This is the ultimate in street combat. These city fighters are martial arts maniacs with a battery of 40 individually controllable attacks - including jabs, head butts, and overhead kicks. They're up against a mob of Kung-Fu creeps and axe-hurling fiends. On the streets it's only two of them against hordes of attacking scum. Slam into pipe-wielding weirdos and bash 'em with their own metal. Throw an uppercut or an elbow smash - these goons keep comin'!", 'youtube' => nil, 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [7549], 'genres' => [1, 10], 'publishers' => [15], 'alternates' => ['Bare Knuckle'], 'uids' => nil, 'hashes' => nil }, { 'id' => 972, 'game_title' => 'X-Men 2: Clone Wars', 'release_date' => '1995-08-17', 'platform' => 18, 'overview' => "The X-Men engage in a battle so world-threatening, even Magneto switches sides! Mutantkind races to the edge of oblivion at the hands of an evil techno-bio cloning organism... the Phalanx! Be Wolverine, Cyclops, Gambit, Nightcrawler, Beast, Psylocke and for the first time ever... play as Magneto! X-Men are at their fiercest with Cyclops' optic blast, Wolverine's slashing adamantium claws and Gambit's hyper-charged cards! Use each mutant's super-powered attack to defend the world!", 'youtube' => nil, 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [3762], 'genres' => [1], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 973, 'game_title' => 'Metal Slug X', 'release_date' => '1999-03-18', 'platform' => 24, 'overview' => 'A revised version of Metal Slug 2, titled Metal Slug X, was released on March 1999 for the Neo Geo MVS. It fixed problems with slowdown present in Metal Slug 2, and increased the difficulty. Metal Slug X also introduced a few new elements to the Metal Slug 2 game system. New weapons and items were added, such as the "Iron Lizard" and the "Drop Shot". The enemy placement and bosses were re-arranged as well.', 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7885], 'genres' => [1, 8], 'publishers' => [60], 'alternates' => ['mslugx'], 'uids' => nil, 'hashes' => nil }, { 'id' => 974, 'game_title' => 'Fatal Fury', 'release_date' => '1991-12-20', 'platform' => 6, 'overview' => "The plot of Fatal Fury centers around a martial arts tournament known as the \"King of Fighters\" tournament, held in the fictional American city of South Town and sponsored by local crime boss Geese Howard. Ten years prior to the events of the game, Geese murdered a rival martial artist named Jeff Bogard who was on his trail. Now, Jeff's sons, Terry and Andy, along with their friend Joe Higashi, enter the tournament to get their revenge on Geese.", 'youtube' => nil, 'players' => 2, 'coop' => nil, 'rating' => nil, 'developers' => [7885], 'genres' => [10], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 975, 'game_title' => 'Fatal Fury 2', 'release_date' => '1993-03-05', 'platform' => 18, 'overview' => "After Geese Howard's death in the original Fatal Fury, a mysterious nobleman becomes the sponsor of the new \"King of Fighters\" tournament. This time, the tournament is held worldwide with fighters around the globe competing. As the single player mode progresses, the mysterious challenger begins defeating the participants from the previous Fatal Fury game, searching for the man responsible for defeating Geese.", 'youtube' => 'https://www.youtube.com/watch?v=EChzW0Kvd-4', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [7885], 'genres' => [10], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 976, 'game_title' => 'Ghost Pilots', 'release_date' => '1991-07-01', 'platform' => 24, 'overview' => "The gameplay is straightforward with elements similar to that of Capcom's 19XX games, but it is incredibly difficult even on the easiest difficulty level. Unlike most scrolling shooters, the vehicle is a seaplane instead of spaceship or airplane. As the in-game instructions indicate, move the joystick around to maneuver the seaplane. Press the A Button to fire bullets. The player can also hold the A button for a semi-automatic fire. Press the B Button to launch bombs from the inventory. The player starts with 3 bombs.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [7885], 'genres' => [1, 8], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 977, 'game_title' => "The King of Fighters '94", 'release_date' => '1994-10-01', 'platform' => 24, 'overview' => "Rugal Bernstein is an incredibly rich and notorious arms and drug trafficker, as well as an incredibly skilled and ruthless fighter. Having become bored with the lack of competition, Rugal decides to host a new King of Fighters tournament. Rugal has his secretary travel to eight destinations around the world and invite fighters to his new tournament. Unlike the previous KOF tournaments depicted in the Fatal Fury series, the new King of Fighters is a team tournament, with eight teams of three, each representing a different nationality, participating this time. Most characters come from other SNK games, such as Team Italy, which is composed of three heroes from the original Fatal Fury: Terry Bogard, Andy Bogard and Joe Higashi. The two heroes from Art of Fighting (Ryo Sakazaki and Robert Garcia) are featured along with their mentor and Ryo's father (Takuma Sakazaki) make up Team Mexico. Team Korea features Kim Kaphwan from Fatal Fury 2 as the leader of two convicts he's trying to reform Chang Koehan and Choi Bounge, while Team England is a mix of female fighters from Fatal Fury 2 (Mai Shiranui) and the Art of Fighting series (Yuri Sakazaki, King). The two heroes from Psycho Soldier (Athena Asamiya and Sie Kensou) form Team China along with their mentor, Chin Gentsai. Similarly, Team Brazil features the heroes from Ikari Warriors (Ralf and Clark) along with their commanding officer Heidern. Additionally, the game features two teams composed entirely of original characters: Team Japan featuring Kyo Kusanagi, Benimaru Nikaido and Goro Daimon, and Team USA composed of Heavy D!, Lucky Glauber and Brian Battler.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [7885], 'genres' => [10], 'publishers' => [60], 'alternates' => ['kof94'], 'uids' => nil, 'hashes' => nil }, { 'id' => 978, 'game_title' => "The King of Fighters '95", 'release_date' => '1995-09-01', 'platform' => 24, 'overview' => "The King of Fighters '95 marks the beginning of a story arc that later became known as the \"Orochi Saga\". However, the only elements from the Orochi Saga known in this game is the introduction of Kyo's rival, Iori Yagami, and Rugal's use of the Orochi power\r\n\r\nRugal Bernstein, thought to have perished in an explosion in the previous game, had in fact survived and sent out invitations to the teams from the previous game signed simply 'R'. Only one of the previous teams failed to attend the new tournament: the American Sports Team, now replaced by the \"Rival Team\" consisting of Iori Yagami, Billy Kane (from Fatal Fury: King of Fighters), and Eiji Kisaragi (from Art of Fighting 2). Saisyu Kusanagi, Kyo's father, appears as a fighter for the first time (having made a non-playable cameo in KOF '94) as a computer-controlled sub-boss character. After defeating Saisyu in the arcade mode, it is revealed that Saisyu was being brainwashed and that Rugal will fight once again as a boss character, but as an enhanced version named \"Omega Rugal\".", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [7885], 'genres' => [10], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 979, 'game_title' => "The King of Fighters '96", 'release_date' => '1996-07-30', 'platform' => 24, 'overview' => "A new King of Fighters tournament was announced, though the letters of invitation sent out to the fighters were no longer sent by Rugal Bernstein. The letters also announced many changes, the first of which being a massive overhaul of the tournament's approach. During the time that had passed between the tournaments since the previous year, the King of Fighters tournament's fame had grown immensely, to the point that it turned into a major international event, which had not happened before. Huge corporations transformed the King of Fighters tournament into something widely televised, commercialized, and celebrated, drawing in many crowds from around the world. The tournament is now held by Chizuru Kagura: a descendant of the ancient Yata Clan responsible for sealing the Orochi demon along with the Kusanagi and Yasanaki clan (the clans from Kyo Kusanagi and Iori Yagami, respectively). Chizuru uses the tournament in hopes of finding and recruiting Kyo and Iori in order to stop the upcoming Orochi threat, but Kyo and Iori aren't exactly willing to work together on friendly terms.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [7885], 'genres' => [10], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 980, 'game_title' => "The King of Fighters '97", 'release_date' => '1997-09-25', 'platform' => 24, 'overview' => 'Despite the events at the end of the previous game, the KOF tournament was a huge commercial success and sparked a worldwide fighting craze. Within a few months of the tournament ending, various large corporations had held smaller KOF tournament qualifiers and constructed special KOF stadiums around the world, building the excitement up for the next tournament. News of the tournament spread through every form of media and fans and new fighters from across the globe come to watch the preliminary matches.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [7885], 'genres' => [10], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 981, 'game_title' => "The King of Fighters '99: Millennium Battle", 'release_date' => '1999-09-23', 'platform' => 24, 'overview' => "Two years have passed since the last King of Fighters tournament and no-one has seen Kyo Kusanagi or Iori Yagami since they defeated Orochi at the climax of the 1997 tournament, but out of the blue, new invitations are sent out to many characters, inviting them to a brand new tournament, though this competition is more of a secretive affair than the ones in '96 and '97. Unlike in previous games of the series, there are four characters per team instead of three. In total, there are seven teams, each containing four characters, four Team Edit characters and a boss.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [7885], 'genres' => [10], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 982, 'game_title' => 'Magical Drop II', 'release_date' => '1996-04-19', 'platform' => 24, 'overview' => "Magical Drop is played in a style and gameplay similar to Compile's (now Sega's) Puyo Puyo and Taito's Puzzle Bobble franchises; a \"stack\" of random colored bubbles descend from the top, and a player is defeated when a bubble hits the bottom. Bubbles can be picked up and dropped by the player's \"clown\" at the bottom, and are destroyed when three or more of the same color are put together on a single column. \"Chains\" are formed either when a single drop caused a chain reaction, or when more than one group of bubbles is destroyed in quick succession. The game is normally played with two players (one may be a computer opponent), and chains cause the opponent's stack to descend faster.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2126], 'genres' => [5], 'publishers' => [60], 'alternates' => ['Magical Drop 2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 983, 'game_title' => 'Magical Drop III', 'release_date' => '1997-04-25', 'platform' => 24, 'overview' => "Magical Drop is played in a style and gameplay similar to Compile's (now Sega's) Puyo Puyo and Taito's Puzzle Bobble franchises; a \"stack\" of random colored bubbles descend from the top, and a player is defeated when a bubble hits the bottom. Bubbles can be picked up and dropped by the player's \"clown\" at the bottom, and are destroyed when three or more of the same color are put together on a single column. \"Chains\" are formed either when a single drop caused a chain reaction, or when more than one group of bubbles is destroyed in quick succession. The game is normally played with two players (one may be a computer opponent), and chains cause the opponent's stack to descend faster.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [2126], 'genres' => [5], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 984, 'game_title' => 'Samurai Shodown II', 'release_date' => '1994-10-28', 'platform' => 24, 'overview' => "One of SNK's legendary fighting game series has made a return! In Samurai Shodown II, you can take on one of the roles of 15 warriors as you fight your way through the land to defeat the evil Mizuki! Slash, kick, and slice your opponents in half...do whatever it takes...live by the sword, and die by its blade.", 'youtube' => 'https://www.youtube.com/watch?v=CLrR5CUqHQA', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7885], 'genres' => [10], 'publishers' => [60], 'alternates' => ['samsho2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 985, 'game_title' => 'Samurai Shodown IV', 'release_date' => '1996-10-25', 'platform' => 24, 'overview' => "Bringing a new breath to SNK's swordsman fighting series, this 4th installment marks the return of 3 classic characters (Yagyu Jubei, Charlotte and Tam Tam, now with updated stuff), introduces 2 newcomers for the pantheon (the brothers Sogetsu Kazama and Kazuki Kazama) and brings some new backgrounds.\r\n\r\nIn spite of these little improvements, the game preserved (and improved a lot) many elements that did the previous one (Samurai Shodown III: Blades of Blood) a quite popular title, like the dodge move and the chance to choose between two versions of the fighter: the standard one and an alternative dark-styled one (SLASH and BUST, respectively).", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [7885], 'genres' => [10], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 988, 'game_title' => 'World Heroes', 'release_date' => '1992-01-01', 'platform' => 24, 'overview' => 'World Heroes is a versus fighting game. It features a cast of characters from different countries and time periods, ranging from ninjas to a cybernetic super-soldier. The characters are based on real historical figures, but are endowed with supernatural powers. The player selects a character who then fights his way through standard one-on-one matches or takes on an opponent in a Deathmatch, where spiked walls and landmines add to the danger.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [256], 'genres' => [10], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 989, 'game_title' => 'World Heroes 2', 'release_date' => '1993-06-04', 'platform' => 24, 'overview' => "The general premise in the series is that a scientist, Dr. Brown, having perfected a time machine, organized a tournament for various fighters throughout all of history to combat each other to see who is the world's mightiest fighter. True to this plot, many of the fighters are based on actual historical figures.\r\nThis game also marked the debut of Jack and Ryofu, which many players considered to be unfairly powerful.", 'youtube' => 'V5oCoQgu_Qc', 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [256], 'genres' => [10], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 990, 'game_title' => 'World Heroes Perfect', 'release_date' => '1995-06-07', 'platform' => 24, 'overview' => 'The general premise is that a scientist, Dr. Brown, having perfected a time machine, organized a tournament for various fighters throughout all of history to combat each other. True to this plot, many of the fighters are based on actual historical figures. There are 19 fighters to pick from.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [256], 'genres' => [10], 'publishers' => [60], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 991, 'game_title' => 'TimeShift', 'release_date' => '2007-10-17', 'platform' => 1, 'overview' => "The key feature of TimeShift is the player's ability to control time: slowing, stopping or even rewinding time more or less at will. This allows a player to stop time to dodge an incoming projectile or steal an enemy's weapon. Specific time-related puzzles also require these abilities. The player's abilities also affect the color of their environment in such that slowing time produces a blueshift, rewinding it produces a yellow haze, and stopping time creates a white filter \"haze\". The player must use them wisely to make its way through the game. In some parts of the game your time powers are lengthened.", 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [7374], 'genres' => [8], 'publishers' => [32], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 992, 'game_title' => 'Vanquish', 'release_date' => '2010-10-19', 'platform' => 12, 'overview' => "Vanquish takes place in the near future where Earth's human population has grown so rapidly that nations are fighting for the scarce remaining resources. The United States of America has attempted to alleviate its energy problems by launching an O'Neill Cylinder space station harboring a solar energy-driven generator to provide them with an alternative source of energy. However, the government of the Russian Federation has been overthrown in a coup d'état by ultra-nationalist forces calling themselves the Order of the Russian Star.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1829], 'genres' => [8], 'publishers' => [15], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 993, 'game_title' => 'The Lord of the Rings: The Battle for Middle-Earth', 'release_date' => '2004-12-06', 'platform' => 1, 'overview' => "The Lord of the Rings, The Battle for Middle-earth is an unprecedented real-time strategy (RTS) game that delivers the epic scope and depth of J.R.R. Tolkien's amazing world. In a game that the press is already calling \"visually stunning\" and \"nothing short of magnificent,\" you are in complete control of the epic battles as depicted in all three installments of the blockbuster The Lord of the Rings movie trilogy. From waging all-out combat among Middle-earth's vast armies to controlling your favorite heroes to fully managing the resources of your side, the fate of a living, breathing Middle-earth is in your hands.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [2724], 'genres' => [4, 6], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 994, 'game_title' => 'The Lord of the Rings: The Battle for Middle-Earth II', 'release_date' => '2006-03-02', 'platform' => 1, 'overview' => "BFMEII is a real-time strategy game. Similar to The Lord of the Rings: The Battle for Middle-earth, the game requires that the player build a base with structures to produce units, gather resources, research upgrades, and provide defenses. Units are used to attack the enemy and defend the player's base. Players win matches by eliminating all enemy units and structures. Unlike the first game, the player can build an unlimited number of structures anywhere on the map, allowing for more freedom in base building and unit production. Players can build fortresses to defend their base. They can also construct arrow and catapult towers on building plots around a fortress to provide defensive support, and build walls adjacent to fortresses in any direction and length to provide basic protection. The game's HUD, called the Palantír, shows the player's hero units and their abilities, a mini-map, and objectives.", 'youtube' => nil, 'players' => nil, 'coop' => nil, 'rating' => 'T - Teen', 'developers' => [2579], 'genres' => [4, 6], 'publishers' => [35], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 997, 'game_title' => 'Earthworm Jim', 'release_date' => '1994-08-02', 'platform' => 6, 'overview' => "A crow is chasing a worm named Jim while in outer space Psy-Crow is chasing a renegade ship. The ship's captain has stolen an ultra-high-tech-indestructible-super-space-cyber-suit and Queen Slug-for-a-Butt has ordered Psy-Crow to get it, since it can make her more beautiful than Princess-What's-Her-Name. Psy-Crow blasts the captain and the suit falls to Planet Earth.\r\n\r\nBack on earth Jim wonders if he is finally safe when an ultra-high-tech-indestructible-super-space-cyber-suit lands on him. Luckily Jim rests in the neck ring of the suit. Then the space particles begin interacting with Jim, causing a light-speed evolution. Jim soon realizes he is in control of the suit.\r\n\r\nJim overhears the Queen's plans for the suit and decides to meet this Princess...", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7663], 'genres' => [1, 2, 15], 'publishers' => [144], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 999, 'game_title' => "Shellshock: Nam '67", 'release_date' => '2004-09-14', 'platform' => 1, 'overview' => nil, 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => nil, 'genres' => nil, 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1000, 'game_title' => 'Legend of Mir 2', 'release_date' => '2001-09-19', 'platform' => 1, 'overview' => nil, 'youtube' => 'Rdq7WMyuILE', 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => [9582], 'genres' => [4, 14], 'publishers' => [200], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1001, 'game_title' => 'Fantasy Earth Zero', 'release_date' => '2006-02-23', 'platform' => 1, 'overview' => nil, 'youtube' => nil, 'players' => nil, 'coop' => 'No', 'rating' => nil, 'developers' => nil, 'genres' => nil, 'publishers' => nil, 'alternates' => ['Fantasy Earth: The Ring of Dominion', 'Fantasy Earth Zero Armudo Edition'], 'uids' => nil, 'hashes' => nil }, { 'id' => 1002, 'game_title' => 'Operation Flashpoint: Red River', 'release_date' => '2011-06-07', 'platform' => 1, 'overview' => "Operation Flashpoint: Red River is a tactical shooter. The player has the choice of playing the campaign co-operatively.[1] However, the game does not feature competitive multiplayer. The game does not feature a mission editor or SDK.[2] The player will be able to choose between four classes of Marines; rifleman, grenadier, scout, and automatic rifleman, each with their own weapons and abilities.[3] The player will gain experience during gameplay, which can be used to unlock weapons, attachments and perks. For example, a scout could acquire an enhancement that will reduce the amount of bullet drop.[4] The game's director Sion Lenton said \"Operation Flashpoint: Red River is being built around four player co-op online play, complete with a strong narrative, new enemies and combat scenarios to deliver gameplay that immerses players in the reality of war like never before.\"[5] The enemies will be able to kill the player with a single shot.[6] The single player campaign will be divided into three distinct acts.[7]\r\n\r\nThe game uses a video camera style feedback in the game for the action. With shots near the player getting dirt in the players vision similar to a lens would, and damage scrambling the screen, along with losing stamina causes parts of the screen to scramble and freeze in some places until the player rests.", 'youtube' => 'BzbMgbP21r8', 'players' => nil, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => nil, 'genres' => nil, 'publishers' => nil, 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1003, 'game_title' => 'Mega Man X Collection', 'release_date' => '2006-01-10', 'platform' => 11, 'overview' => 'Mega Man X Collection contains the first six games in the Mega Man X series. Mega Man X and Mega Man X2 are based on their appearances on the SNES. Mega Man X3, also originally on the SNES, is based on its 32-bit update for the PlayStation, Sega Saturn, and PC. The remaining three games are based on their PlayStation renditions. All the games now use save files, including the first few titles that originally necessitated a password for continuation, though upon loading save data, the player is still greeted with the old, fully-functional password entry screen, complete with the correct password to access the saved game. Mega Man Battle & Chase is a game that is unlocked after completing the first three games. It is a classic series kart-racing game previously unreleased in North America. Mega Man X Collection also contains unlockable artwork and music. Both the PlayStation 2 and GameCube versions are identica', 'youtube' => '', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => nil, 'uids' => [{ 'uid' => 'SLUS-21370', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 1004, 'game_title' => 'Psychonauts', 'release_date' => '2005-04-19', 'platform' => 11, 'overview' => "The story is set in Whispering Rock Psychic Summer Camp, a remote US government training facility under the guise of a children's summer camp. The area was hit centuries ago by a meteor made of psitanium (a fictional element that can grant psychic powers or strengthen existing powers), creating a huge crater. The psitanium affected the local wildlife, giving them limited psychic powers, such as bears with the ability to attack with telekinetic claws and cougars with pyrokinesis. The Native Americans of the area called psitanium \"whispering rock\", which they used to build arrowheads. When settlers began inhabiting the region, the psychoactive properties of the meteor slowly drove them insane. An asylum was built to house the afflicted, but within fifteen years the asylum had more residents than the town did. The government relocated the remaining inhabitants and flooded the crater to prevent further settlement, creating what is now Lake Oblongata. The asylum still stands but has fallen into disrepair.", 'youtube' => 'MeQu0kkcHHA', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [1361], 'genres' => [2], 'publishers' => [201], 'alternates' => nil, 'uids' => [{ 'uid' => 'SLUS-21120', 'games_uids_patterns_id' => 2 }], 'hashes' => nil }, { 'id' => 1005, 'game_title' => 'Chrono Cross', 'release_date' => '1999-11-18', 'platform' => 10, 'overview' => "Chrono Cross features standard RPG gameplay with some differences. Players advance the game by controlling the protagonist Serge through the game's world, primarily by foot and boat. Navigation between areas is conducted via an overworld map, much like Chrono Trigger's, depicting the landscape from a scaled down overhead view. Around the island world are villages, outdoor areas, and dungeons, through which the player moves in three dimensions. Locations such as cities and forests are represented by more realistically scaled field maps, in which players can converse with locals to procure items and services, solve puzzles and challenges, or encounter enemies. Like Chrono Trigger, the game features no random encounters; enemies are openly visible on field maps or lie in wait to ambush the party", 'youtube' => 'U709nJ_AQ-s', 'players' => 1, 'coop' => 'No', 'rating' => 'T - Teen', 'developers' => [8096], 'genres' => [4], 'publishers' => [11], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1006, 'game_title' => 'Crash Bandicoot', 'release_date' => '1996-08-31', 'platform' => 10, 'overview' => "Crash Bandicoot, a heroic, agile and mutated marsupial who must save his girlfriend Tawna. The main antagonist is Doctor Neo Cortex, a mad scientist who was often ridiculed by the scientific community for his outlandish (but nearly workable) theories and is now motivated to prove his tormentors wrong by creating a mutated army of beasts to conquer the world. Cortex's henchman is Doctor Nitrus Brio, the insecure creator of the Evolvo-Ray. Crash's love interest is Tawna, a female bandicoot about to undergo experimentation by the Doctors. Helping Crash in his journey is an ancient witch doctor spirit named Aku Aku, who has scattered masks of himself throughout the islands to grant Crash special powers. The boss characters of the game include Papu Papu, the obese and short-tempered chief of the native village; Ripper Roo, a demented kangaroo with razor-sharp toenails; Koala Kong, a muscular but unintelligent koala; and Pinstripe Potoroo, the tommy gun-wielding bodyguard of Doctor Cortex.", 'youtube' => 'y-XTPz77Omk', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5839], 'genres' => [2, 15], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1007, 'game_title' => 'Crash Team Racing', 'release_date' => '1999-09-30', 'platform' => 10, 'overview' => "The main antagonist of the story, Nitros Oxide, is the self-proclaimed fastest racer in the galaxy who threatens to turn Earth into a concrete parking lot. Preceding Oxide are four boss characters: Ripper Roo, a deranged straitjacket-wearing kangaroo; Papu Papu, the morbidly obese leader of the island's native tribe; Komodo Joe, a Komodo dragon with a speech sound disorder; and Pinstripe Potoroo, a greedy pinstripe-clad potoroo. The four boss characters, along with an imperfect and morally ambiguous clone of Crash Bandicoot named Fake Crash, become accessible as playable characters if the Adventure Mode is fully completed.", 'youtube' => 'GIQMlAazZds', 'players' => 4, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5839], 'genres' => [7], 'publishers' => [14], 'alternates' => ['Crash Bandicoot Racing'], 'uids' => nil, 'hashes' => nil }, { 'id' => 1008, 'game_title' => 'Gran Turismo 2', 'release_date' => '1999-12-11', 'platform' => 10, 'overview' => "Gran Turismo 2 is fundamentally based on the racing game genre. The player must maneuver an automobile to compete against artificially intelligent drivers on various race tracks. The game uses two different modes: arcade and simulation. In the arcade mode, the player can freely choose the courses and vehicles they wish to use. However, the simulation mode requires the player to earn driver's licenses, pay for vehicles, and earn trophies in order to unlock new courses. Gran Turismo 2 features nearly 650 automobiles and 27 racing tracks.", 'youtube' => '0JXqpK6slp4', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6739], 'genres' => [7], 'publishers' => [14], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1009, 'game_title' => 'Jet Moto', 'release_date' => '1996-10-31', 'platform' => 10, 'overview' => 'Gameplay in the Jet Moto series differs traditional racing games, as players instead control hoverbikes which hover close above the ground and can be driven over both land and water. Most of the courses in the games are designed to take advantage of this ability. The game has a its variant of the traditional road course, but also introduces a new course type, known as a suicide course. Instead of being a continuous loop, these tracks have checkpoints at either end of the course, and the starting grid in the center. Characters race to one end, then turn around to head for the other checkpoint, repeating the process until all laps are complete. This provides a new gameplay dynamic as often the player must navigate oncoming traffic.[1] Characters are split into teams, and bikes are adorned with logos of products such as Mountain Dew and Butterfinger, similar to real-life sponsored racing.', 'youtube' => '_VnRQwX1YQI', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7778], 'genres' => [7], 'publishers' => [20], 'alternates' => ['Jet Rider'], 'uids' => nil, 'hashes' => nil }, { 'id' => 1010, 'game_title' => 'Jet Moto 2', 'release_date' => '1997-09-17', 'platform' => 10, 'overview' => "Gameplay in the Jet Moto series differs traditional racing games, as players instead control hoverbikes which hover close above the ground and can be driven over both land and water. Most of the courses in the games are designed to take advantage of this ability. \r\nThe game has a its variant of the traditional road course, but also introduces a new course type, known as a suicide course. Instead of being a continuous loop, these tracks have checkpoints at either end of the course, and the starting grid in the center. Characters race to one end, then turn around to head for the other checkpoint, repeating the process until all laps are complete. This provides a new gameplay dynamic as often the player must navigate oncoming traffic. Characters are split into teams, and bikes are adorned with logos of products such as Mountain Dew and Butterfinger, similar to real-life sponsored racing.", 'youtube' => 'WxcOkTe9NXM', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [135], 'genres' => [7, 11], 'publishers' => [202], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1011, 'game_title' => 'Jet Moto 3', 'release_date' => '1999-08-31', 'platform' => 10, 'overview' => 'Gameplay in the Jet Moto series differs traditional racing games, as players instead control hoverbikes which hover close above the ground and can be driven over both land and water. Most of the courses in the games are designed to take advantage of this ability. The game has a its variant of the traditional road course, but also introduces a new course type, known as a suicide course. Instead of being a continuous loop, these tracks have checkpoints at either end of the course, and the starting grid in the center. Characters race to one end, then turn around to head for the other checkpoint, repeating the process until all laps are complete. This provides a new gameplay dynamic as often the player must navigate oncoming traffic.Characters are split into teams, and bikes are adorned with logos of products such as Mountain Dew and Butterfinger, similar to real-life sponsored racing.', 'youtube' => '0td5d8ot8mE', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6363], 'genres' => [7], 'publishers' => [21], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1012, 'game_title' => 'Need for Speed III: Hot Pursuit', 'release_date' => '1998-09-27', 'platform' => 10, 'overview' => "Hot Pursuit remains focused in racing using exotic sports cars, but features races that primarily take place in locations within North America, including varied settings and climates. In addition, police AI is significantly improved over its predecessor, utilizing several tactics to stop both the player and opponent. The game was released for PlayStation in March 1998 and later received an enhanced port for Microsoft Windows in September 1998. A PlayStation 2 version was developed, however it was cancelled. During the Electronic Arts Keynote on June 14, 2010 EA announced that a new Need for Speed game under the same name, scheduled for released on November 16, 2010. The game title's suffix, \"Hot Pursuit\", is a term for a police pursuit.", 'youtube' => 'Qe3boVLNeSU', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [2570], 'genres' => [7], 'publishers' => [2], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1013, 'game_title' => 'Resident Evil 3: Nemesis', 'release_date' => '1999-09-22', 'platform' => 10, 'overview' => "Join Jill Valentine, the heroine and amazing survivor of the notorious disaster at the mansion, as her nightmare continues. After resigning from S.T.A.R.S. Jill now prepares to head out of Raccoon City...but it's not going to be easy. Caught in a town crawling with flesh eating zombies, more than ever she must rely on brute force and cunning to find a way to escape alive. This unique adventure intricately reveals more of Umbrella Corporation's nightmarish plot and picks up just hours before the events from Resident Evil 2.\r\n\r\nMore zombies, more terror, and even more evil.\r\nMore challenging enemies that come back to life at any time.\r\nFace off against the most terrifying mutations stalking the streets of Raccoon City.\r\nMore detailed character actions: Try the dodge move to avoid an enemy's attack.\r\nInteract with the environment like never before: Use background objects defensively.\r\nA unique new drama which reveals more details of Umbrella Corporation's devious activities from the Resident Evil series.", 'youtube' => 'spDD7fxVETQ', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [1436], 'genres' => [2, 8], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1014, 'game_title' => 'Silent Hill', 'release_date' => '1999-01-31', 'platform' => 10, 'overview' => "Silent Hill is a 1999 survival horror video game for the PlayStation. The first in a series about a mysterious town of the same name, Silent Hill generated a direct sequel, three indirect sequels, a prequel and a film adaptation. The game was included in Sony's Greatest Hits and Platinum Range of budget titles as a result of strong sales. A reinterpretation of the game was developed for the Wii, PlayStation 2 and PlayStation Portable.\r\nThe plot focuses on Harry Mason as he searches for his daughter, Cheryl, who has disappeared following a car accident which left Harry unconscious. He finds Silent Hill to be largely abandoned, shrouded in a thick fog, snowing out of season, filled with monsters and being over taken by a hellish otherworld. As Harry scours the town, he begins learning about the history of Silent Hill and stumbles upon a cult ritual undertaken to bring a god to Earth.", 'youtube' => 'URD929802zk', 'players' => 1, 'coop' => 'No', 'rating' => 'M - Mature', 'developers' => [4765, 10_302], 'genres' => [1, 18], 'publishers' => [140], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1015, 'game_title' => 'Mega Man X2', 'release_date' => '1995-01-27', 'platform' => 6, 'overview' => "Just when Mega Man X thought he had brought down all the X-Hunters, several months later an uprising moves from within an abandoned factory. While 8 all-new X-Hunters occupy Mega Man X, a triple threat plots to resurrect a secret weapon that is all too familiar!\r\n\r\nThe good Dr. Light supplies Mega man X with incredible new abilities hidden in capsules buried deep below the surface. And with new vehicles like the mobile attack cycle plus powers he gains from the X-Hunters, Mega Man X will be ready to face his destiny as a Maverick Hunter. Now it's all or Zero for Mega Man X!", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => ['Megaman X2', 'Rockman X2'], 'uids' => nil, 'hashes' => nil }, { 'id' => 1016, 'game_title' => 'Mega Man X3', 'release_date' => '1996-01-26', 'platform' => 6, 'overview' => "Mega Man X and his trusty partner Zero have a new force to reckon with. Who or what has caused a riot of Mavericks to break out in the experimental utopia known as Doppler Town?\r\n\r\nNamed after the scientist reploid, Doppler Town was supposed to be a place where humans and reploids could live in harmony. After discovering a virus that was turning reploids to Mavericks, Doppler's anti-virus was a big success. But Doppler itself became infected with the virus and assembled a team to take out the Maverick Hunter Units. The Doppler Effect is about to unfold, with Mega Man X and Zero the only cure for the deadly virus!", 'youtube' => 'https://www.youtube.com/watch?v=lcD55YjTh8I', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => ['Megaman X3', 'Rockman X3'], 'uids' => nil, 'hashes' => nil }, { 'id' => 1017, 'game_title' => "Disney's 102 Dalmatians: Puppies to the Rescue", 'release_date' => '2000-11-08', 'platform' => 10, 'overview' => "The game itself follows the films' storyline loosely. The player can choose the role of one of two dalmatians, Oddball or Domino, who are out in the backyard looking for treasure. It is not long before the player realizes that a toy found buried in a park was made at one of Cruella de Vil's toy factories; this alludes to the fact that Cruella's toy sales are down, which ultimately leads to the problem in the storyline. Facing financial ruin from lack of sales, Cruella sets an evil plan in motion - to reprogram her toys to capture any pets in sight. Oddball and Domino are the only puppies in their family who have not been captured when they return from the park. Their parents, Dottie and Dipstick, set out to rescue their puppies, commanding Oddball and Domino to stay home and 'be good.' The puppies do not listen, and are soon out on their biggest adventure yet - to save their brothers and sisters, and their parents who are captured along the way.", 'youtube' => 'HhR9UQ7KHQM', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8978], 'genres' => [1, 15], 'publishers' => [26], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1018, 'game_title' => '1943: The Battle of Midway', 'release_date' => '1987-06-01', 'platform' => 7, 'overview' => "The game is set in the Pacific theater of World War II, off the coast of the Midway Atoll. The goal is to attack the Japanese Air Fleet that bombed the players' American Aircraft Carrier, pursue all Japanese Air and Sea forces, fly through the 16 levels of play, make their way to the Japanese battleship Yamato and destroy her. 11 Levels consist of an Air-to-Sea battle (with a huge battleship or an aircraft carrier as an End-Level Boss), while 5 levels consist of an all-aerial battle against a squadron of Japanese Bombers and a Mother Bomber that needs to be destroyed.", 'youtube' => 'AHnUzNUsKuc', 'players' => 2, 'coop' => 'Yes', 'rating' => 'E - Everyone', 'developers' => [1436], 'genres' => [8], 'publishers' => [9], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1019, 'game_title' => 'A Nightmare on Elm Street', 'release_date' => '1990-10-01', 'platform' => 7, 'overview' => "Something frightening has been happening on Elm Street lately. It seems that with each waking day another grussome discovery is made... another neighborhood teen has mysteriously passed away into the dark stillness of the night. Everyone says it's \"natural causes,\" but it seems as if something (or someone) has been picking them off one by one in their sleep. It's a horrible nightmare come true... and this nightmare has a name: Freddy Krueger.\r\n\r\nIt's up to you and your remaining friends to search Elm Street for his bones, which have been scattered about then collect and burn them in the High School furnace. If you can just stay awake long enough, you might be able to end Freddy's reign of terror for good. You had better hurry though, it's getting late and you can feel your eyelids getting heavier and heavier by the minute.", 'youtube' => nil, 'players' => 4, 'coop' => 'No', 'rating' => nil, 'developers' => [6991], 'genres' => [1], 'publishers' => [89], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1020, 'game_title' => 'Advanced Dungeons & Dragons: Dragons of Flame', 'release_date' => '1992-02-21', 'platform' => 7, 'overview' => "Advanced Dungeons & Dragons: Dragons of Flame is a role-playing game and the sequel to Advanced Dungeons & Dragons: Heroes of the Lance, developed by Atelier Double and published by Pony Canyon. Its release for the Famicom in 1992 was exclusive to Japan.\r\n\r\nThe dragonmen have taken Solace. Its beautiful tree houses lie black and battered amid the stumps of great vallenwood trees. Kapak Draconians, armed with poisoned weapons, enforce a crutal martial law on the survivors.\r\n\r\nAnd Solace is only one outpost: the dragonarmies control the plains. Only the elven kingdom of Qualinesti stands unconquered. The rest of the plainsmen suffer the most: a long slave caravan hauls hundreds of them to the fortress prison of Pax Tharkas.", 'youtube' => 'vaeSY9-0y18', 'players' => 1, 'coop' => 'No', 'rating' => 'Not Rated', 'developers' => [9135], 'genres' => [4], 'publishers' => [79], 'alternates' => ['Dragons of Flame', 'Dragonlance', 'AD&D: Dragons of Flam', 'ドラゴン・オブ・フレイム', 'Doragon obu Fureimu'], 'uids' => nil, 'hashes' => nil }, { 'id' => 1021, 'game_title' => 'Advanced Dungeons & Dragons: Heroes of the Lance', 'release_date' => '1991-01-01', 'platform' => 7, 'overview' => 'While Heroes of the Lance is a faithful representation of the books it is based on, it was a departure from the usual RPG style of most Dungeons & Dragons games, and many players lamented its difficult game play interface which consists of using one character at a time in horizontally-scrolling fighting. Each character has different types of attacks and spells making them more suited to fighting different enemies but they merely act as "lives" for the player as in more traditional fighting games, removing one of the main strategies of role-playing games from the game.', 'youtube' => '99EvK7nnblg', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [9135], 'genres' => [4], 'publishers' => [110], 'alternates' => ['Heroes of the Lance', 'AD&D: Heroes of the Lance'], 'uids' => nil, 'hashes' => nil }, { 'id' => 1023, 'game_title' => 'Adventure Island II', 'release_date' => '1991-01-01', 'platform' => 7, 'overview' => "Soar into action with Adventure Island II. That Evil Witch Doctor's just snatched your favorite lady. And you've got to battle your way past EIGHT treacherous islands to get her back.\r\nCombat prehistoric monsters -- some of the creepiest, fire-spitting critters ever to slither across a video screen! Survive molten volcanoes. Dodge giant scorpions and king cobras. And the action gets even crazier with a new vertical/horizontal scroll, while stage select lets you control play.\r\nSo sharpen your axe, slip on a leopard skin, and take off for ADVENTURE ISLAND II. It's gonna be a wild ride!!!", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3923], 'genres' => [1, 2, 15], 'publishers' => [74], 'alternates' => ['Adventure Island 2', '高橋å人ã®å†’険島 II', 'Takahashi Meijin no Bouken Jima II'], 'uids' => nil, 'hashes' => nil }, { 'id' => 1024, 'game_title' => 'Adventures in the Magic Kingdom', 'release_date' => '1990-06-01', 'platform' => 7, 'overview' => "This is your ticket to breath-taking Adventures in the Magic Kingdom!\r\n\r\nJoin the exciting adventures as you search through the Magic Kingdom for the six silver keys that will unlock the Enchanted Castle. Use all your skills and resources to achieve your goal.\r\n\r\n-Answer Disney trivia questions to gain access to the attractions\r\n-Become the engineer of a runaway train in Big Thunder Mountain\r\n-Race Autopia cars through a maze of obstacles\r\n-Don your sea-faring garb as you tangle with the swarthy buccaneers of Pirates of the Caribbean\r\n-Hurl yourself into the black holes of Space Mountain\r\n-Grab a silver key from the ghoulish inhabitants of the Haunted Mansion", 'youtube' => 'WpWmhxXf_pU', 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [1436], 'genres' => [1], 'publishers' => [9], 'alternates' => ["Disney's Adventures in the Magic Kingdom"], 'uids' => nil, 'hashes' => nil }, { 'id' => 1025, 'game_title' => 'Adventures of Lolo 3', 'release_date' => '1991-08-09', 'platform' => 7, 'overview' => "The journey continues! The game preferred by the best and the brightest is back with a brand new installment. See if you qualify!\r\n\r\nSeventeen levels, one hundred rooms. Play as either Lolo or Lala. Underwater levels with new challenges. Lolo's Grandpa teaches you the tricks of the game. New tactics, techniques and characters.", 'youtube' => 'oa9CMqdrZjE', 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [3694], 'genres' => [1, 5], 'publishers' => [205], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1026, 'game_title' => 'Airball', 'release_date' => '1987-01-01', 'platform' => 7, 'overview' => 'The player begins every round atop inflating stations. These inflating stations, which are scattered throughout the arenas, also act as checkpoints. Remaining atop an inflating station for too long will cause the player to burst. A bar gauge at the bottom of the screen allows the player to monitor their air level. The game was released for multiple systems on 1987, a version for the NES was under development by Novotrade and Tengen (without a Nintendo license), but cancelled.', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [5466], 'genres' => [5], 'publishers' => [206], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1027, 'game_title' => 'Al Unser Jr. Turbo Racing', 'release_date' => '1989-01-01', 'platform' => 7, 'overview' => "Get ready for racing action like you've never experienced it. Because Al Unser Jr.'s Turbo Racing is so much more than just a game you drive. It's a game you design, a game where everything - from the pit crew to the power boost, from the suspension to the speed, right down to the color of the racing machine itself - is in your control.\r\nAn entire racing season on the world's 16 toughest tracks lies ahead. Each demands its own strategy; Al Jr. will give you advice before every race. In the pusuit of the season's championship, you can set up and modify your own car, or climb behind the wheel of Little Al's maxxed-out machine.\r\nGreat graphics. Astounding action. If you're into racing, Al Unser Jr.'s Turbo Racing puts you into it like no other game around!", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [2126], 'genres' => [7], 'publishers' => [55], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1028, 'game_title' => "Arkista's Ring", 'release_date' => '1990-06-01', 'platform' => 7, 'overview' => 'The Evil Shogun has stolen the ring of Arkista, plunging the Elven Kingdom into darkness and despair. Only one elf, Christine, is brave enough to take up the treacherous challenge to recover the stolen treasure. She must fight, through towns, graveyards, and mazes crawling with hordes of monsters. Yet, with your help, can she make it to the infamous Ninja Dungeon?', 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [6099], 'genres' => [1, 2], 'publishers' => [207], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1029, 'game_title' => 'Astyanax', 'release_date' => '1990-03-08', 'platform' => 7, 'overview' => "Astyanax is a side-scrolling platform game. The controls are fairly simple: the A Button makes Astyanax jump, the B Button will attack with an axe called Bash, and a combination of up and attack will perform a special magic attack. The game also contains a few role-playing elements, such as weapons upgrades. It had a unique feature (for the time) of a bar that grows between attacks; the length of the bar determines how much damage Astyanax will do with his next attack. If one attacks rapidly, one's hits will do little damage, much unlike most games where a rapid succession of hits would all be equally damaging. A very similar system would be used in Secret of Mana some years later.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [299], 'genres' => [15], 'publishers' => [94], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1030, 'game_title' => 'Back to the Future', 'release_date' => '1989-09-01', 'platform' => 7, 'overview' => "You are Marty McFly, just a typical senior at Hill Valley High. But after getting behind the wheel of a nuclear-powered sports car turned time machine, you find yourself in the year 1955 where you've accidentally tampered with history. Now it must be corrected. You must somehow make sure that teenagers Lorraine Baines and George McFly (the two kids that will eventually grow up to become your parents) fall in love before the photo of your family fades away and you're left with nothing to come home to. It won't be easy. You'll have to protect George from Biff and his gang of bullies while doing your best to keep them from beating you up instead. To complicate things, Lorraine has a crush on you, so you'll have to dodge her advances while trying to figure out a way to get George and her to kiss at the school dance. Time is wasting and even if you manage to put all of the pieces in place, there is still no guarantee that you'll get back. It will all come down to one brief moment in time when the past, present and future all meet.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [7946], 'genres' => [1], 'publishers' => [89], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1031, 'game_title' => 'Base Wars', 'release_date' => '1991-06-01', 'platform' => 7, 'overview' => "While maintaining basic baseball elements of pitching, batting, fielding, and base running, Base Wars adds a fighting element to the game featuring four robot classes; a traditional cyborg that looks more like an android, a tank, a flybot, and lastly a motorcycle. A player's robots can be upgraded with new and advanced weaponry and repaired with money earned for game wins during tournaments.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [4765], 'genres' => [11], 'publishers' => [98], 'alternates' => ['Base Wars - Cyber Stadium Series', 'Cyber Stadium Series: Base Wars'], 'uids' => nil, 'hashes' => nil }, { 'id' => 1032, 'game_title' => 'Bases Loaded', 'release_date' => '1987-06-26', 'platform' => 7, 'overview' => "The game allows the player to control one of 12 teams in either a single game or a full season. For single games, there is also a two-player option.\r\nBases Loaded featured a unique television-style depiction of the pitcher-batter matchup, as well as strong play control and a relatively high degree of realism, which made it one of the most popular baseball games of the early NES.\r\nOne unique feature of the game is that the pitcher can provoke a batter to charge the mound. Each team has only one batter (usually the team's best hitter) who can be provoked in this manner, however; it is up to the player to discover who it is.\r\nAt the time Bases Loaded was released, few video games were licensed by major league sports. Therefore, the league depicted in Bases Loaded is a fictitious league of twelve teams", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [4411], 'genres' => [11], 'publishers' => [94], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1033, 'game_title' => 'Bases Loaded 3', 'release_date' => '1991-09-01', 'platform' => 7, 'overview' => "The game is the third installment of the Bases Loaded series. The series spanned three generations of consoles and eight total installments. The original Bases Loaded title was a arcade game that Jaleco ported to the NES. Only the original Bases Loaded was an acrade game; the rest of the series were exclusive to their particular consoles. There are four video games in the Bases Loaded NES series, Bases Loaded II: Second Season, Bases Loaded 3 and Bases Loaded 4. There was also a Game Boy version of Bases Loaded. The series continued onto the SNES platform with Super Bases Loaded, Super Bases Loaded 2, and Super Bases Loaded 3. The final entry to the series was Bases Loaded '96: Double Header, released for the fifth generation consoles Sega Saturn and PlayStation.", 'youtube' => 'sfumppUWRVk', 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8959], 'genres' => [11], 'publishers' => [94], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1034, 'game_title' => 'Batman: Return of the Joker', 'release_date' => '1991-12-20', 'platform' => 7, 'overview' => "The seedy underworld is crawling with criminals. Even worse - the JOKER is back on top of 'em all! Law and order means nothing... until now! Because BATMAN is here - and the action is hotter than ever! Ear-crunching sound effects. Pulse-quickening music. Graphics that are as hot as 16-bit. And this time, BATMAN hits fast and hard. Flying, leaping, and sliding to attack! And striking at the heart of the JOKER. The CAPED CRUSADER has a totally new arsenal at his command: Batarang, Crossbow, Sonic Neutralizer. He's even got a superfueled jetpack. And even more powerful weapons at the touch of a button. BATMAN has got to use all of his power. Because this world is a very dark place, and you never know where the JOKER is hiding!", 'youtube' => 'https://www.youtube.com/watch?v=JGNSt5Uzb-w', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8329], 'genres' => [1], 'publishers' => [75], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1035, 'game_title' => 'Battletoads & Double Dragon', 'release_date' => '1993-06-01', 'platform' => 18, 'overview' => "When a battlecruiser the size of a city and called the Colossus smashes out of the moon, its laser cannon glowing menacingly, you can bet it ain't gonna be makin' no social calls... You can bet it's gonna be creating some bad n' crazy mayhem on good ol' planet Earth - 'specially when you know that the dreaded Dark Queen and the shady Shadow Boss are on board just rarin' to rock n' roll... The dastardly duo are about to unleash their most monstrous plan yet - from their secret lunar base they intend to launch an invasion that'll make them masters of the world... Neutralized by deadly glooming rays, Earth's forces are powerless... That is, until the Dragons join the 'Toads! Take a 'toadacious trip with the dream ticket as those terrific twins Billy and Jimmy Lee team up with Zitz, Flash and Pimple against the combined might of the gruesome twosome and their mindless minions Big Blag, Abobo, Robo-Manus and Roper, in a 'toadally terminal new adventure! So lets get mad, bad n' crazy once again as the BATTLETOADS join DOUBLE DRAGON in THE ULTIMATE TEAM!", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [6991], 'genres' => [1], 'publishers' => [164], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1036, 'game_title' => 'Best of the Best: Championship Karate', 'release_date' => '1992-12-01', 'platform' => 7, 'overview' => "Best of the Best: Championship Karate is a Kick Boxing game that features black belt kick Boxing masters. The object is to win the kick Boxing championship by defeating an array of Kick Boxing masters in a series of fighting matches.\r\nOriginally titled \"Panza Kick Boxing\" on home microcomputers in Europe, the game was retitled to \"Best of the Best: Championship Karate\" when it transitioned to home video game consoles.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [5733], 'genres' => [10], 'publishers' => [209], 'alternates' => ['Best of the Best - Championship Karate'], 'uids' => nil, 'hashes' => nil }, { 'id' => 1037, 'game_title' => 'Blades of Steel', 'release_date' => '1988-12-01', 'platform' => 7, 'overview' => "At the beginning of the game, players can select either \"Exhibition\" or \"Tournament\" matches. An exhibition match is just one game played against either the computer or another player. Tournament matches are similar to the NHL playoffs. It starts out as one team of the player's choice going against other teams in a playoff style tournament. The team that is successful in beating all of the opposing teams is awarded the Konami Cup.", 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => nil, 'developers' => [4765], 'genres' => [11], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1038, 'game_title' => 'Blaster Master', 'release_date' => '1988-11-01', 'platform' => 7, 'overview' => "You've fallen down a hidden manhole into a world of creatures so terrifying they'd scare the rats away. You can panic and perish, or blast your way through an endless maze of tunnels, searching for the secret passages to your escape. And that's the easy part. Because the Masters of the Caverns lay waiting - prehistoric creatures so powerful, so gigantic, they literally fill your screen! So load your arsenal and get ready for Blaster Master.", 'youtube' => 'm8vfd50zCwk', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8329], 'genres' => [1, 2, 8, 15], 'publishers' => [75], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1039, 'game_title' => 'The Blues Brothers', 'release_date' => '1992-09-01', 'platform' => 7, 'overview' => 'The characters have the ability to pick up objects (generally boxes) and either put them down to stand on them, or throw them at enemies. Each level is a variation on the jumping theme, with the characters finding a necessary attribute (e.g. a guitar) somewhere in the level. The sixth and final level ends on-stage.', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [8874], 'genres' => [15], 'publishers' => [64], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1040, 'game_title' => 'Bomberman', 'release_date' => '1989-01-01', 'platform' => 7, 'overview' => 'Bomberman is an action game that has become synonymous with the Hudson brand. This is the very first version of Bomberman, which was released in 1985, and it went on to sell over one million copies. Bomberman boasts a simple and addictive game system where the players set bombs to knock out enemies.', 'youtube' => nil, 'players' => 2, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3923], 'genres' => [1], 'publishers' => [74], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1041, 'game_title' => 'Boulder Dash', 'release_date' => '1990-06-01', 'platform' => 7, 'overview' => "The game's protagonist is called \"Rockford\". He must dig through caves collecting gems and diamonds and reach the exit within a time limit, while avoiding various types of dangerous creatures as well as obstacles like falling rocks and the constant danger of being crushed or trapped by an avalanche, or killed by an underground explosion.", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [3056], 'genres' => [1], 'publishers' => [210], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1042, 'game_title' => 'A Boy and His Blob: Trouble on Blobolonia', 'release_date' => '1989-12-01', 'platform' => 7, 'overview' => "Blob has come from the distant planet Blobolonia in search of an earth boy to help him save his world. Join him on this fantastic adventure in mysterious caverns beneath the earth searching for treasure. then travel to Blobolonia to battle the evil emperor. Discover Blob's amazing appetite for jellybeans and the different transformations that occur with each flavor. Learn to use these shapes to overcome even the most outrageous obstacles.", 'youtube' => '', 'players' => 1, 'coop' => 'No', 'rating' => 'E - Everyone', 'developers' => [4107], 'genres' => [2], 'publishers' => [211], 'alternates' => ['Boy and His Blob', "David Crane's A Boy and His Blob"], 'uids' => nil, 'hashes' => nil }, { 'id' => 1043, 'game_title' => 'Bubble Bobble: Part 2', 'release_date' => '1993-03-05', 'platform' => 7, 'overview' => 'A new breed of heroes! Cubby and Rubby, descendants of the famous Bubby, must battle the Skull Brothers and their army of fiends to rescue a friend in danger. Fortunately, our dinosaur heroes can blow bubbles that will destroy their foes. They will rain fire, floods and tornado!', 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [4378], 'genres' => [1, 15], 'publishers' => [56], 'alternates' => nil, 'uids' => nil, 'hashes' => nil }, { 'id' => 1044, 'game_title' => "Bucky O'Hare", 'release_date' => '1992-01-31', 'platform' => 7, 'overview' => "BUCKY'S GONNA NEED A LOT OF LUCK FROM HIS RABBIT'S FOOT!\r\n\r\nToday's newest renegade space hero, Captain Bucky O'Hare, faces his greatest challenge. His crew, Dead Eye Duck, Blinky, Jenny the Aldeberan Cat and the genius earth boy Willy DuWitt, have been captured by the Toad Empire. Now you must play the role of Bucky, blasting past the fiercest toads in the Aniverse. It's an intense arcade action battle with eight hare-raising levels. Luckily, when you rescue a crew member you can assume their identity and take advantage of their unique fighting skills, like Jenny's Super Mind Blast and Willy's Laser Cannon... WE INTERUPT THIS PACKAGE FOR A SPECIAL BULLETIN FROM TOAD HEADQUARTERS!\r\n\r\nGreetings, warthead. This is the Toad Air Marshall, coming to you live from the Toad Magma Tanker. I'm here to smash an ugly rumor goin' around that says you're thinking about becoming Bucky O'Hare in a futile attempt to rescue the captured crew of the Righteous Ingignation.\r\n\r\nFool! Those lunkhead traitors are guided by the elite Storm Toad Troopers in four toad prisons hidden throughout the planetoid belt, from the Way-Cool Ice Planet to the Burnin' Hunk of Lava Star. So don't even mess with us toads, you wart for brains hare-ball. 'Cause it you do, I'll have to blast ya Toad Battle Cruisers and Double Bubble High Speed Toad Armada Tanks. That ain't the worst of it, pal! Once I've got your pointy ears in my sights, I'll drop the big bomb with Crater Centipedes, Robosnakes and triple threat Triborgs that your laser-guided Wart Remover doesn't have a shot against.\r\n\r\nFace it rabbit. Try to croak us toads, and you'll be one unlucky Bucky!", 'youtube' => nil, 'players' => 1, 'coop' => 'No', 'rating' => nil, 'developers' => [4765], 'genres' => [2], 'publishers' => [23], 'alternates' => nil, 'uids' => nil, 'hashes' => nil } ].freeze end elastic-elasticsearch-ruby-c38be0c/examples/apm/pinger.rb000066400000000000000000000026701462737751600236510ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'net/http' endpoints = [ 'http://ruby_app:9292/', 'http://ruby_app:9292/ingest', 'http://ruby_app:9292/search/mario', 'http://ruby_app:9292/search/sonic', 'http://ruby_app:9292/search/donkeykong', 'http://ruby_app:9292/search/bubsy', 'http://ruby_app:9292/delete', 'http://ruby_app:9292/update', 'http://ruby_app:9292/error', ] def sample_fibonacci [1, 2, 3, 5, 8, 13, 21].sample end while true sample_fibonacci.times do uri = URI(endpoints.sample) req = Net::HTTP::Get.new(uri) req['content-type'] = 'application/json' Thread.new do Net::HTTP.start(uri.hostname, uri.port) { |http| http.request(req) } end sleep 1 end end elastic-elasticsearch-ruby-c38be0c/examples/apm/screenshot.jpg000066400000000000000000011716001462737751600247200ustar00rootroot00000000000000ÿØÿàJFIF,,ÿþCreated with GIMPÿÛC     ÿÛC   ÿÂ?zÿÄÿÄÿÚ ýRE¾s¯ÖmSèøü–ÅENžwÛò#¨ç÷ú®o M=—:ÿAý Ïó=Æ84ÌpýŸ#ðGóÌ&ßRåú³y_§é˜ÝËLH(oõu¶™Ž\·06¢d˜JêÈF0ª´ZDÚVÜúqÛÙßDºŠÔÇY´4Ìn‰ùÝ£Ó¦…ìHôÇçÞ¯#è=_ö/+ôѦc‡ìù‚úŸá6ú¯7½öo+ôý3¢y²5ëiKTéNª–ÙAY¥.¢4E¢ËtÈö&!I1ˆ.ix6ˆw§°›K̵(&uÕYDË–èž·ËL!LëÏM7¯²»Vª–‘h—ètÏ ¥ÀÓ1º'æVˆ'Ñë6†™Ñ<¤À±.¢@Öp=ßü_Jóþë|m¦b¾þÛò#¨ç÷ú®o Ó1º$™Ñ ¦ctHLÆèÓ1º$™Ñ ¦ctH +ï]‘ ØO¥€Dµw@lXA6’AÕÝ ±a\ Dµw@a ÃÐÊwp|÷Õò}wÁú 1é³¾ÞÞH8mÎÒ÷V¬Ñ®qs¿Óà>U‹&™ZRò+jé‹_éçµ¥¨3×ìzguI ¥ø½)h¯w5±¬«5{RÂ[¤€9î Ùm ~yØï®kä½­áoÉ+.Œ«m¨¸Ã¢5«é?-@a(:ãÈ÷pK¥ún>Ñ?-p•!.³[h×0¬É‰ÕhÆbEmk5•DÏ#ßæo&ãÑ’'ã½_–=uÊVw¸Ç}´ÓâGó?úO˜Ot{R‹³‹èþ'ÐrýþeŽ=uÂ=ë’-¹;xŸSÉ©¾'7ÓÄ€Õ1ºåSFåèâ=.î}ôDýy(’'+Eöv÷\ùêÛê5Ÿ•Þ›Vç©~®Ô߆Ò;ø©¹º<™úëab–#}æû—£îáûoÿ*ì¦XéõH¨…ôü»ÎNÎc¿ÏÄߦWXÓ]³HÖ›Þ>º.Þ¿ƒÐ›–õ›aqÏÐ UoÏÈ÷ùòóÓ·ó½:Ͱ¸çèÂ\ìMqW¥®vð¨‰f‹W¿¤€¥Ìvpì4^-geO$Msöšo…ç?Ež?ú?™øÒ|Àé¸û`k•gG/ÑüO ÃN~s£ *[(¾ØˆÉâ½?,~¦øŸºî¼ßL ±`-]ÐT»JÏÇævß;|µƒjõºSˆçèú'O%ÎZŸÖô·¥ý«º¶Î–æíMfGF5øë•mc®]-ÊÖüÍé>#æó~ÎÔèi=¥'ŠÞ¾Òݬ@‰\§e¨„¶@Îk—Ä>æ~#ôŸ0õ7Äý×uæú`m‹z`t1"%«ºÆ³ó½+ôjÈ'•´uP rÀŒ²€ÀØrþÎ=_ =>Éà} ®;¶,>s§ú6}‚%«ºbÞ˜ H‰jî€ذ–®èm‹‰jî€Ó,Àbx@¼‘aI M°b†ØèzX‘ÕÝ„¡B®]6‘%.`œÑ‰ž€D7Kl&@`œ¦=€ÀÌž€"ž„ú„¼‚R`¹`A¼‘gœŠóÌ×,à6ŇÎtä™N®ê$Dµw@a.xèaG.‚“:f=7U’â5ÖÑô®¸°ðÂcj|†2Ê(ªMÉJ‹øš H‰ÂõÕYf0­¼µU™6C¬î´a1“YÆSaôœÅym®ôÂ^V|=•õ@k–ÇÏ©z})h­FWß7ѦyÍeRÚó·EÕŸg•¬ó‘ñ‹®èú`†QN¢åœذåoÅ’ÝE:ÄKWtÆr³†“ÓÃa¬Øxb$‰ÆcØe/"r˜Æ'4iO³Ë`’5ž‰eŒÆÈœQŒ¼‰É !‰é´OAêHKl×,7ŠJΉ¢bVÛ¯]ˆ×º,´…žsäLyc1.åœذ–®è 2Ì'„ ÀÄÛ¶,%«º xC# x(f ±aÂÌê$Dµw@lX|Wö'é¸úâ%«ºbÃŽ˜‘~§>ñÕÝ%ÝÃs†Ûé¦ÄúœáY¶2ó¾È¶ÄÍÏ@3Ð+”[Ô`Ó =oåéѶ–‘5ö&@”Ø6Å€Dµw@Ëöñ`ŽÓòú/F&ü{+hZçk‡N‘UoFDýGÅ÷›u¬ùúk2s‹´ÜE{¼ì)6å-JÚ_u$ãIMmS–¹} +€6Å€Dµw@lXR ]¤Dµw@lX|§N?OªçØ"Z» 8KÌeçz`l†@bÃ’˜lH‰jî€ذ–®èm‹‰jî€<5K4€!䯨¶,(&üH‰jî€ùŒZÓJAÇN¿l¤Òúf=…¨a,¢wD€ Õ‘6ŇÍôäöG§X‰jî€øDM¶•å9º&vòYqôçÓ… ëú' %”Nè!Z² ذæ¯ÃêzJvˆ–®è £Ôè¬À´dZLsòí*0–Q;¢~/c¦q)¥Ü6k”œuƒzé‰ö³î¹¢h2ת×+ªÛœšÔͯ³˜÷§@ŸœK¯ÊÚ7Ê%4ú¤A @×(ö¥ž;s}|”<“ðéÇL/ù{hº9l±Þ·l$Öý_ +VDÛÕÝa,¢wDñ²Ê#²Ó+úp½çßæûc}Kå›|wãµwãöÏï ü§;r›ÏM„ô»ãožœ>ü×FøUãÑ÷ZÇ©Ví…–;ÖëŒ qhÙ5´çè­ß «hayË×k@­YlXKWt„²‰Ý+VDÛüÐtqÕÝò9r…ñYŽòº¹¤R×ušëFª_|WœêôæèÐs3X7Ÿ¼M,3° %”Nè!Z² ذàôâ…9}'/HDµw@R”d5¥B-ë*³bâÕÛ–µ6®zg}É"¦-ÓÞ’k 0–Q;¢y™óùÙàúE}þJÕÆÙ×RÀ|sÚñþ—åúSùº8žœ'ã¬i>³•m¦ôÃ-ekŒIvùh÷|ðøy‰¬jßÛÓmg£,+`V¬ˆ¶,9ù è"â%«ºÂYDî‰DDae¥d9aâ}F2Ù iÎcd7$cÙŒ!‚bÌ[ÃÔ€Bµd@ ±`-]ÐdÝ„²‰Ý+VDÛÕݪYlÊ'tH‚i6ÃlĤ€9è^Z#Äë$’M.Õ ©’H«"m‹ ²ÇC"Z» 0–ÈŒI×,à0–Q;¢~{KsÚçQî+^'j}Û;åçª_ë»cÀçxwºgÜe øÍms¥8kWµçÞ·«—ìxì­YlXr¶Â¢ÜÿAϼDµw@a.V'„™´ÎbíXv¦øž¦+ÝÒàä…ùœÊ'tOYço“F‡7K}l¥ç Cå~‹l3Îñ3ÓΞ~û-@Ïë1­·§gKr’úœHBµd@ ±aÊLzuQ"%«º l€ÕKëÛ)4° rÎ eº$V¬ˆ¶,%«º\½†È %”Nè!Z² ذ–®è eº$V¬ˆ¶,+ˆSÑ"%«ºÂYDî‰MróÐ)Mí"¼¼ùúTÉÑw™«"m‹’éÍÐCº§H‰jî€0–Q;¢@`i=A2f|í*€d躎°!Z² ذçmŒ9Ë®§X‰jî€Ó è %”Nè9™ó´ª“¢ê:À…jÈ€bÀ"Z»  %”Nè9™ó´ª“¢ê:À…jÈ€bÀ"Z» >s®˜´½$cµ¹ÚVfMj«y–¤;"ÒÝ$9IYÊñJ©U·ÒPK(Ñ s3çiT 'EÔu Õ‘6Å…Y¬¸KWt).-¶³«ÉJ➊—Ù9ÐkZŒõìé^‘wKa|㧯Gg[Ê'tHÌùÚU9oCþ-%RÀõßYÙ Œ%º²“¢ê:À…jÈ€bÃŽÓ† ó÷ùzÂ%«ºÂYDŸ;J VíŽ:zõ¤ì­Ÿ,Øep‰zÆÒ¶˜hLg{V§¦–Ü÷®Ú•qõôùΛŒ;åiޙĀ^ùÏÊûk ¦Ñœ3‰ªb—Ñe·Ÿ;Žm×1²$œïÏËOGç_ÐY:.£¬V¬ˆ¶,1ØDˆ–®è 2n€ÂYD·›Ïõcy˦2æ;ºfgÅÐqê"iZ®ÄÜý7óz €(zòÃNÍQ½—?›iŽ‚%ëOÙLï¤þ:Øãp®Ú‘4ª3µ˜·¬N‰ò# â×Ð žŒëz:÷aê7ñëéÛÓðûœg™Ûòø»"|1˜Î'ŸìÏdúxiçÊ奮 Ý© ¤¥nytÝY/ZÝéwÍ®Pj´m¬×mJ^½eÓX,r½n~Lô\Î' Ž{»;>kXãq¦ÑOÓŸ–›žKúr}ž†ûp]rg;;å&•­Þ–|÷•KF½h{­µ9匼gMãU×¼šåJWí_ ®m3‰‡«8¸ývõcuxw¼¼s¸Œ²‡5Ýž›õ[ròÚá jÈ­†3D[¶qoüúi´@Ö–øiœN¹ˆ×¬ «…—\ºk˜«Þ—¼ºèµh»ë»»åÓ8):s«¯Ô·Êtz‹'EÔu Õ‘6Å€Dµw@K(Ñ |Ï¿VÞ|ÞêǼ¿gWÓåÜ[çÅ]½9ü~ý…&«‚vß9í¬­p„l¾ŽÏ›¿j)»|×óuÍ¢×¾W7¨®Ú:¼9VàÆm¤Šã•)}Y÷ùl±×“Ëeí:rÇ· ®]Å|Šú{—žµœcKmv+mZR[]^‡Ên®Q-¾ˆÒ~|5Qô=7¥U­6õüæUãöfÏ“ÚóNzþ¯Ò¾rf,÷gÍìaÕóÒ銱µV_Ö³¯™[¥ÏÐFßÏ“·•_¦R¹}Ÿ z~n5j÷¾|¿[§Ä±¯•ºŠmû,y}ÜÑÑó«YŸcùíìùü-Ïl¢²é‡“8Zû+MSÓîǽFNhq×/‡é³‰Ñ·$ÞÚé½zöð§sFQ4Ý„Ü}mŽy"¸ÊO=yí=>Ç‹ÜÍZÉÖ›»Â±·˜0›gZeW’Æöñokœ©¸Ã¦›¯Ì›¯‡±XÎÌ£‚V*¾ŽÙ‘Ϻ´‰m±ËÖ•M"ty~ÆÒqì«Û9Ïj'£,{uW§EzX{S¯ò±/¦\¿]–Þ~î ȦYSÄSGÒö<š“CÛäÉx’ò[×§«Ç¼V¬ˆ¶,%«º¥è´¦ò"z饭l„²‰Ýp³7ÓJh¿iùý½©õ§/Ó†åê¸ý(“xcâÖi5˜Š½f•WdÓÉ‹¼ëš|ëmœM”e½Auƒ7Îb!^¾kÇ?ËÈFi­i ö«Ši­¯“TÓÉ‹,´–Ì<*'}v¤šÛlEvÜóòÞÂ3—¿›pù]§ãÓ:3VéÎrsÖÎ3¦¶˜_× xôçÝÐa¥U´™ø˜KK£ÂàEiYyõWL/—¶Á1Ž}[+}vÎæ•Ú®)§¶Ø"}U[a·o6_'±Ðד~¶Ñˆ†×b²Á:–Å:W–Ëj´ÖÖDDø§+Ùçå]º®^œO;á|rßÌÓ]î¹»d(+'X½>fÍ8îyúºüqÈ­YlXhSž›u"%«ºãÙm«— ¶°¼}n¹åÂYDî‰# ™*õ4­¦‹,«˜ÄúŽj¬ôúU«õœì¢^HC##X†øz¶,8M8#M>‰—¤"Z» +Ä£iäLy²Ù2í«9LH–p’Ôî‰[F(™[CµwÀ ±a^ Dµw@K(Ñ ‰hÅk`V¬ˆ¶,%«ºL€ 0–Q;¢~Ò^—•°E­ªôÎú¶‰©ž­®ôÏul-¢mm–ùþù}/;€´-3°­€U–€¬,À…jÈ€bÀ"Z»  %”N蟗ʾ®šZoËKÌE<Ï[Žúy¹ÈÓ¦ä×±ß>£ î~¾Þ™p›ÒoUg4}"–ú,KF(›[PóíùóÒáÅÙÔi9µ\û\#Z+÷Ïé°ùO/M‡G>ÛG}ù¬u ×-=\ö^~ÞÎNQoÖ¸Ø!Z² ذäæY"Z»  %”N蘠‰¾ÕYÊ[4Ë8ÐÝ1]$Lä@Nèyd˜S(%£M­µÄµp†ÚÏ7£¢¬%®¶—jòé¢s´g„Ye1…m¶Õ×h!Z² ذù­ù‰úU:KWt„²‰Ý–ŒQ6¶…jÈ€bÓ˜dH‰jî€0–Q;¢@ŒÕ1êdC\¯"1Hž‘-¢ml›–ÄI‰Æc2Ú' Õ‘6Å€Dµw@K(Ñ ZŸ&¸§dDxµ½©”X"Z1DÚØQ™¤ÊclMˆ#Ô€#Ô€yóþ÷ÐþƒÁ"Z1DÚØ]\ù¬ðå³çîöì§®]æÝœV<žÌÕS(1_«tú>œ¾|ó¦üí0Øžãn¾k<6Ì×W< b=4£LD¹·‡†Gm·XáñäÈÑÝmÙ´àñãµ¶–÷Öúû7.ZêÒîúó¹áôMû¸Lxþƒ¿hf\½v<^\½ÆÝ?ˤÓzjeœÏW§G'Ÿ>›fv§¨Ó~S>|N³NŽN«NˆJJeßíÙÅåË]³›û3ÚkÕÄãÉÛmÖ­YlXKWt„²‰Ýž|÷½ô?¡ð@ÓKTruÞ÷q–ŒQ6¶p¸ñ÷[v|{—ÌûW¦—.¸‹«ë±›ÑßÀcÅsmz}:>iÏÁÜí×"º¹òó}k§Òù_7Úí×Y\úKïs}D+VDÛÕÝa,¢wD€çŸ?ï}è< T°¯Ãzþ}ú_KÏ-¢mláñäî6ë‹•6¶¹àZÛA ´›kˆqI“qÃãɶg CŠÔ×/¦oßœÌH¯—/C}çÚòæÃÃåÜþÑ÷î—6Y\ù ¹¬-~Ë^  Ö“­òù†½5UÎÂoÚí×+Q\ú ì8ܹuÄvÛuÆŠÈ›r9sfrÙóýW§ÑäÜÞoÖz}(5¤ë\@­'ÚãˆÇ’Â×âqåúgGwÌùø~»ÕéqòvûuˆV¬ˆ¶,%«ºÂYDî‰Ï>{ÞúÐø \=¾CÙj¥º/G€D´b‰µ°#‹Ç—µÛ¬S—ÏÓ^ ¯­(©[¯H|ÿ/ oÛÅcÉÚíÖ!Z² ذ–®è eº$ƒîw~狲Õ?ç÷x:C€D´b‰µ°tÇ$Ý_P+N×n± Õ‘6Å€Dµw@K(Ñ ÜûØô`„ð½®ÏÙò$i@s¾w²¡ô8KF(›[ÅcÉÚm×èÄãÉÛmÖ!Z² ذ–®è eº$jùºo{x³´òÏ›èôþŸœ8O Úîýßâ{_«æs¾EèpWóïyÝÆïŸßèCèp–ŒQ6¶DW|Øq8òvÛuˆV¬ˆ¶,%«ºÂYDî‰:ã;|uÖÛ-PùïÏû¶Ý|·|¶\ÃFw×[KÛ! ¹3Òí}¯U-Äx¾Ïyîø€8Ï×èý?Žñýn‹ÑàÂ'¢ô8žóûÀ¡À"Z1DÚØ'm·X…jÈ€bÀ"Z»  %”NèÑKó¾wSêy wëv>Ç’BÇi»b9¿7ÐÙzôü<ïß?|0‹aY¹íä—“êLÛ/QÐz"“‹³›Þî!OÇÕYÍÓÕú¾d|ïKÅÙÑz< á·3æú=§³äyxí7|@1<§•éÜörs>o£?|%kŸCèp4gzÎnЇÐà-¢ml‰Ç“¶Û¬Bµd@ ±`-]ÐÊ'tHB¥ê÷ÃÚi"åw[ÍÓcÓÏÎyÞ†ëÒ÷»ˆ°Û™ó}ÏÙò+Åö;/cÈÊÑÏùýã¡ô89ÿ?¼eäOAèp{Ïïè}{Ïïè}Ïùýàô8G?ÁÝg¢ôx(ø{gôa¦—³éæ žNª®^ž¯Õó*9:«¹º:SÍüûÖótJ×:~>¼"lºyúC€˜ë¢—ÎÑ[ÍÑä#á~¯Øó}"Z1DÚØ†Øc1™mˆ8¬¹;}zÄ+VDÛÕÝa,¢wD€ªÚ>™ê­½Dxµ½©Ïy¾—Gèùüïß²Õ´êæ¥âì¾ïáÝzˆxë'Lù_/Ó¾:©n“ÒóÀ\;/[Œ9?+Ó¶êæy'´è½wÏïôC¢ôx5RÔüw½Ü\÷ŸÝmÕÍ/l¹ï?¼t>‡nŒïNËÞòùÏ7¿¡ô89þû®Þ9PÏðwa[t~ŸÏyýùÍn»y6Z¼÷Ÿß{ÝÃé q¾?­Ù{M?_5çzW©æEËXxëYÍÓuÛÇÐwð×stbUòôË×+¾Þ:êîfߟ¥öøÄKF(›[«× ¦6ÄØ€q8òvÛuˆV¬ˆ¶,%«ºÂYDó»úþ_Éôlzyê9zúßWË¢ãî—®X«“¦wFPñ×msòÖéý_8 þ}ëù÷×[tž—ŸÏyýþC]eÇ–¾º¯_Îç|îÿdFžWMìðÁÃzO/¢~¸PãèNèË ïáªåéöUüšäŠž>™·çí¾Ìä|/F㯒³.¨xíÓz¼ÜûÞ÷qghç¼þñÐú÷Ÿßç6s;¢Û¯—†ùŸRÏÓ¥O/Wsíøµ|½<îÌÀ‰hÅk`†\ÝF›ï›Bµd@ ±`-]ÐÊ'tH‚B£ÌØ[úxãVV×Iæ|NÛÏO–w^`©ó6ð·ôñ«ó¶ðµôq£ÌØ[úx€9Ÿ¯ ö¹·kP jÊÀ%£M­€rÙóÞ[Y¶¼+VDÛÕÝa,¢wD€ 3aoéâÂ|·©Ùý›#j€£ÌØ[úx€iÊtåiT£ÌØ[úx€9ší뾓‰ –ŒQ6¶Îg……¯gm!Z² ذ–®è eº$QùºóÙ˜Î>;Ùú7ØxÞÈ>nÞBßÓÄO›°¶ô±r?5Û×}/‰hÅk`òyôªñûo>‡ÎòÙä=ydä=<‡²Ü›Wù½7>ï%ä=%ä=—5òž¿Kõ~E1Ú›‹ë Õ‘6Å€Dµw@K(Ñ “ÉèºõyýÍ~3ÚúWÙø£L×tX{£žÿŸ|“Uçl-}@UùúëÚ—Ur¿;ÙÕ} ½r¨Û.¯“¨D´b‰µ°7&²zòÑͦþœÀ‡Ã¾´ÿG˜FäÖO^B7&Òzñ?9éçzø ïò´?§©úÿ+Ä~]j<^ûO“Fr:rC“øÏs­ûO ‰Å¼^M´á¥ß¿çi]˜ÔøÝºyô˶þŒï¾ÌÕ…ÒÛµ/ècyôvž}6ï?‡ßž•©ñ»ºÏ²ñË¬Ž¬¢qo/·‹y}¸ /ô·tgSâ÷tßWärß!ìöqàÓÓ, »ë Õ‘6Å€Dµw@K(Ñ E¾´§UÉÔ+´ÎÇ=+×ËÒòôí‰çzyú.n€Š)÷Æë ùší¶ú¿3dOÛÇôO7ÑßO5®Zó]\ÝŸln{í½|Ú˜ËE«]¦v¹k[¦w¸o®c–ëåê¹:³‰kÎy^þ<޳“¬PtsÙyszé®cdH¦8Žî燻8šMð™KÏÏNW¯’Ï-mñÛTÖ¿JZå¨ðå:ù:ÎN¾_«—¨åê%£M­€ò_Á}i÷¿=Æü/ÐvwóàSx]þVdue³JÓx}ò»1“Õ?‡è_ý'—#§*¿#· N4¶W¯•œ­9ô›ßÏeëqñß ïÜ{œžOdÞþ~‹éü¡YäöVù]vÞÏ Žœ·ôæ*¼nÛ_gŠç½khܺÌíÂïè<á§ŸNkå}{ŸwÏ×­½ž!GóÞ•çÐù´ž£›^ê<‘GóÞ‘ŸCçR|ÿ£³ZjÇHüÚÅãÛ®ûo+྇³û¯Ÿç>c֕ׯ±ÃÍü·¯uïyúyôÓé¼/Bóßó´a¤Þþ}ºÓWx‹»ë Õ‘6Å€Dµw@K(Ñ qݼ{k9¦~ZhµaiIµŽZF½gçz}±Ó1>šVk–PÙcžº¦°ïH—¯_Ç׺³õåú¹ºmùþœ6|±Ÿ×yuœp4ÏØzu|qí^£žç·ÖÜ·_,ŠÚU-2—⻸¯9÷ë9:ùN¾NŸ—«—êåòBU-i–²©nw§žÏ-j6ÇÂÛ-tÌN¥øŽî+,µ×1×qõòœ‡g'×ÉJYe¤kÖ]-e–µšåcž•zå;="^—íÎtó_óôi´C½:®N "Z1DÚØoN´.šï3ªóè<Ø\Óyt?èå1x¼›uÿmá Ï#³NU~Go³ßGæWy}yéX¼[ùŒ4¶¶þŒ°ÎÙé\k7ŸAç œôò½}5e~ƒé|¸üºÑøŽÝicéòÎôy…Ïú:pÒ_f¾_gOõž5ÎúwÿIåû!Kàúþ× /…è[û\4¾¡aérÃáèÙ­'ú\µžOg•‘YäöXúœ—ÿIæQ|ï¥iëñÂàè‡Å½¿µÃ£›HWAô¾U/ƒèÇå×N[4­Ç¹ÁCóž÷Ñù”?9é×eŸKä]ßXV¬ˆ¶,%«ºÂYDî‰ Œâ@£ß Ì7g ë¸úùÎN§“§lXÌurÏÏKŒvðåzù2Lº^ÛdVÚ¦>g^~ûm2‰±Ï@ZåM¾:æ;..Àjò½|¶¸ë{†ô›ááy†ñíZí3£èÂç ¯0ÜÁzÜûßóôWéœìïÃwñw<¹&»Lçç|“Õ“[ö¬;ÒÓ-D[R‡££—¨s=\Ö9ik– D´b‰µ°?èÞ{þuo—×'¯oå}~‡é¼¨¼›cKZzüQùµæ~OØì¾ëÀDâßLßCœ¼{oèίÈìJßÚáVbqo3¿ž›Âï‰Ç¿¦þŒåva ƒ£Fpøz5en›êüŠï/®ÓØâÄÒ|ÿ£ë¿£/eeêò br˜±½WÛ…mwïùÙLsÿ5êg¥o~‡Íç~_ÕßÓžþŒ¬ý^H<]y´—Û‡/ò>̾ì:oªñý k18·›ßÏŒNSæß?ôw•à²÷ük»ë Õ‘6Å€Dµw@K(Ñ ?)×+È ð­×+,µÅ$ÃaÑŠ&ÖÀçì“ f3=æë §a$iÇMÛg[åöOô¹sµ|N¬¯»ZI’ #ÄúŒ)oe• â}F¬ï•£ÊÈÏJëÊÛu¬~})þWÒè>ËÉ h‹Ðg×:™mÖ,¯‡¨&4^“>ž^?Qâi¾?ÓÃêyµZn4ç÷žÒ:rô¬¦úñ›~žoÏç×åfWÉíeõ|XõÏêÂÒøñ> ’*)Óém~m2¢áïï}_•º¾°­YlXKWt„²‰ÝUKdDxµ½©”Xa mÄë$`x‚tÀ5„hNd€ `Ð `¡£DNùñ k5ƒX³Y°Ö‰ Y¬ÊZ$ĪÚ<‰4ÁhÕ”Ę#Ã9IÎc|HÍˆŽ“"DKF(›[FSbl@5ƒÈchß°k"@ÖxG$#j@ÖbF$£rBå¶Z7Dì‹ òŠoFä&4&Z 47LDLÔz„9H†‰JG©B%£}f4¦£ÔŒ!¢Ñg D¨04£ÔꘛD+VDÛÕÝa,¢wD€ ô¬ß äî‰ëk VVðoŒ L˜žž²JbÍcÌk‹u¢b2t tñ sÑ;oJ¬¶­éæú:NUXFètñ TJ®%hž­ål:*¦Ûâ&Ú·5°ôN½)=-4Êþ—‰òô¯­î­KšØ]2&´ö_Õs,™ZÙ^–Õ‘ÑŠ&ÖÀ)ˆå·U°Äb¢ÑÑ"Þ¶”‚´kçuY·‰”®N­â,«a„8Ù›‹Rª-&Õêi`‡'3í«®³U°²eZ•µ¿CzXRÀr„ÛEEm×Ú›«a„8Ù›[R M䬫#]\n“o«O[5Ý[éAÓÍgŽÔ’ë4ÎVw•½F¸LÏZm+ÛV=‹V¬ˆ¶,%«ºÂYDî‰KF(›[Bµd@ ±`-]ÐÊ'tH"Z1DÚØ«"m‹‰jî€0–Q;¢@ÑŠ&ÖÀ­YlXKWt„²‰ÝÁ¾ƒÁîüþþ‡‡»r1•†WùäÅÝëG–žkO§TOË¿=õû­óâ{<»âu"·‹jbK­ YìÓem¢ë;Ôòu|gã¾·íÿmñ´}|äK­¬*¯³8e1€„K.k3«`‰hÅk`9Ìðü·çüÿëOCé õg#;ùYµ&glÏN—«šw9kWÓŽ¾}kwDz­úžOã=¾Wãý¿¢þÉñæ0‰‹¥-)jËD¨› ¾W¾/"h&±3¿sÑ•¶wüóâ}ÕÖ¼ŸWö>:¾Ñ2&<&Ê)š"gxöŠøXá·/ׄŠ×éµÐ Õ‘6Å€Dµw@K(Ñ s]<ÖÙk/=4ÌWLYRÔ³µ|¥«¥Ó šo+{OG:Ôzy×löD“Šv#ÃÂ\NžgÍôzO͇hôÈÖS¶e°›Ñ ÑŠ&ÖÀkˆà±ãïöíÕhÎDåhŠl‡²©‰´EDZu©C[]Z³bÒˆ¼{Wù½VÞ÷œ7ô9L€ì¿?ôs³ÔBµd@a,¢wDŸú^lm¹où;:ž.ú.Žxzå”V‹§ž´¶Ãl"ýO6–ÜÝÀ>aKÑMluˆ˜«:)õlçenÇÌQe¤ñ½®œý+YÑO«g;+pVbNÎíâù–[NF1§Ô'•Óñ·èQôò€ìÏÿE½æê­YK(Ñ"™èµ%Ròi¦¹¬KÓ$D¼kµ'å®Èœ&&g¨QZe1>%v‹(¨†i'£(˜v‹(¨× öŠH™Ó¢d#Ôüoè>r™Ù~èçg¨…jÈ€ÂYD" eº'TÇ€¶'Ò«" eº$ToÏ®k„­±Û}4‰¦^¾åmõ¸S ­põ y¬¶˜Û­7Dîµ}‰Ú>7ô9L€ãËõú.>à¶ÎÙ¤Bµd@a,¢wDŸz^egOQÅÝÖpú<÷W%nØr¼=|ž,"öXí2–ì|ÿL8z]|ðÑgE>­œì­À8ùˆTÒnØÍË^n)YÑO«g;+pyGÈ7¯_±šòS3‘Œiõ ÇetümúçT}< Ûþ_뾇ãû`Öóëº$Bµd@a,¢wD€^xL<„;E”HÔC&âÊ$WBm¢ž&tÆè™õ?úœ¦@qåúýp[glÒ!Z² 0–Q;¢uLxb}!Z² 0–Q;¢@…jÈ€ÂYDî‰óëšá+lvßM"i”Ìõ´Ëum¾·+¢bÍmæ6E€hâÖv¦Ø°†SêöѲ’øÔ|¥nØ€ú7îu<ˆ Ìo±"«" eº$|ûÒó+:xúŽ.Ñ纹"é—#Ûñ:æ=.ùºfRÝŸé€Ë£M¶çß:ÆÊ´Yý§+l­À9iNb—¶Ò*²­ViÊÛ+pyGÇ7­þv»µ~~™6®Êkõ‰ÃmuümúçT}< >ßòÿ]ô?ÛÖóëº$Bµd@a,¢wD€™MÏPpù§±âľ`:®F盬'$ˆV¬ˆ %”NèSØŸHV¬ˆ %”Nè!Z² 0–Q;¢EG6§…×?FÊiYÑÍ3-|˜Ê'\Ä=2°Ëm¬ªiùÊ¥ôÌk´I­·Òà4M­©²,hѸµs‰ŠcÄϤÊÒš«2’øÔ|¥nØÜy~·oåúà˜ßbD+VDÊ'tHá=:·£“¥ãìê8½ žHöо?aùõ<]õ{a"›tûPtcO¿>Åw+qÍÝQ¿7yæz ̳¼ýé_ŒPugöœ­²·¼Å~Zû¾uÅViÊÛ+p›LRiDäè›ÝÅòŒ¶“j즿Xœ6×_Æß ~uGÓÊÖ~é~³óÿHÖóëº$Bµd@a,¢wD€5é&—™LÏPÃÐIÀæžÇ‹ùÑq÷t<}À4œ’!Z² 0–Q;¢uLxb}!Z² 0–Q;¢@…jÈ€ÂYDî‰=Ø^ž\ý)¥gG4ìµÕ1ä¶UêeS@²Â–›®z)2e:$v'VæPê“)Ñ ›˜YÙh‚XCD­âG柰øºðû¯Êý…Ž;€Ðã}±"«" eº$pž[ÑÉÒñöu^…O%fÙB× ®n¿{¯‹è~W¯œX;1ºšTE9~œþµœì­À ê¹^Ùe¿NZÎvVàòï^‡+ÚiŸ#[o´K¦¿A·>ÚëøÛôΨúyN|?èÜý u¼úYK(Ñ ”8ßCÎÑjtü>†ÚØ •· …jÈ€ÂYDî‰Õ1àm‰ô…jÈ€ÂYD" eº$s\˜ZžüÝJßN˜ÎËp=m?LàÖdÊtHŠ&ÊÕ‡ 29y‹:ÎËDÂ%o9í³Õ èq¾Ø‘ Õ‘„²‰Ý8žÿ>³§“¦ãíèøû©z9n¹ú€ç¹ëgцŒ-Ëôçõ¬çenÍ+k}+ŽN_§?­g;+p*ùÕìq½Ž¹ðu¶ûDºkôsí®¼ŸFZ&­ç×tH…jÈ€ÂYD ÑŠemè!Z² 0–Q;¢uLxb}!Z² 0–Q;¢@…jÈ€ÂYD" eº$A¼Ÿ×pzA¼«" eº$ 8W£æö¾w¤ “€!Z² 0–Q;¢@o¡çv^¢«" eº$V¬ˆ MÎ$%â7À %ˆ=3‡ ÿÄ8013 "2P!#$@`p5%46B&7€ÿÚþñ”ö´omƒ|b§œlÔhåS¨·K‹í¸öÜQ«íÕÕýÍZpš£±YŒú¸v… ŽLúˆ"´¥±1Ðõ¢âBTiéª9Št˜e*’ãîÈ¥:¦XB›e¯¤ã¨êN”;l³iL”ŠòéqV¤FšqÝ¢­æÑIY7*œ¹ ÐjA®Žúä1L¶Nœæ&#©©EøºC|éµZ<™gHáÙõ9ÃÒuóðSøz}!§i³•!šØK‹Ãï²ûÔ j‡êtê´}Cˆ›mF¯2x¦Ä8P‚> •I§ÍfJ£ CG…ÍÆÒós¸YÊ„b6™ ú5:suH¾Äb€Ý!AŸGûYW«ÄgÑøYôµ‘õ|(ú¾, Œ Œ Œ Œ Œ „FI§Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#U#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#U#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#Q#U]_O÷[+¢V¢_&¾Ÿî¾©l‘Ñkä×Óý4f}~aó˜|Ãæ0ê¡ó˜|Ãæ0ù‡Ì>aó˜|Ãæ0ù‡Ì>aó˜|Ãæ0ù‡Ì>aó˜|Ãæ0ù‡Ì>aó˜|Ãæ0ù‡Ì>aó˜|Ãæ0ù‡Ì>aó˜|ÀŒúñ5ÃÌ{Ìó¼Áï0{Ìó¼Áï0{Ìó¼Áï0{Ìó6{uH> _OÅS­?ˆü)­?DS•Tf£ðÖ+½ªwôÿ|þçÿßù/ÏÆàŸüÏ‚×ÓÊ¿.¨|k‚ý¾’ì¾â)o³Äük%èœP¾¨­=T‘\§ð5Eé”Šì·æqG*Œùõêäê%_‡ØãwöiG-ö8–¿S˜õIΩEnŸ^]g…xn S‰¨tÙâN1¡uâ M3µFÇ'·NOOq¾«J¨GáUÕ¸šA. wR“4®«8ÅÊŸ@£¿:‡ÄßêúrQW%ªvúJ+Laf¶‡eF®7*)V.LZ«²ã}‚Sõ´2ûµ–lºOµ&j".\ÔCOòoþêRœH¨“Ô—%±.LÔD\¹¨†Ÿ9r\n­2iÄ3¯2m•]ÕÕë’fE*äÅÀ„UæI¾þÒŸZfž¨Ï†¿|ú–†)’Ý’ªMka†«m:¶ëqÝr<ÖäDï ~kud¸ì*Ú§÷¦±Ça¯þÿÉ~|œLZtŠŠb·²¹ÇaÁ~¯†ô†£Ó£µCv€óNÈ£¸Ëri †*´ 2¹pOþgŸGGGGGG_O'ÿþ•?þøðÈø?‰”^×ñ3Ècn5/ø><àä÷9õnMZ]'…“H—Á状óÈŽ×:‡é¼QÿªKîä/bC4ôà_ü—í8ÃýåNs…ìU^áÚjxn­$¿Çì¢<¿ñ›¨]C<%Ä-©šYù?òõ/ÿ¢|©²^qØ®.±Ú¥9J]1GqÙµÆáLk‡)ôדQ‰V±ÁšTÖ!ºÜ…SÞDJrj ¥æâRÚ†çòoþëH7(ïI‚ìê9´rœm/7–Ô7|êqe96u:tõ&!º\zd¨Ò*‘6=RæÇFv\™yu"“H¨O_ïÝJ–ÑA›&ST·Š\¢Cœ>þ3‚ƒ§&÷ƒDÄÕÐrRL*\WaÄÿïü—çÉýj£“¤4¦Û;\ˆ·f±WaÖ$OCôÎîË> ª®ÅdŽ¡3Ãð?ÉŒ%Ú%œšE/•o†“P‘Ãõêñq¹T…Y¢¿Q­q&¶OâÉMÅáö©¼?Ãt×(ô:­ùÜAÄÔW¢&¨ˆãˆ¨)¯ÁM?ŠŸO pÒøq|G˜ªYpÕN³3‰(¯V8BŠý.ŠûüUñ™Š<ñ?˜÷ñ'Ïîýÿ’üün ÿÌü/ÔÝ7©ºNrkéðÊ ½ÜeÃt?géÿÏTG׫ƒ«ƒ«ƒ«ƒ«ƒ«ƒóWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWzõâ^G1îácÝÂÇ»…w î=Ü,{¸X÷p±îácÝÂÇ»…w î ün±K§·KƒðÁ˜ônèÜ9ɯ§û­úc¤ã·Tï&¾Ÿîö¾Ÿîö¾žHBl±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H4‘¾ŸAÐtAÐtAÐt "ºÄ‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"Ä‹,H±"ăIøÝ¶èÔúüIÈä×ÓÉDÙ¨‚Òª˜KN¡ö‚¥4•sZÉ´‹‹¯Ãq¥d¿R›I6é:\ˆÈþ#Y#¸¹È—ÈÔD²WÆr[JÜ’ÛJrCl‡CD§Ð”l7Œ¤ ÓüÍ^nú~~®[ìoJ9»öyøœ?Mާ6gÃä×ÓÉEADÅUÇÓtšiajÄ—Vê—-Ó £QÒ”Çl©JAo§åŠ…©i;†[ÐËŠx 7‰fµ¤Ôµ|戫%´W`AšRµ"20i±üªfé'zÖÔ‡®O\®HŸ#ȺA›ç¢²$=›©—Ë¿5&³5™¨0xÖo5q¦D•Z˜ëZÛ–¢6®Jñª'ȶ ‰Ägwñoùš¼ÝôÅ{ˆ$@¨H⊉$¸†IÔiUªƒ®µÅp¯ŠjQ¢Iâ:¬COJv«ˆjrG H•.‚Ÿ«‘Ìsi¿öß¾¨5%·\Ь€¯?5.\"M6Zɯ§’>‡YCíÅ‚Ô4B…£ÈÙlÖ¦¥)–Ö¢I&[IZ]M Q›HR ¤$)¤(†ÍÊ &Ú ¤)$„SHQ%$’6Q%†ÐJ‡{¤’H6f¶á’l6¢S-¬ÔÒ ´¨ÔÊ-.¤ÚH%–ÐÃi i NZm¤È›I¶“Ëf¬H¿‘²ƒZšBÍm!À¶Òá)´­8ÒhÄŽŸÌÕæï¦*huSU ›*TR¨F£C†ó\7Ma×hmê,9T šÕ˜Ê~¡æ5šÀQIý…^°kéä…¦ËÒ/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ôƒQ»éõGQÔuGQÔuGP“+¯H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H½"ô‹Ò/H5ŸìúyXF1ÆC d1ÆC d1ÆC d1ÆC d1ÆC d1ÆC d1ÆC d1ÆC iÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4Œi’.VÆC d1ÆC d1Æ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cHÆ‘#F4ŒiÒ1¤cH$‘x±ø‚D¨ò8‚DXüšúºÛ~+Š:r ‹É¯§û­4S Tg/&¾Ÿ‚URtiižÚ v>Âê[[ó#Å&1’Ó K­C„ÛròÉbdyFÝB+®*lt¿ð"¯>L…Ô#°h¨EqØóãK6êQ¦15êõÕMn¨Ë”šMe <ÊÜ8tîí™86&Ç”Üi±æ—öS_OÁSÿk¤+ˆ^–N¤ã¶¸s\i•¿4³SÖÛ1f9àÔÉR^CÑ&Tã²Ú8vKÍD™ð0å-­´ÿ¢!¯…Û~ê¼H±½‰áée&_>)ÿ@¶VU¥eH6¶iE¨×&#ªŸr•Q‹@–OÔ?²šúºæUØŠˆuv%#“_O÷\¡3MžÔ9îM}<½Š£b¨Ãت0ö*Œ=Š£b¨Ãت0ö*Œ=Š£b¨Ãت0ö*Œ=Š£b¨Ãت0ö*Œ1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC D1ÄC.…ðŢɇUL¸üšú»Úú»Úú~”›‰Ä1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 CÄ1 F®¥ðÔê¥OÊ©T9µôòsŠª.Õ•[¨´ÓœjÄxЪñ'@P‹5¶jÐd-ª¬'ä~Ý^Lú?Øm|UW“.u)äěɯ§” ¼UÄlHŒRšC”^ cô‘©2¡ñRa1?öêògÑþÃkâ—Beò‰Ce‚ä×ÓÊ5249Si‘ª j ”µÂÔ¶i´Î¦QÄ*djt¼F‡+öêògÑ{Ø‘gEEòÿ =ªÏârÅN¿6·Äª¦Teqdˆîûp†¢«ŒœŒÔn/ä¾ ¬Ôªí³^¨Ä¯S¸ÁšŒêhëtº/=ZqŽ>yÊmkŠ$R”ïºåB‹\ï”zGÔ™ Ôø·FT^/uRO޾_éɲ§êlµ³Q·W™¥2]Y.ȪUÕ‘Ä(†nTÚE6¥:ZiíÔÞ¿Ú.J™=¹<Úðšú~À¯&}Åtg«´ºõꤲàù…Ãu>]V«Bá)*KE—UqÊ,Ú-Mþ“RŽßJTø~C’xr2Šû” ÜjŸÒ¦Ò¡ÂL ptó«ðí©\á:§L“.Ã’iÕn£½D§¦™ìõ 9ø¿ãªu §S&ÇïFYBþœf›<"ySé;«—Fuâr’ê\“¥Br™"Kèå=}…ʼnÐÕ)|Úðšú~À¯&}ì6¾)UE5&-QNÉä×ÓÉEXö¦?T—V—ÅrZâéö_ýÙ“ºÂæ×Ó˵5Þ=’ˆH_ÒÜ„÷A“ OÃ’~ÆÒÔâø*!¡Î†ºlΉ>t>‰ßcàUJSUvªÔ¦«0Ý¥4íV©ÃmÔçÆg^?Œ¯&}Ä9ûo ç¼MœëRš–ð-å>*ÙîTŒÝ¶K†Ìs“%ÖPwu×ß\#uÄL•!öÑÜ$¹$ê/fC’fãÍ«Ÿìjp†Æ˜AwaÊ‘-Îèûj[Ê)ºƒí qØ¿Ô-|R©jvLZZš“ɯ§ì ògÑø‡‹Oj1§µ ¿‰ã¶  uã´“ˆÁ¶¸QÜIÅeO(ä·b²ú –̾'"²ê¦‚!°Ó‰ƒ²~šÚãyQ5á5ôò°Å†,1a‹ Xbðņ,1a‹ Xbðņ,1a‹ Xbðņ,1aóW“>ö^_O"¸Ë¢‡EŠ:(tPè¡ÑC¢‡EŠ:(tPè¡ÑC¢‡EŠ:(tPè¡ÑC¢‡E¸‹’¼™ôyEŸqwX[RçÆ€—e2Ã_œEJeÆCí±6<—cTbÌ[ry~ºÕ>±gFœÔz´oH¨Äˆã’e_Ô­|S§jT_iþM}<‘ô|H’ÚßýšþŽJògÑOPyç8žÜAÄT].W᧪@¨S£:•‹›4:¥.<%ǯðÿS‰S])Î_ ʦª…T T¤q- âñ ¹ ¨5>$á}çéU˜.U¿©Zøªk4Ì7÷6¾žHú8„IUR::£ª—ãÌj YdJUHš` µ¾%ýŒ¸n±&$7Ÿ’¿£’¼™ôEOƒé‰œ?ÁiáùTÊSeÔàÍ©@¬p̧‰¢Dæº'2Õ6‘2íŒõ>®®r{t*,ØÕ }6¶ÅN/ <ÕO×kˆ«RÝ«=Sái’æRµñ3MŸoSêË“_O$}ln,tÄûeý•äÏ£ý†×„×ÓÊÞƒ¡Ž†:èc¡Ž†:èc¡Ž†:èc¡Ž†:èc¡Ž†:èc¡Ž†:èc¡Ž†-ëÍ^Lú?ØmxM}?`W“>ö_F^…=š’ÉþM}?`W“>Å2äÌ9³'åLyç"ÊUe6ïx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%Žñ,w‰c¼KâXïÇx–;ıÞ%ˆ3ß”çãÍ¯Š›\/Uçiä×Óöy3èüF‚Q¢3M­˜íGJ£´á}_ë8>§6¾*­ª"eUAšúytXè±Ñc¢ÇEŽ‹:,tXè±Ñc¢ÇEŽ‹:,tXè±Ñc¢ÇEŽ‹:,tXè±Ñc¢ù«ÉŸGÃwÕþ³ƒêskÂkéû¼™ô|7}_ë8>§6¼&¾žU>#©@ªÌãY0ž¬ñƒtšŠ¸±–ørä–ë¼]Ùi“ø›“x²lZIq;ñÞÆN8¤qû.SkuÙÙgÇÊZdñl†_9µJ?wi8’§¯â«ÉŸGÃwÕþ³ƒêskâLÕ,?PTvù5ôò¨Ò™[ªð*ªª"²ùðt™Æ|!RM!<*CÐøZ­KDÚ-F¡Ã5^]Nk1Uq¹¿ã÷åR8‡†Äý‹¨6ÍO‡j3£5Ã5j[‘øR§HYÒå¿[ñUäÏ£á»êý¾çç² SÃ\–Ë+C‰p¾Üµ¥´´êG8>§6¾)ðJ;Ø Aòkéû¼™ô|7}^r* Åp©s}ôFhŠd²…+iŸ†D¶¢“&d9ð’Ò£ý›òŒŽëÔ1!¹-ÔÝV<ù¢˜úv>>„UxŠRV•—ÙdÔ[жKÈñ\y ’— ÆuÂe¸1Òó ¥µÖ¥›žCŸbÿg*B;sÄ}K”S›_èO)®M}<º¬uXê±ÕcªÇUŽ«V:¬uXê±ÕcªÇUŽ«V:¬uXê±ÕcªÇUŽ«V:¬uXê±Õ|ÕäÏ£áÊq,«»£¢TKK®-GË À^³Ü¤ÊDFÙaÉNª|d©G§Qø–ä‡I¨´àãñª‰(ä7ÉélÇ+Ÿ©)m¡¥í#á“9¸Êî†C¼G Š„gÛªEl²Ì–6^€¢2Qs—7 DWyd`K§)/$Øe1Ùu' Z—P ú­+å9{/¢\'Bé¤ÙÛ±Îl½bÃ<‡pv8iä>ŽR%5=Ù² Q-?TÄÙz­&#KWY‘5F7KH,•CQ.”hY8µ“hJæJL9…)<žy 7Üœt*LÖÉ—Rûn¸L·fJµ©ñÞ"Q+ã“)¸ˆî¶†%5$„‰ŠÓm%cE¥ ÙÃu8®’ê¬õ:‹Ì„¨–žReµ»²GwBB—ή«še·g§èáÇ7Š$¤Ëkã#%rîû¤ÔwŽ$ôÈæ© !\DŸúŒx㻲FÛ¨u/Kf0Mb" K„ Ĥ*lt«6£:ƒíCÈ‘!¸­¦©ÑA÷“–Ø”ú¨)…%d²çQ”hLvŽZ =½È.W9Aõ9µá5ôý^Lú>Ö’‰':E°žLgj®ΞÆVM…2öô¡·1AfmH*r¤ƒ(ÄL¨šžeÚ’¡«&8YL’M-OæY9‘-¶S¸½L*œÉr™ö%ÊkDœsÜíÊX:TTƒ‰ -ÉdŽd· *Do¾‘ÝÙ!žšøÿŒHÞ§°7¤<y¶¡vÓ1 ëbÚ‰„•®F§3“”ë\ixT›2&àÆx´¤¢Ed6ˆrÜd’ÂÞypØqøÐÕM¼ÓÛ²‡Gv{B“£n=}@YPp- ÓÔ§¦¶–YùsÏHî &±Âä¹Piv´©L%ÌîJ*Ll”å<Ü“JpÓ.L rÞˆiC°ƒUHQ-M³&R>ywL êñ-yÓR+¸4˜Óõ‡JÊ[Fˆï!Tç®§ÊN€ ¨TÖÃqYPË=¡Žká0LYP@ÄÜÜÖ‚@vÓH}ˆl@ÈnR˜3É.lâÏK²£A"ª²£$¹LSuX®ê,²ÚW¬ïrZAU£(.‡­1`áH@‹?*§¬åIB ´ ó„kÉw¶¨‡l¸v˜}ue0:ÔF9ë­ ²*Õі1r)í>N©mÁê“§­bÊc ”ºXvªƒ'ŠÁ·ÔÿȨ>ÂPLJŽÑDȉºlNSašªm¨®¦)VÓŒ!ºHBiäTŽØ:‹Í„G%‡R˜®ÈÚmškæB¢ú\y¸/>³hv¸Ž Y ªb5ÔðÔm§’B_a2Ye%)¤M\ uX„)5%Hæ×„×ÓÉÆu|g›w‹à¦$¾56qÔc~å^Lú?¼ìFâ~TÇžr, p\ „²üˆ¤•àR┦ñT¤ÅˆÑˆžRc¦SZRŒvv vÕ6Ï„¤›O)0š”}¡€šDDÙC%ÊD&eÍ"ASã$.ž¦rå¸Q"Tr\v– ÚQÈÊâU%®½°ÈiIH8ÓV#ÇDFþ')QÖ®Øašs ¨ËIoÇ(quZå"+½Ü]ä÷Ê$TÄo”ˆ­ÊOou±¯8E„QÔ§þnä:ÔÑfªª‰ JKnèÑþ â0 ˜l!@ÿ8NÅRç0°”¦ à—2Ó³* :¬12òru„µ)ø†or\&ª(M>2ÔÖ,3Ù¹o…ÒZ.Tq+޼¦Æ|û,1UÍúk©ˆ,F BMÚYïÁ’"Q*˜ ´’Ét– ]µ`âËh†&m¥Ù|ߎ܂íDÛ.ž'M˜j$.¨ŽÚoR#:k†M¶L \K¥0jí(PL6š’§f¶ÙD†QÒä'#¸rf<#ÓÐÒ¹;—¶PÏ%$”0¶3Fcm-vš“\hHŠj+‰˜Å“]+”’ZUHÔáÈ`"¦Ž¯I9†Ë)Ž×)öCuf¹™y‡%ÿÇ›_ßi¥½Ä1˜¨òkéäÿ•B¥K¤ÕøxÕÃScRŸ£Õ¥pBþå^Lú?#2ÚÙŽÔtª;N{Öc"SQaàWðC"?È”D] ŸBëÎLtJj,=sý²ÙmÐÜfZWÄó ÈJKHý™—Rj;L~ÎTDÉ£&+ÛK¤„%´ü m.%¸¬´p=Nm|]ɸ‘“‘užM}?`W“>†÷­ýgÔæ×ÅÛ$Fr?U|šúy^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼ù«ÉŸGÃ{Öþ³êskÂkéû¼™ô|7½oë8§6¼&¾žU>'¥Ñߨñ%6”Ùq9G/ŠépBx¾’ºzë0ÛC|GNz~.¥J•NâêMZDî%§SUJ®A­'öjògÑðÞõ¿¬àzœÚø§ËÓj-A2ä×ÓÉÕ¿B­Ù"‡XO Éšº,*‘R&À¨Oƒ E¡ðåF ?†Ùz$®£Ô#HâX2ΩF'ª\Kû5y3èøozßÖp=Nm|R*2ŸL|ŽCä×Óöy3èøozßÖp=Nm|Qè‡o6¾ž[m ¶†ÛCm¡¶ÐÛhm´6Úm ¶†ÛCm¡¶ÐÛhm´6Úm ¶†ÛCm¡¶ÐÛhm´6Úm ¶†ÛCm®jògÑðÞõ¿¬àzœÚðšú~À¯&}Ž â™ƒò¦<ó‘e"¼§4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7Æ›ãMñ¦øÓ|i¾4ßo7ÄfeW¬kÂkéäºÌåH¨Ä†äš¼N‘õ/Ý+ÉŸGÀf;QÒ¨í8^ÉI…ç6RžÔu•A÷†µX”TÛp¤ÔY‹s-‘âU¢Žüä2Ÿˆ6â]oÃ9è'{“Z«œm´ÚÍhðÓQKï#IÚÃqÛvsmIðÝ––¤"¢ƒRª(K±æl/×%0ã»=--Ùí´h¨!oxjU‰*‘-—*L·wõŽÒMHœg}£g¹'£&C^pA†§6áwD’qN#ÃTô%æ§!c¸$8¤«ÃvZZš“f§g.³3;¿_ʺ"L‡Wn\ÎM}<¥Q$׫’ûu:¡ ètº—°ü~ýÒ¼™ôe5““ qÖr¥R–ó©„ñ9â7hf}-ÉL§-õøŽAZãLŒ·ÒÔŠ3:Ѽ< ÛD74Õ“0#ª,o ÈòÒ¢-t§ihÖëOxrS¯Gb^W ¼¥³mÍðå´oÅy‰+’üwCP^Kž#åW˜qè’iËyßÈ’“ÄILvá¾Òa°q£øn±%—Ye¸rTÍ>*¢·áºË»£ÈiµÓüXïçðä0§^ŽÄ¼²â=%öéêLï‰¯Š¤Ëg>fÕQä×Óöy3èÿaµñNŠr›ƒâ·É¯§ì ògÑþÃkÂkéå…  (P0 a@Â…  (P0 a@Â…  (P0 a@Â…  (æ¯&}ì6¼&¾Ÿ°’_IJd6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ÈmÛ!¶Cl†Ù ²d6ˆ4] á:ÊÍíiO&¾ž\MªÝf,&§qLXÇÝå%MHž¢n]~=&5„鬯‰•"G SÛ\Þ`Ú•NÕ‚ ¢×[Þ˜®›Ü^ý鸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\Bâ 4¨D•Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅äúüHve6#i—*'&¾žOÓ!É}Ê9éMˆmœ(ê•£¡R ”XtØ”âL(蔊5·ÓNˆ„·I‚ÊÝ¥Ã}6.j3,+ö ògÑþ@窯Sù _èMÏb &à3ɯ§ì ògÑþ@ïª~¯ò¼&¾žXˆb!ˆ†"ˆb!ˆ†"ˆb!ˆ†"ˆb!ˆ†"ˆb!ˆ†"ˆb!ˆ†"ˆb!ˆ†"æ¯&}Zã¨ORjÕŸ†T–áFî¤â¹Ô+ ÓesUm•4ˆë?Ã]õOÕä¦Xœ{Aü+Q!4ùìU!üOÌ[3¹w(ÝËøk^_OØäÏ¢?È¿ùþ%§3Uã.&Óyú]9ž"¯°“¨pâjpdQ–üZ<Úe0 5•’£{<í5NS³¦øÝ¨ôˆõGj›àزø²;íÓ§ÀˆË-À¨Té­.´ï¶På wÕ?TWÿѵÜ$Rç¥ÊëoÐ_n+:Šœ\&õ΄Ä$ËœÀ’4ã¥:c¯Ôj±áVOÆn7 Ÿ @öª˜òä7œÌv¡%"›8¶ z7ðƾ)Uô¡èµô­îM}?`W“>ˆ‘™ª++}úT)/34w‘Q—K„äV©ÑX(´è°PÕ& Û!í”äa¶j…9F€òÛŠË.¦‹OBÝ¥Ã}Ù¨RÐqS­Ee…ÿ wÕ?T-´º…Ób9ê\)/ÈZèÜ2Å:ŒŠtFŠ-:$&âS!À>ÑhŒBj—± ‰tèµÒ|ˆ¬ËoQœè¥Bl»lLRaHuTè®k‡·ü1¯Š•±ÛªÛ»“_OØäÏ£üßTý_ä-|R¨ [Ñh CÜšú~À¯&}†§)èh9Îo±9å®EI1ÝUY åq ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\C¯'}Sõ~.æ¥M‰5Ǥ½RK UM)8ÕÉX¸…Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä..mxM}?`W“>Ã&I5ÀKŽ5OCO9©êbBSbŠ»êŸ«ñ*ž…<˜$—åÀÌÊiɽ¨(i_eê]|~¥×Ä3éûF¼&¾Ÿ°+ÉŸGø„¹&Š×Žïª~¯s¹HâºTWØyYäSX9žï¢3,º—ÚøeJjvnK2¥5 ˆ²ššÁŸB‰-©ñÌú58Õ49%NÖ|yrsùϪť’TN'ã­êÒ"JL¨PjêL~ů ¯§ì ògÑþ!RWÿ¡ñÝõOÕñjÕöiJ0£Óhm&¡X›Û©t8zž_H2d"$zMQº¼HŽŸtø*•F©LÓ*(ªEçT¨&— 4„KÄËÿáuõ¤rqiiŠ«uˆƒˆU‘M·/‡d“R¸‚u,û}s‰$jиe:Šâ‡ÔPgÒߦ?R¥?ƒXtŸf_G‹?^¨šLdT㮟H¯5U[œ@Ãuo†[å, q½Á”9[´~QÒUN#¡]N¨ô/iTú©u>äÝKˆ¦ImĺؔùEÃ1á%Äp£M¦‹Ä?®¥–¨õfë|¼&¾Ÿ°+ÉŸGø…Gý¿Žïª~¯‰PšŠl*--j‚¹Kwj´¥Kˆº]R à£þMwŠÕu9ùޝ2!Óø;Ï•f¨ìUÑêÒŸGOwªE>ßÄâ³=øÇGª÷&k§’g «:ïæU8wòå&]Z¤ì—«ÔøüI0—ôt”:ÔªúãÖæþrâ/ÒJâÏš ÈâäÉqPn5•ÇáÏg’ßP¦÷ O)êÍÄŠáeœš½%Ék©Ò;g 2á<ÔÎ#u2¹ñcŠí-6–Zá¯Ò8gУL¬U[£SŽ›oäqW:³‡„Ea£ÖâÊ)Ùü9ÖõŠê©³ø±Ón‚ÃDÃ(áûkœXÒ»b_B£Ç‘]¨F¤Ô ©O«ÕWreV©l¥D´Ô+×.­TMb‡L"‰Ä2«Êbº'W•¯ðµá5ôý^Lú?Ä'ÜðÞs4g”ô.Nú§êø•’îUl™V¹»l>'˜¤Ô+õZ4z¹V"îÒ™žõx½œ{­6ˆÝ9éSB~•©´êõ9ÙÒ*íUãÿÚâéiÐ≟›Åq?GÅR¿;‹3öÚ× ÇÖ¡8‚uoy×#‹˜„ª½#»U9q]Ê#ò{šëo&›Vᘫf›Ê 4 |5ùÔ¹îSå¶ûoߟż¥°R¢Çª¼íM¨ü9D“¹HLÆb§ú®"øÊ÷ÔPšL¥â/Ê“?õR8…Z3x^:˜¢Èý'?º.\žé”¦ TRž¤ð,F5b±=®—A§º“’ÂeG‹Zv-KE&4¬U%~G¼ÙÊ¢í7«®·øJ­TS'8zcMR*Οɯ ¯§ì ògÑþ!7ñ/×RËm8—›ªªÚm#ä{“¾©ú¾%¶k â´ryͧF¨¦*%8ùE„Ä$òv½Ê¯ È38wõnqbMØ¿¨âºôV(²VªñTW9&ДÉ⻣5F…Û©Qâ3<ŒºŠ EµW“™­üSi±j%Q¢&–8pÊYsf xÏ´»ÂT·‡ÄÍS[¢©5*“©lÇ S¢½Ë‹Sÿ õ”¨Ÿ%[“¾©ú¾¥Â%u#ö3#&lNƒ"+?e¨E݃ÃPž‹ ö´z3ÑkÓã.MxM}?`W“>ñc~Ÿ€¿Í®Q?µïõeøWù;꟫á×Ö£QXÖ¤“òño&¼&¾Ÿ°+ÉŸGø i¨”÷Œ_?ýæUhÞUÏúnþÞNú§êø|^wQȺñ—ËÄüšðšú~À¯&}¶mµµYœ¸QÒ¢Z~#>…Aš¹±ü*úÌñ˜ühPÿéÖfª<ÙkÄ£>§éÿ æ¿Áú×§/ð¬rwÕ?WÃu†ßþ'Xü+üšðšú~À¯&}±Ê”Ü6aËLƃŽ%¤|/³¦§j¥K^Jw'Ý&‰#j7)ʲ'¾ ª±ºIcƇøðå?ñ_ù¥WÒ“J,O|4ÆNü'ÕÿÔ? ‡'}SõW¿ Ÿ&¼&¾Ÿ°+ÉŸGÅyäGi™’–ïƒG|×/ã~[qÝåÿv±ñÕ…kó¦;šŸU]”úK—Då‚™•Ô&‚ñ|«'ÒH?ÉåWU´È%ލ$…k3Qá(íM=?þr—þº¢œ’*о“ä­|ªÆ(ɶ— ð«Tÿu_ÁþNú§êÿâ?ûšðšú~À¯&}†cŽ3éˆFšã³$T“ÕUžPf”Æ®!V2}Úºìb⸅Ä.!q ˆ\Bk¸¡Å-w®!q ˆ\B⸅dÍrâVƒQ¢üÑ–xë·˜«ªÔE[ ®®¨€¬u ˆ\B„ñ÷¢¬ÜBâ•unšvK¸…Ä+ÊÿŠ>×n!X_éf´RbSdì@¸…Ä.!q ˆU—Òšÿåªâw±SžIS§\B⸅Ä.!q ˆ\Bâ –Ó± ¯øÅ~cÏ®úi•ëˆ\Bâ LjQTœ¶Ÿ¢ Ç;kSÔ]Ê£)¹ õäïª~¯Äô·˜š‰oAê’XRªiIƨ¦JÅÄ.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!q ˆ\B⸅Ä.!ÄçørkÂkéû¼™ô~['[DT¡Ò‚YÜ‚‡Tõ1!)±-þ’²üúÝpºÒ—! G:º4êo“”¢BhÒ\[µÕt¦T“…Ï‚¢ûŒ³VäafÄÊK™iµgµéФ¡òTüõêOÊåG朕^ªÆèi¶”),ˆòš•ʧóKòÖEJ§¤uµà¢^Å\UÔDêTKM'òœzCqËà¯JUX¬åZù™®"úckÈØ›R\iZ]A­)W(³TÁV|ãÁ˜ÑQÊ2,¦ÐÿÕDNE²wÅ™òUÌÉ% ÜôÕ$k@¦µ¥6¸«iHMˆoð®Ö”e2dFÊG'}Sõ~%@%¼ÜCÒàfe4äÞÔ4¯â|WÿS“^_OØäÏ£áÖ÷´Ç±Bš´Ë¥Nx•Hmĺ…Rq®™!r#Už6)óà·$ùDª*ÛÔ•Xq7ÖC”îe=“—/ó*±ÿIW¿šEä‹X;ÜK r™Sy.D¾zÔ/’ªÿÏZª8ML#êSÕdzä.*Ñ0›r^§µ¡=ÉM2쿚¯ô×QQ•.F<(’ñ½Du­z¸«–Z…8íC'¾×–N?ý˜oÖšmHY8\übW?b£óϬ¾iI^Jhmåè? ™2é+BÉÄUŸÁDEǧ!dâ%ÝVDfå´(ꩊi߉ֿ-§ ù,. ËSÕ7¤~]j·óG\AQ,•• —ÍßTý_ãÜ]þ¯“^_OØäϣ᭬FR̸q-cZÑŠRU¸Ÿ‘!2ZZ©ß—:®¢7’ÉÏCkÍHå±JeWÖ#XÕ6AI‚ôÆ#‡k±†X[1Т]fI­HJ‰i¢þ1£~š¯5Yg¶Œmթ䘈Uè¦|ÒÔdÍq}e-”¹ú®²*¯¥tªKxáyˆôåIzwåÔªg“ݺ•hÔÈL3‹¢*ƒÍ$Ô*¥l¥Je‡&:d´IS2"¨¤Ë©—F ÇQUdDjI¹…¢žâ»›ÿò5¯!ž­éS ¡xî´O7úªRâSI)ÇÛoL´¢S1)œ‘!M~Zz^\yñe§GSÊß õ‡L‚R‘!…mDvœP[6Øh‰©udFÐÚ1¶t¢)Ò~TX0¬v-2CN&˜ÂLt ¦ÛS¬ ÎfJâÓ3;4ÐJ:éãÏ̪ÈIE›"f%ËJ +íºÓ/?S¦°ÔõÓX„ò&™R`S¦1NLš¡ÌKo=¼‘ Óxçw)qöKNN]9f¨Ñê @*t%H‡$z–ľŒÀH"$“<Û¯Ã$8ˆVɨ¶k2B&ŠJzO7}SõqŸþk“^_OØäÏ£ây‚.ÖòµNêãÜ—²Râi!ÇŽ$ˆ‘S¾]:ü]¿ e”Çoœ¯Æ,'zRéEÒ9Ó!,CÆç'¡%çÛ>•?Ââ Ô7-Q …2Whf—Yå$––"·»{{ þþj˜4’‰ÚmK.¨fƒP2GJI ä„=¶ÒÒ>–¨¯3 3åñKaO"$| 1€á°qÙæïª~¯ñî-ÿα膼&¾Ÿ°+ÉŸGöQ °>eޅׯY\ˆ«éC‚VÃðøU"~2¼™~Žâ®gøU"þ3>Ue’µŸÒ3ñÝõOÕþ=Åùø_ôÃ^_OØäÏ£û$|µ:_ýOض¾”håkÿ…BŸøŸ‚óyZ†É±›ÿ…BŸø«àWúßÝ;꟫ü{ˆË­ ˜}i¡¯ ¯§ì ògÑý”£Å. l‡ûlr.…àLü¦~,xÓ?éŸõ¾ýÛ¾©ú¿½óºL3KyŤuëû_?¯_ŠK¸#ÒÝZÙý¬9k\Á^MÔJ2®£†¼&¾Ÿ°+ÉŸGöU6”´‘t/ؼˇ7’CŠæºü&ßJ‰d*?+T²éƨ~ Æy¨‘~/ùoÛU%i@b èKäïª~¯ˆR[7Ætfç&[Qs9±%¹%ÉÉ-´ç)kT¹ïÉr¯óGoä«Ô_Xm&ʲÏa*¹ ¤6oU‹9Af/· ¹y {†s>7åµTž6¢RËy·)§\Ub°ç{„¨&qAID”u,6Û‰yªçú&.¬yÛó#¹µÝ œéªw3Ù>”Ó.rL¦”ÿ*©fLYwS`]ç׉‹5éâ²›é?ô¡¯ ¯§ì ògÑñjsdéŸäÍB3ïò~¼’6œK͉UÆ"Êð”¢BY­BðsÕ©O8Hj ‡©Ô´ªžU™tb 1âš}ž{ÌIga†›ÄÓ¯!†Ø}¹-ïÇ7çÖZ‚½¦õ©•B¨rZÒÒÄÑ 'ð8Ú]AÇj£V„ã”ÙœŸ®ÂŽæ±mƒq¾n8–[*„ä6…“ˆIˆˆ2Ó: •*\‰ÔêNl:ênMŠ’yô(µÃuñZüÕówÕ?WÃòÕ0Èú•ÿ«ç×%ZIâ¨LœˆBs¸a”g!Žàð;;‹g}PßÚŠë„Ót¶Ì˜?ʬ8{5WþJ³Uwä«%3ind€¥ÇV¾zÂ^8`·©3•IÜ0]oURå”D°ò$5ÉŠ‹o¾;’”¦!œ“b#ù˜ù*¼žs (†½NC©mš!ò—ùU8òI?øÉ\ª?3Ò?.¨*?šå)Ã\%þm]‡5ɤ`O7:¸ÚTJK,& äÔJyÂe¦ ©êt)[l·RmÉN|õw Û‰PŽgl’~“.6J|¶"TÊêmý(kÂkéû¼™ô|6¦äÕf< ¡Éµ ÄS—Mï-7MYÔji•FoR™;~%nJ£S¢CDXtÙêïMi-³–*ͶUIóJ«•6r¥”º±2þ:¬Á.ší=¦L†LúÓ!dUÙò)ÑäÇZæQfK©Ä=úÃæ¨ñªPMØZÕ)¡5‡!Šoëç &K4‰x¢EœÄâ‘!¸¬Çau§ž¤:ÛÉ¡B(Ðé±à·…áSé`ªþº^4ã¥,àÉ–£Qn«&93\d׿6êMó¨ÁLö6j¬’hª”Ma0¨’M-ùÑã$á½&™½ØN¤"Ÿ¹r;®¹Ä6SÜ*T†˜•PDv¡P-º+é•Vq4¸jˆÍ@´*Sj¨ˆâ˜—Wvu=Å>u °\Ÿ=0›VT¶¦6õ:-RbõÛânú§êøsÜÅ ÝMŸøè'žc´ü“Ÿüº¯*çH«þÕùµt–•HHs „oS;Zt5¢rWÉYz¤¶äK–´*L³•MJI ‘L7òçWAœ4(œCWy¤¾ÒžÊaH9 =ù•z›jS1ä"KKüÊÄ3(ò)„nG«oÔÓŠ0M@Î|—pG§Ç$Ó‘{-ÅŽQc̉œ9l”‘t`¸nÍŠQ`D<Óݧ䜚e B2ŠûÕf‡þ”5á5ôý^Lú>•—8ÔxÑdrzúMAýVh™Hyém4–[ø'Æ’ÌÊd ˜*;ñAPPùö(†ŒÐu´¼ÛN9 šl2 Ø ½/â‘J‰-úƒ}²[ *·'áÂ%2Û•ri”õEåS‚©I¥Är:ÑÚ’žÍIBh2¨ŒzgÀe*3ÌP °‘xJRIDÕ*[‰JI iìT”’§äû’Ìkôò•ãÓéo5#”¸R›™N‚Pæïª~¯‡Xüa‰p˜k,zyíÈ–ÆÌh2ÒäJZN´ˆ‹1e­ø$ÆD¦âÄDTó“2™B ´UújZzCäeÔ¢ED6EH­ÉSY›”Ç¡þ¦eE¬Ði‡Ê£f¸ÎÉ]Ar%Š*b]§4ìŽWZŠŠ;´èÿ ‰¸aPT®WŸ'Q•ºc¿ñÔ‚º9¨ˆÁ-0ª0ä<$7ÛÞ†düÙ4öå:Ei?§^ª7’žÓĸÉeJ£Í‰ÃËãQŠ$DCh)D’åÄ2vdçQ*‡CÿJðšú~À¯&}‰Ï-r*IŽêªÈO#}{ s6666666663¶666666666666666 æÔ[ q+äïª~¯ÇsÎ-ê’XRªiIƨ¦JêS"ÀcÛ*8öÊŽ=²£†ø²ˆÐöÊŽÄ<âÓÆd'Û*8öÊŽ=­¢döÊŽ=²£l¨ãÛ*8öÊŽ=²£l¨ãÛ*8öÊŽ=²£l¨á|_Fq)ã 2í•{eGÙQǶTqí•9ÅÔWPž0£!+âê+¨GQZG¶TpßÑYG¶Tp×Ðã—~§Ýí•{eGÙQÃÜgM&»kðXC¥ÅàqT–ý²£l¨ãÛ*8‘Æ0 “€í¿l¨ãÛ*8öÊŽ;Ã2Û6“Âò4\®¦7BKqU@öÆŽCÛ*8ŸÄlÕR‹†f{eGÙQÆ™ñ:¤Šâª95Å´fšC¸ŽT!jl¨ãÛ*8öÊŽ=²£l¨ãÛ*8öÊŽ=²£l¨áù­qD¨uV¸qÏl¨â‚i|âUbR Q?Ò†¼&¾Ÿ°+ÉŸGãjž†žr SÔÄ<„¦ÄòR‰ Ê‹–â-†‰îkZ[FD^·ØÜc?5¸–‘‘7ªcy2[¼ÖâZNDÞs'›˜Ã®ó7PJeöä%¹ÑQ¾Ù7ÌÜJT܆žVÃDósuÞjq(4HiÇ2&öd5!<ÔâR¦ä4êÔóh6$³$¹›¨%2ûr‰-8¶d5 ¹›È#iæä ¥° Ä–d—5Hi$Ûˆy Ëaâeöä#š¤4”¡Äº„ÍŽ´3!©)äïª~¯ÆÍ= ;.fSNMíACJæn$–‡áeEì¾Ü„óÈ’ZK©9 $3!©)ç‘7¥Ô)´MŽêq#žDÞO6møÊi§Pú9ªcCÏ·”Ë…‘óT–P‚ZTØæËN¡ôsT†’”8—P©Œ!¿RYBP´¸…ÎŒÒú—5LaqÄ2…Ka ãÏÈ*cKŽ¡”9:3H#ê\”¢BU%”)çÛŽ•Êe´óZÒÚ%”8óíFK³c±ð5á5ôý^Lú>,æ‰èiÒMB,¥¥H^Nu6IøGýeF4¥¸œOçUg=9èÿ­^FgEB²sª³š#±¿ZyŸ#Ry¾Ê™LVPÄ• Q8¼ä²G:1¦I­µdƒ‘©<æ3|†M2$M†¥®æÌç-›¥°i’䘄§éî:³æû(nd/Ï[‡óeóy¤3*æ‘& {ެù­)†¨hü§\ƒ…ù’y¨“El‰ŒyΞ·VžNú§êøÒ#’ªØ6šÒ–Góeóz9*¥ •4ËpßH§¸êþ#%U6bþƒó–Ý<àÕIÔšÖ˜yfÝ[–„¸“üˆZZ£Ë§:K§6â§óü 4¸·SNÂà-Õ±ÍD˜B)SL â {jf3"‚˜‘ÐmJb3&³k’З‘óLf,NmLÁä´%Ä+ò IYFlÛÄÓ&³k”æ‰èo¨„Ž¥–Õ¨¨Sq¹TÙ'àIRNDŽ¢Çc°^\šðšú~À¯&}äú§êÿ!kÂkéû¼™ô;꟫ü…¯ ¯§ì ògÑþ@ïª~¯ò¼&¾Ÿ°+ÉŸGïÍzMK„f;&5Aõ!{‡{R^Z¤¤× oÞ¹HX«Ju\I0ãò‘!o»IyoÄâÛs¢Û’—$S!z‹šã )oC¯-h¨:¤?"A6·T™&8úÅVBâÓÑ%ÖÞiÅ» œt‚žZ믴ä‡VƒTçÓ1ÕÈy–S-åßyɘ¶Ó弟¶»êŸ«áñÇiôV§ÈfTgÕ"š™.)¶ã–ã,’d@3P˜“¿e{‘$ªBëèÌúç°ªÍr:Ÿe5Y p‹ÓêȘ¾#¨<šDÇåâ .2Í&KŒÍšâ›$É“‚\>–A‡ÖÖ&‰­ÍqÖb¼o³F›)éuø ‘:¯2S­O#‰Y«Ì:LÓ©RÇÔ_r­þ?¨¾ãî<¶æ««°¦0HaòKrT—•Ÿ8­91Æšâf›Hº-I¶œE~\ù…WWTbÒäVª×öF¼&¾Ÿ°+ÉŸGèpüZ“°¡3O`›I)1ZB›‚dû‘šz?³4ýxÆi©j—“_ SœO'©,>ãm¥”VÍÝV²”fÒ§#a¸m!)ŠÚÅlÝ(l\vÖ5›êÜVÙPRIiGCCÝ?Ci˜%ÍÛ&>sÓjÄ0†ÁBe$ˆ­ k7×Q«Zi,—Û]õOÕðÜm/6×RÚ”dFXQi ‰dÚIHA6‡!¶ãšÍÜÜvÚ9”8SäHŠÔ¢~ @:dcƒ+‡Y¨U•Iˆ ÌV£¨IŒÜ¶¢RX†µ¶•ŒiȆÒÚ0"À¦’¥j5Ñ ¥°Ž€Ü˜ôèñ\v+o;Oá¶#¾Í*,q3p£ ÇíŠM-œiÉ®‹Ú\N4äq´º„Äi%¨×I1™Š$HíEáèp¥½ µ®›Â°âSž¥E‘öV¼&¾Ÿ°+ÉŸGù¾©ú¿ÈZø2ÈC! „2ÈA¯£ì:ºØÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðÈðI)JZLÆG†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G†G…ï&Òðcúa#Z‡GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGæªâðcz`W“>ö_š>Y;Sf¡Ê7§öy3èÿaµñ9B¦¼â–‘Ê7§öy3èŽ+¬W(D\DtB•ÅôˆNNâÊM9×øž— ñE-4ØüGM•î8¥vÈœRš¢Ë‹iP™Æ4xÏâš]0Gܶ?­Zð£ú`W“>ˆãȯL¡Ôáºïñjr$ð½:C5Øt·£ÐIÚêi…C¨ËŠûÎñ1Y•1z†cÓŸ'4¤B‰Ã›eDþµkà;ÇÎ?0|ãç8Jm/°+ÉŸGû ¯µ«ÉŸGû ¯µ«ÉŸGû ¯µ«ÉŸG‘ñRÙâF8»GÃŽúx¶2™¦ÔZªDþO_©9K¦Ó8™2öÒ"™1U.&ä7ÄÑ\j772x´¤Í‰Æ(U>GBd%D´øžÚ<Šœ'•&°×Èv:ëi‘¸ÆÉ_Åf;¼VË+sŠ"·5Ž0!è¼^ü¨1øÅ²§¡iuT*4˜ W8øº2¶PÐÕ:pf¥ÄSf¿ÅðškÍL©Éã±¥!÷Úãhn1Zâ´ÓcIâ¦b-.£Å­M]:¾4{až'eÈŠâøfÌ> TÊôÒA®B-lѪe"—ͯµ«ÉŸG”®jräpxžÉþ\Þ niÑé…Hüž¯Cn´ô® Báש«§;@ƒ* 8EÓ}®u©ðô¨<&ªzà÷a°\ÛQ˜o >#œ4ëóÕÃϽ:7 *8í §Ò)¼$¹´Öx›6€ûµ8)¥UãðÆÙá4üÚÐÓdË^r™Þij¤]Wc€0¢O ©÷¨ü:íJ\Ù¼O#€#©tÚIS¥9Ã.é-\—"ûëíÔx3¸¾ÓdË^-Vs¦¯„¯j³@š‹œn7ƒÞ§²Íqêæ’Q •5è4QcókíjògÑþÃkíjògÑc c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c cË“_kW“>'æGŠ©8qå^!—Û’Ø)̪/À¥GÔ¿’8ûm*MF,%J©D€úþÕÇÛiRªQ ªMJ$5~Õºý5לq,¶•ÒÛ¨t¾ ÿäM)Þó‡¼áï8{Îó‡¼áï8{Îó‡¼áï8{Îó‡¼áï8{Îó‡¼áï8{Îó„ ;°y5öµy3èòdšŒ%=&¡[Oé<…YÕuÆÅ§s’ë‹R0¥Ê¦OP©Œ6ÄO䕨Íw ±·•øÏDß·‚— ]Åùo9µÑûÔf»„„<åQN¶ô*±\%wå¼äfÔKGìOþJµYj<êM7ýi%0i“Ýr(˜Ë‘Ãgsb»þóö´/ô|šûZ¼™ôy? <£‘K‡-e’hcFI0#M Á§S“*<*SqâéG(ìÆf;Qá± ¿’-¤8ri&:õ&”­¤8Öï]2¿³[HpäÓ¢Í\š< Žkµƒ w®™ ßÙ¶Ò ŒÒJI ›HfXnŸ–U•.SÿÇ{³½Øv#݈÷b=Øv#݈÷b=Øv#݈÷b=Øv#݈÷b=Øv#݈÷b=؈´ òkíjògÑþÃkíjògÑc c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c cË“_kW“>)uh°\z³‡¤VâÅ >™-ô(’“6ìÑ;pí÷Ü;pí÷Ü;pí÷Ü;pBlG&¾Ö¯&}•3636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636<ù5öµy3èÿaµöµy3èò—V‹Ç«1XzEn,PÃé’ÑŸB‰)3cò-2÷ÑŸäõ „z\Yu˜°Ümļßí©Æ*MN4IjÑà-§Pû´*äC“2sPk3ÚbKr‹à©qýBGÞEH{È©y!ï"¤=äT‡¼ŠáÎ%“W…ÜÁÁÜÁÁÜÁÁÜÁÁÜÁÁÜÁÁÜÁÀÚ®o“_kW“>)’»tôKJjgìUQÈ·¨•0¶„™JØ(D”?ÕŒtJM¡Éx¨¥8™S ÅG\^]t”ã:ÍÍþƲE±\"º¡Š=fjÞsƒF…Ý%8γgs±¦9ªÍaödÌáçMèî3 ->YFq™ôÈ­«b»þóâàõ>3>&¾Ö¯&}è‰}ÿéÉpÑ5?¾§Ì•îÞš=ÛÓG»zh÷oMíé£Ý½4R¸j5"?olvöÇolvöÇolvöÇolvöÇolvöÇolvöÇolvöÂSjy5öµy3茨!™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±™±çɯµ«ÉŸGû ¯µ«ÉŸG”ºº"¼ºÉlL¬"aÓy§–ÕI½%Ëa¶6:#”¦M¤OŒã2j5<¦e¥‰›Pûn6ÝB+É̃S3#ÉRjV¼í[ü~m^4q/7ûY58Ñ$L¬Å‚âN'ölV¢IUȇ&læ)ÑÚq/4Ä–åÁRãú„:¼Š÷‘Rò*C†x²]dwppwppwppwppwppwppwppwppwj¹¾M}­^Lú<¦ðæãQN©$äA6×-u„Ï3%q°)ˆÈˆã´ŠÃŠsi YaÌJ,¶¶èþ¾zÒôç(ñ¿QÃñ -.}ËøýeĦ¯ Ìø!th]ÒSŒë6w7û*áÕéÑìœf|º4.é)Æu›;›ý„:¬½J˜æ«3d32‘MÿZã0¢Óå”gŸLŠÐhú¶+¿ï9ðì™ôy5öµy3èþÃ]½Žq¢5 Òá¢j~ |O™+ݽ4{·¦vôÑIá8”aÛÛ½±ÛÛ½±ÛÛ½±ÛÛ½±ÛÛ½±ÛÛ½±ÛÛ½±ÛÛ½±ÛÛ M©ä×ÚÕäÏ¢2‘ ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊC) ¤2ÊCÏ“_kW“>ö_kW“>)utEyu’Ø™X8DæóN--!ª‹zG%’B'Fu´Ô"­„Ëal±)™Eüš}Yª{Óê.Áæ¡è'X€I~|hÊýœÚÊb;&¶†œL¶Wë /Ï_²n´N½> PŽ äObz öÛ¨Eu‚«Á2åVã ¼j¯¶õ¡N¨È~Ÿ¸èÜtn:7ŽÇFã£qѸèÜtn:7ŽÇFã£qѸèÜtn:;›ä×ÚÕäÏ£Êa?n5ê’NDSmr×YaÍåÓ‰TÚä]˜µvŒ„ˆ‹•($'ù5m¥ºÍ]µÎ]}¥;CU<»³Œ<ÄFúãý•ni»'cµÎvÌpr©åÝœaæ"7×ìiôýTÖº¾ilš“j öR y¨ÚôÅwýऩý›>&¾Ö¯&}êWã7(¾ø>‘%ÿb(¡ªtvÓhi´4Úm 6†›CM¡¦ÐÓhi´4Úm 6†›CM¡¦ÐÓhi´4ÚV—&¾Ö¯&}”ˆe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†RHe!”†R|šûZ¼™ô°ÚûZ¼™ôyIª<™J©ÉreB£2 XSªjCèŒÄ%¼ì_å•Z£Tx[×:ÄKóãFWí%ÕußL¦Î1Ö _Ÿ2¿dÍ}·?LAœ‰ìB¯AžÛu®°Ux&\”ê\Ütn:7ŽÇFã£qѸèÜtn:7ŽÇFã£qѸèÜtn:7ŽÇCGs|šûZ¼™ôyN…%»[‰•>;’¡ ñܘ÷òÞ …P}Sšï ªž]ÙÆb#}qþΣ”U¥1)\"ªywgyˆõÇûQV—ªu‡‰FKHƒ5&Ôì.¤*óQµé‡½oÚ³èòkíjògÑþ¥~3r‹à8­(ôÚm 6†›CM¡¦ÐÓhi´4Úm 6†›CM¡¦ÐÓhi´4Úm 6†›CM Eirkíjògј¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bó˜¼Åæ/1y‹Ì^bóæ×ÚÕäÏ£ý†×ÚÕäÏ£ý†×ÚÕäÏ£ýr§z/”î"j[–^ŽókíjògÑþ¹Oä9ʾïOä÷ç6¾Ö¯&}ëÇøk;ÿ_kW“>ö_kW’ChÚhm46šM ¦†ÓCi¡´ÐÚhm46šM ¦†ÓCi¡´ÐÚhm46šM ¦†ÓCi¡´ÐÚhm46šM ¦†ÓCi¡´ÐÚhm46šM ¦†ÓCi¡´ÐÚhm46šM ¦†ÓCi¡´ÐÚhm46šM ¦†ÓCi¡´ÐÚhm46šM ¦†ÓCi¡´ÐÚhm46šM ¦†ÓCi¡´ÐÚhm46šM ¦†ÓCi¡´ÐÚhm46šM ¦†ÓCi¡´ÐÚhm46šM ¦†ÓCi¡´ÐÚhm66›M¦ÆÓci±´ØÚlm66›M¦ÆÓci±´ØÚlm66›M¦ÆÓci±´ØÚlm66›M¦ÆÓci±´ØÚlm66›M¦ÆÓci±´ØÚlm66›M¦ÆÓci±´ØÚlm66›M¦ÆÓci±´ØÚlm66›M¦ÆÓci±´ØÚlm66›M¦ÆÓci±´ØÚlm66›M¦ÆÓci±´ØÚlm66›M¦ÆÓci±´ØÚlm66›M¦ÆÓci±´ØÚlm66› y}®Â1Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2Èc!Œ†2ÿî_ÿÄN !1AQ¡"2aq± 3RS‘ÁÑáð#0@BPc4`bpr$C¢²Âñ‚’D€Ò âÿÚ?þxѧ¦ªÚ{L/ûwõw|Sþ€m6—:¶£âœqºpá·ÛY`£¦¨¿î±èÍð_÷_èÿ›à¾ŒúbŸÒD´6ë‡óžÏPR¬ÊŽÈU¦,•ÛÑÖ¾•úKŒ»EK˜7øŸõ?ìmþ¡ÜU’ÎÛCË\è·,z{3YLV¤ëÍ8e¯ú_öÇÿO´xŽæáŸ»äO%¤kN`û'àœy>D °Ï$&æ§.•8OL-½gwÏ©8ð£…î„Lt{‘Âz‚d9àjL2Ö“²Tí[z¥!ÂzÂzã].¨X5Gt¦áx.½±Ú¶Î£«RÕ'lv„L4;¦;ÑÁÏF7-DFS8G·$òïé?¤YôeÇœ‚ú'麬¯rÒék¨û¼OúŸö6ÿPî*ÅZ„Õ˜ Œ:D*õ©hE 2v¯ú_öÇÿO´xŸŠv(À4d õ!ɈÛ=êî`tGP3Ã0d 4lQ’v.Ÿ™ùï(âg¤ï+0% !4@ƒÀqމö'cz5ü¿k÷B~¡óèpvÅOêËc šØhiÙå Ž„q=¢D9<^ž”yÏžHD`þ˜îäyÓÑï÷ð´ÅRþd& ´šÍcz"I?Å;ˆGœó´û!jퟂŽò}hÉgLϽ<_sñHõBt¼Ì–ŸVâç;ln'ùwkÿ§ê[kÕkãý?ÿ¥ÿj~·ù~*“ :mcŒ‘Ão±2ßGCQÚƒÓ—â¿íOÖÿ/Å}ô=?£IpuçþëB… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (ÿ e±¶F‚D’¼5ú{þ Ã_§¿à¼5ú{þ Ã_§¿à¼5ú{þ Ã_§¿à¼5ú{þ Ã_§¿à¼5ú{þ Ã_§¿à¼5ú{þ Ã_§¿à¼5ú{þ Ã_§¿à¨Õmzb£r?q©È¦6ÇwØ»“IïØ°d·?ÜšzN=̦¿»íö}¿Ñ¿²³·¿íjÖ°ôžï’©6õfNÕHÈ3´ª¸Q‘ç5U@yÞä9\ýɇEVãñáA§QôήâªáH n;µüôp¼èᣜqê íýpQ7¬µIóU\(Ïñ58èÚ³—½Î*ΟFüÁ…MØG_ÏfJ ¹uã#‚ª~¤»¥£ç¥ÀØJyê *gaU ÚÕݾ¡³½Òæf7©i³º§Wµ7ë ?­H8‚iYüõ'‹—2v¾+«èêT.æ´Þ›\9÷ NÑÓÕñ…F×zŽ– oRm¡¦õîLcŽÍ©¶ \Ö‘{)õ¦ZZð\8õ&WuÂÒ}j¥Õ(²£°’;~ÓíLa8A:ÐóL4’6.2ÂYìDlL}ö‡ú‚™µª•1ïEgštœñ¨(¯zyäVsU¯ß9kQ³ÚŸPS"öµR ¦1áv §Øïw¬vÇj&NÙö|÷'aMÄgóz¸;'±LcÐO«5ñ>¥3ùš£ê¹²üu·(ö«=¤¹­¾8N©BÒÒèÕ1:¥ K9Å;¶÷*oŽÆ´ß4î>±á± à¸4´‰ùëTí$°¹íŒHëÄôúýËŒ´ Aœ£^)¾&#ƒé¯îû}œ$S¢íuÌû>*°¦6ŸfÐŒ4”êTM«‹ xm“ëTìåí$ ÊuªTXÚUW1„éÙ¯ 7£fp ÇD xª–rÆ—‚ g•{;¨±Ä¸HÕ­Z,qQ™câ>OÑ¿²³·¿íksiužåCÊ·¬*_‹¬ªÞCÿ&÷ªÿ³·ú½Ü¼³Æ÷ä«c£«ÿ‰ö{•NUb57z&a0ªáhëkP’y›=Xتùü›Þ«%ÔFùà ?´ä*<ÞÓÞUo ?¨{OÙÏõ3ÚŽ:eîÆ”ñ‡†ûUOÚ*Ž•G2zroìêÔòõ¿«Ø_'Kúú|Zô^ý5ÑÎhzsNž›ÆB}ˆYê"1iœóÏÕFÎj2¥áw’g§ÔWT­F[søNäÊU[fsƒ±ï÷*œÛCj]3'1ҩѪ(S¤G5ÃÔ'iÖm7Ðkfgêœú¥Q¦i×.Õ Ý)”^Ú4šöLtÁ=jÎ*6sD*Ó3ŸïE¤M°§>‰©zûsÆ®ÏohV{·ØA€r£`È€áS Úfsá0[3¸jœ>qC ë'zƒtmï÷#‹Ý¡Xæí ÐìPFõžÊÿÛé":=còN³œÍ$rLο‡Je¶•6kižô,õE ôàdŠu™÷ª9§¥½o[·*T…:b–Á ”j]ÃëÀje– {èäœõœìÏ$ë3œÂÃëöp>´,ä0€Æã«WÏb³Óu6ïøèàúkû¾ßg ´uÍòè:þBªöÌ‚p–Ÿm®æ—ý[°êéõ¦Vc©µ® F¶uêÃr}`öU“‹œú½ëNÖV¥Tct7p‚ªÕn‰Ík^õ^¥7Òx.¼Hà {OWIO¬Ãku@pƒþ’;ø~ý•½ÿjþP`‰îY'Ý./•Rj2ѹ8Ë:w.g7´’çfPuÚoqÈcÚ6–·øL<íY)pÕth_IºÄ'ò©\éÔ°sn;$ nJ‡Õ<=Ûdªmº ô÷ªœªaƒl¬ ‘Bg£€t±Ù‹y»ÑZ_Ð=zÕHuz³©Þì¥Í¹©?•EÔÆ¾åý¦SùM`ØIÝbÊTé™c@þV}5ýßo³íþý•½ÿsâŸËÃVs8Ô{üã?Ë«e¶¶€L¼ ú›¾+À¿©»â¼ ú›¾+À¿©»â¼ ú›¾+À¿©»â¼ ú›¾+À¿©»â¼ ú›¾+À¿©»â¼ ú›¾+À¿©»â¼ ú›¾+À¿©»â¨Òm b›uxÖŠŽc@feYé¹%ùŸñ¿¤ý%6¿hûL¿*8"Ž:ÑÂg£~_—Ù|…>¡ÝöšÏ®Å­ ½l[>v!”£„öpd½èåÚŽ¿HáóжðÅ×íàwâà9“ó—ÕÚ£WZÀCMÅÍMÆên$ÜͽiŸ†Sy²Ž¾Ïb8Ogr8OgzÈ£ø‘á99á7RÙÚµ;_gr:ú½ÿ¾ð tüûP—5Ý'Õ>ä]ɼ5ÝŽßtPCÜ­Än  9Â2½wÙìL冻QÂT’ÉÛ{ÔªrAPŸ qØucyÝg¿Ä«øü?íϽʯãÿø~^ÊU©´1®:>*í£ÎúŸÿ_~8øý'Oòp„91#³ä¨ѳ$îQ“¶{Uã|?^}¨r@TïÁdèŽÄyXyS:Ìö¬ÉvÞÃ%¿Ãü6¼uî±ù#{‹ºµã0OóÀÙpÓ¿Éû ÕêÒp0&?„*†­†ž´j0:áv)Õi³8úŒ§‹Ì'Tc罡·ÉÁ>ÓJ›Bpùù(T¼ðÖäDüûÓj1æëL•¥¦MÛÂQ¨Æºé8ø®Á×z·‰Y r8+\-qâ´^T¾²5&›ór¦5!ʳt„10¸þhZ³¥ý^Ç+ Úäù£½ÊÑRYS g(ÇœûPc]V¼Ÿé†Q{àÌHÿ•¥J@g'XË d©@¥IÏæ‡>}f0õõ*†“©9ô†šOalŸR¯5t:éáë(:•GÒ3Ô ÌîWG.×{ýêÐæÓ}B1&9$g–_'Å©åPî Ðtq”ôdÖ«ã¬ZÑœl¦âjåÞWâ<=^&§u;¸§à åÛ»Ó„é@ó·cðMåTÿÄŽø_ÝS'¹<ç†ù­øîM<¬6ž½‹Züeßþõk\7GFò¥[H{=¿:»|oÙ|Íåx6Ëæo+Á¶_3y^ ²ù›Êðm—ÌÞWƒl¾fò¼eó7•àÛ/™¼¯Ù|Íåx6Ëæo+Á¶_3y^ ²ù›Êðm—ÌÞWƒl¾fò¼eó7•àÛ/™¼ÿ‹¡®»ÔQÇ;b»õ†žÀ¬&ã17Fju£ÉÀÿ8ÛhkªdG^¾¤êímALcÕ«¯Æ«nÁܪO|íjµ8ÿITÌXçúgç½0}mêù Îyw³‚œ"“Ü1ng×üã©ec¹¸wz•;+ÎÇ»Õã]xæŽ-¸rRoé5û“y$‘­KƒÆa7‘‹S…ìþöóõOšÄS.éoz Ôf}HjmêÍ^䇎iù ÐÖ‡f5—¶4ºþ'±4à°w áu¯<ÓÓ¤U{vWGJ{f½Öë Á7#ñ;Bo-åÛ ÇnØNÀ½­ÄµX1œPp-c¼äÞyc°ƒ:õú láêÃÛ( -ñ{½ÈXoOä—ãw4 â?“•X/)ÕšÖ‡ g.”&1V—èôgø¿ÚåVÐ Ýv`1çXÙó:“ë;”Úm›£z' ¦mW)ÓntL!ha¡§Õ«Õª(¾óná·ç+:ñcÛŒOÏOÌ£lºxbàeU©]¡'oAèùíüÉØÒ¨Ï8B*Î}J§+ŒG÷™n÷+ßXÇlzÑfªpNh±ÖÿR’âëÛ#ôÜ'aÞiqK_'r~5\ñø±íEß[¥€Ü›õ4KœÈþ¯’©7F*¤¿œõ§8¶­k™ÉB[Å]7i6w£ZóŒ¦þÐê£#‰Ü=JÍ‹Üá”:€)œª crÀúµ*œ¢ç7^äþN¶6:ûF<)ß-; î#Ú«PÒ“ŽmsöN é%Ž‹Ùú£Ä,Î`nØ€[¤KDìp„ê*1Ì{ó’«gÓIÔG­#Ÿ7˜Œ•jf `ƒ=ãÛüúÉçãVÈ]Âôö+G#I²éUù POo¸"ÐÚÑø`zËdzÊo*“F=}H‚h‹¼â èÃÞUæÃ#ñ G“Iî?„zñA¸²‹p•O–WQ-ýJñÜ}_ûAõ')9þhè7“zr8õ|$±¯Žq=‚0ùé_€ç;@„Ü¿›Tª´›Ú{Õª«CKGŒîUÞ„î]ùüXöô"o9Îv7$:÷@¤9-j)¼’Õ5aóŠo$³%wê~r¼e§dïM乤jÆ5+£Fij™ö£‹Ï8B8±ÌÚ!;”£;¡- :÷+uý!}~NÎà@”ìÝÑÏz:ÏLwø–«÷ú+×ìÓD¸$°¡ÝÈçÛ p=E;“êîQ¨"pÃ`_ÞÓ鄹­;~íþÿ^'ÑZ=!¿ž¥ô®H.ç¯Üç¯b;:}‹ñ¸ï÷ d5ÇcrÆHê=óï@Î#/å@hnH´;?ÊŽ9¬Ì­sãæ³Zåe’Œ!fµÊÕc ¥k•”ÂËÿ¸9ºÑäæºV«Ú¼S†hrYGdcìá pà`£€’²üºË½^Ñ6þ½^þÅ+NÞK=¨CçÕÆg´ªWšÊm9·Ȳëtz†}'8êoR#ÄsMJ¯»¬áîT_„µNŽÓxliW29€Lm$êC>Qå~{¾Íü¢ÎÓI§QÍ9ûÕV†Ñp»:V/-»œëFÑæ7.Wºµåeg9¬– *‹Þ]‘´ˆ÷xî1MÝŸê ÐÓ=¿JC©ÞÊ®Lö䬨:‹µ@ïøª^J–ÈìžžÈ@Kœ1êíDÞ¸ã³~;ãïD“©]i¬y¸|S¹N¼á4¸3ø¾q÷!ȸ[›gz¦ÛŒ Ùâ^ºý#?áÝkCs“?=iüª·úõ è«{PËÚzÊ ‹ÔÑÞï³t)¦^çÔׇf¤A¸i´ç„£ÌºÝ}ßåS” Ým»ü¶k®¸8&¶èº?ÃÈäºuÉöá¸-)Âr×óóð@Î)Öš­qžõƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷®5WÑï\j¯£Þ¸Õ_G½qª¾zãU}õƪú=ëUô{׫è÷ª5ŸPÙ¿e]Å”^ææTÞé4ߘßùn¹ñÎ?ËJ9ý•Vii¹›Bª_{†ù‹¹ÇùiG?ÏÎ?ËJ9ýÅÐÑ{VÔº3‰EÃB+¾Ì=è¶LyÞøC‡m$z“s »;SH4ÛPëMitcÝ)“Q¡ÍÖ@©ÎKÛˆ ÜŠaü3Û —ÏFôy2˜1ºWáë$z”óg\î0ªrÄ[êŸ ŽŸtýíÜãü´£ŸÜ_ʧw¤R|T."Øí@Ë›{ #ÿ×Á3 v@Fù;U>@í=GÙcXѪOn¨ê ëbî I»U7]qsº{¡RštØÝm->¤[ u&dîìÓùf¯ñGh„ m0Ñ´(]oœO¯oÎÄÃtSD5³˜ŸQ3 ÂøÙÞ.õˆN—5ƒa't}íÜãù€¨/ÓxOîqsFe_—Ì AËÄ£ŸÙZ–磾@`pé$ûÿ1w8ø…á¾)!¢J {±˜MuáãæƒÁÃÆŸº毜ábüÑ­Q°Rm0ڹʥ3B³©;ÇÒ³jÏòbð3ˆûb@ÍLåöäÀ•M¼™v´h·1‚i ÝwÚ_‘4i:‚¨Û†øñ(çùãÌ+I®0Y¢`J³YjÕa{[( ޏx\àÜÓ\o9 =R$4§‹¾,—˜b¡esÏ IV‹ V2j51ÓÏ„¸74ªth¶98×NyøÅà`¯Ÿ4­ Ö¯·j¾Ý«Hݨ¿¡ÔùÙx®v7[š¡c©TËD•àÛB«gs°¯£ìÚJºJ™çºñ_JÓ¾ÆZ[žE8ðÌð¤uÀdªÆË™‚4FlÁ5ÓÏ…ÎŒkGSÎWœÞp@ƒˆásƒsZM¡gâÈËκ…•×oºzÕ׳¥ ƒZ$ J 5q9'4ÒÄdžcÜ/×O_ bUç;šÔtƒ@ȉ*Ça©Zž“)U¨¾Îó‡bi×öpnjù„—œ$ªT]S”D”û=Ó°©{yÁiµiáÅ^sqpYð¹Á¹«ýi#0œ¼G‹ÐÁ­6…* sdëN³Yªõl±¾Ž>¢šëÃìƒMg]*Ö7ÒÆì&¾p9ðÞ_Ž^дƒZ‘pnkJÕ3Á!_nÕ¤žh•/– AÄ"àÜJ¾Fcn‰B›œ$œUâܳñIä72¬öVYX Ä»¹Zh6ÐÂöŽPÞ‡ Ü<4süò•õêÀÄ¡ôsbé+r{g¨i¹]5^) hýH™ø{×Ò6m+xÅ<õ©š¾³ÍVKªýeC†ßrnŽ’oiZZ“7•ºÎÚìÒ··Þ´u2•¡ÖÚUÊÀ«=…”Z[ÕïF©‹­Àt&>î"­¶-ï7#‘ZâBÏ{iT¾Ž¨îk,4Ùå]=Þ 3ù7aZ¬N¤dúÖ‡iBÎÓ©q2riN¥Q™o_Xp…d°º ½06¯ùµ?GWü8õûQΦ…çû½É– ç&&ý”«SèòDÑ7‘¡tÄÂÐô•¡Žk•Ê›UŠÂÖ·KW.ôê®"èÀp9ͪ.ÖÞ…ÊmÑÓË€Q¦‰×ÞªY®:‚´GÎTìf©ä‚å[èú”EâØWž0!}gÑ3Œ?=_=Ux2 ©J•£ÉvÕi³9Žºü ŠƒRšžj°Øúúù+íÊà„ë5š®\“¹Z>Ž©G–=c%zʇ2¬¶#YØzѰQpºÇãÓ’«f}]É}nÅyã6­+P½Wä¼VäÜ÷§S«H°Xô‡O[ ´ïžš•{«Ë³ú“¬µ?,..€ÄËåØK ^&ì)ÔÝHò}HTjc ¦ ¦Ä(P¤4e³´û•¶Ã£úÊgœÕòÞxZV«-‘ö§ÉÀ ÈXìã7¸¥™Ü‘!U¤ë5cMÊá¬öÒnµRÛ“pUi‹S`ó†^äû#Ç=‹‹7ÍBÅ90§ÙOQ *•£{³(Ð#YW*mV{+ª>‰Gèç~‚Uk)aúÆÂÐì*Íbug ErŽ;V”» œ®´û*¾HÝ;Z¦è¨ÕJÍR®ÚŸô}f¶p=H´Ó<œ–‘¨Ô%d±T­/Þ¼íO ö CDÝ”ê§ úÜ´GSwávkèÊB­£Hrj&ñ“À׸üZU«èâÃ}¸¡hzJÐd®.ÌáhÜ9¥]«Ð®TÚ…sÅ:ÎѪ‰Ù^VJÉN÷â;ªrv!Z>Žm^UFÍiÖrÃBÐÎe6Äâ$SE¦—RÒN ÅP°Ô¬$6ò}œÓ00Wjô*vGÖ0$¦}öç Gèç~ªØÃÊb£ô}GsѵNÏZÑU‡à^ «æà÷·ûµÅˆü•; j˜Ä•àéæ<ªÙMÑ‘VK «:ñÕ­:ÅB«M:y÷¡,:7jTé›MaIªícFUì2/ÐÄlÖN!hˆæ•~ï<+åØ1X¬m³7MSœrD’d¦8°Þ é (ûy¥I§ƒÖ‘›UµÎÃî!³PR׆ôÓy¡Û}ˆb 8F¨c=:÷äg=~Ø gJpœµüüü3Šcƒiݦ"sà·ÑŠz]c?zú6€cc«½fšë½K‹Ùv)Y›“7§<¿…®,2Ë8ÄSÞ…[¼ÖØ£”`îLmFõ6cÓŠ$“'…µ DjZ]¥§¨œ÷;œx[QÌÀ-3†Qê OSæš§œœY\]¬;u¡``t¹üéï½€ÀQã"´µ<⋉ÌðdKÜö‚¾«Ñ„Yg9ÓÞ…3L†ïOyy“ã铱_WèÂ5\D eBÄë%ž¡¼ Þr{§ápefèêöàãç„ÛsÝ=Iï½ÕÂ×¹™"(¿OØ´_0úÑw&ã[P]ª%q{/š}hÙ,îÈŸôua͇B³ÙÅ——S³b¼I”j_ ¼œûØjáÒÔ8£V¡À»ƒ$öÒ´yQŽÕWèÚ™³”–ÏÅ}Ôrèàkîàq öTÆ‹» GW½«“Iš*ywðÛ¨‹M&±šú2†Î®uwðеEiêmZjžrŸ‘Ç­:Ïf~0GRfŠ’oiF­ü* ö<Í'zÓCh3GO´íàž0•Æ*|€Uï|AUÀBuW»Pqi«Y›iå³wª–Íç1P°¹ï‹°œ@›9£€1 J]ƒÄõ¯©ôaVgàYJÓ`sqç5Yéqzu»»ÄkÜÎiEÌw=€ i·˜À´õ›F¯”g©q;1üGrâv8¦–QòMŽõ¦yçb¾¦ohħ8¸Éà˜ZRì'­µ¼ÆZ„̪ô¨^g?½YìN{¹b3Nán'†ZÚÞ´Û 6™¨ù Iå1„U{p9îw8ðFJû¶­#Ƶ¦«ç'9ÎçðñäçȺ b¾’³Š‘\kï_GÑ)šºÎ€1 LãÎÅ9”*àöGR­a¨ÌYÊ Ëd¹õµ†‚s‹Ìž¸EÇ V°¸r©bÔË%Z‡’Äë+¨6\qÙöEíi‚|{À×ÜØoÅ5¸4œÅáØ]*o_qüFcçZ§~Ã1êLÐäzçÄg4p5×J% ]`û‹—Úd³ñ'Äk®DˆºÁîáînE:£ÝƒŽ×¹œÒ‰.2~êç¹üã÷0ì HS{Å-Ä"K±>(%¸„j=Ù•_/²cHìOæLæå¥|¿µ\_eÑæþdç^-ßù 9£ùi_/²8æªR4ÏÕŒ#¢3»?1g4-+å÷R¥J•*T©R¥J•*T©R¥J•*T©R¥OÜÍËJù~pΔá9kùùø gÚÍ«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§jÓµiÚ´íZv­;V«NÕ§j©P¯µÈÁÇbŸhpÀr”p1÷JŽŠ†<ÑÕ­4hê°¸ònîr`pŽC•þ¬7&ÅçsdÇåá ›Ñð÷#‹cç4ìf5dzÝö§ñtŸ÷OrcíN7ºGûcƒ§çøC§í5·¢}ˆa½mû]düäg$¡€éDlùù˳íP;¡Oüw'cöŒ7\ ŽDuw„ìg§þ{þ×iJ§É ¨ä]èµÚBn <úÖÒ~Ó\ô{O½•®V¹ûL lêŸg¹c­L8‡ä ìûC”#š8¶>zÓ±þ~¾ñƒó¹2ð³ó¿ü¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥JŸ¶¨/½½j©¿ÿ«sêù•iÇM×Y*ÄÓ5*7ñgªrý¦ÓõkX48ëºrëïM%µ/…X aôÇã":Ž%;S¿¯Ú>zÐÆîËî9vä©ùf<™å¼û“$1€doO\û“ƒ!ì“|GFôòtæöw[º›©^%¬Tv‰"g®â §r¹Ë9yô£Žk]íha’hãš8™+T)å^Ö†Œ!fgÿ¾„]§ñšÒã^·‡ˆîK/ züHåÜ9Äû“Má?º-m÷„\oêñš ÐËÇ8 á<˜¿ýž·ôûB¨He8órº…-@vcíMqúž£þ¥4´Û€ù ÉŠc.žî•‹WGÐG_½R»¤gNþ´È4y^{g×îOåitØFí‘óÜ™/´?[Y>¥cÇüÛ¦ÆÌþt·¿Ø&µ¦z{‚ Ò>-­j¬ëÔßSaGQŸ6{KLªsrƒuïéN7Y 8_ê?ä'€ÚîcO¯÷>‡•oZÿã>îFAõªj¹§z³BH¢Óˆ#°™ÖŸ‹jÇžÔóõ•Ks jf@Ûÿ=ŠŽ)Œ˜ÿ•O™Rp?‹›TŽ€œ­/kù¿ÿi¤èél ö㯱8ݧÉÊþ¤a”*Ç›í >ºó†=8ª90~¢çYª8ê˜õ¬­.'Íé)°êV{ùkö*ÒE[ùÝ_¿zˆY©É@[zPÃ$02¹à<¬Ôã{Zœ‘Ç5ž|•ŸBèÉF³3ûž bÀ@Gf ¯Æ÷yÆPÀÈYZåN7µ¨?–÷8äTá 0…ª°v,»ûT-ÔT¨wR<¬ÿtë_¹ÈToÜåÿôoR9ì' Ç³½;ÖßžŸÝ÷a¹;Ž©ï÷/ðŽșأâŽ>¨ï÷©Æ~v .ˆ»Çq[z£¿ÞŽ8|ç(ã럟_óR•9³Twä-{_—´Ri‚P!ÂG ázî¿´$4I@È‘ã9Á¢J8HNph’šàá#®8öÔæ”]541÷Q«°Çˆú§Î+?°«5 £ð÷¦ºóC“׉oò>Î?±¼uýþ¥aO÷C •!£sˆ*®¸ÂåI·¡Í-ØSˆh’©Ô!4òÅM§Å©PSªoø•£mäÒ$*üØÚ¬üÈÙÂpÅS¨*6ðà­Öí+•DÑ!C«8^§È¨ævªæí2UMælVƒÉº5§Óu3z’};–{¨]­uߥM•¤mÛú•:¦Öh}ÏÆè%1“gª“¯S„}eWÁQä8Òõpiç˜ÙTê_O¬b3ˆàqº%PoÕã­^:šæ*°2?`L *ATHþCPýž6‡}ùî iqT©òI~e^›4v*”ïw0´u_äG<*<+G6îÔN‰îéœÛ”ÑÃV¡l5¹•IúFʧõ5bo"±nÞ ¯sa­Ìªu/ŒsU±sÒ¬ø4·b«‹Ø ÇJ½Uä–D'ìŒ*îú¬5ª\šŽjuh©wRv5š6pÖä–ÔVŽhJW=!sëOÅæ…R)6îehb‘b¤ëì…øÕh\_žJ©LºÜ©OGG ó@È”êæy9 üKAä]Ð!PäÞ§³®­S”Ø…I—Švšv«A7C´h€‡&¹B¥ÊsÝØ¨rK©ìUk\p Ðb™@@„(ýeýJÐ9†¥"%YâóaS~‘¡Ê¥BØks)έL^tBÍ>«ï]¦2U*i)€Ýiœš®juh©wWëCÿ èù:c¡ßhÆÞpjµ°2¯'/¸ÕåÔm>ÞúÍLø‡“ZN°ËªÐ5*”›R%UmæƒÍhcOZÐ<¦R 3™Nv„½»rTÛq¡ª³ €ss APJçWê ÜŠÁÛS±®ÔÞMg ©Ø×o@Sr£ÏB .Óã‚d’ÚGQG 㤠Ý%7ª‰Ò<¿£†³oS!_Ѫ¦ãÚò¨4†IÌð¶‹XëÜ y.!Syc´o(rMƹ; …àB ¦)·œH ERuæ¯7oNUV··üŠûpUž.ÜÓu¡¼ð,wJ~5š6pVä9µœE1(òkƒµ¤ÒçiO§…Âð!_þ͹4] ñEÏ­Qaç¿2œ/Mª[Nàçd©ÓѶ¢ÐûéØWiÚ©½ý=Êð‹Ê  çë8ª•"àƒÊ¦ý#o (ÿt:Ù5¥æëSšXâÒ¬Âk3­Z±k×ß÷\ªwÑ7¼G1¯çÚmg4pµ¡¼ÞÐLž,v•ª*õMªÑ̽±7Äô*Ì8=¹…Hé^­ 7„kÁeÁtMíjÑÉãR¤ÛŒ A¡¹x”ZCîŸÃíNhvÇsþpO¥£åÒ…C•/Ûâ5¦@àÞ@|„lôâ!6¸g&®j—-æ àsC„(Ói8m>Nv&r«8ìà-x+Œö*'Z¢Ó~éü>ß´é4z¦x L‘Ãq ÞŒxm5*tâ•›z«E-™§6[u}´›ó‡.KÞÎßä/+@t}•›“z¦À­¢+¹Xñ®ÕW;Iû›™{oÜœÛÀµPcš v“=·šZ¨4µ²ìÏÝ©R-¨IËWVŽÏä|½ü)ÙýˆäÙIÚU³ž@V._rÎÉÿ—³îMÚdªBëýÒw—_¾5(šmkŽ¿·ÿäRê §<ýnMž›zÕ¯ðá Åå' ¦þÊZ|œmýÓ–goîæ‰Ú=&¥d¢+?—’" xù«uÑx»³ìí£êãaÃíßûU>ÅWÊ;­Y(Š”ª©6ýFµZØTÝËÆµá£oð…iæS= É›ÿ¤ª_³Tìûçû§Wʳ·÷N7UuÖª´'AàkKŒ7Æf4›Ch*‰ÑѽµÃr´‹µœ:xXÛî ÕVhÞYÃDMVŽ•o7šÓÒîÿ²h’µÍ©ýC»íêþÚÞÅ_Ê¿¬«ÇK½ŠÆ?´4+O)´ßÑã[|´l…_ÉR= Ë•Cü%Pò5GWïn{?=c ÜÔúTƒ\Æâá¯ì­l˜n§ìIÏkœ5pù?Kû•^Už›ºÇ’]S`V†Ü¬à¬Âk5Z„T¼5ãÃYú*”ˆÔµTa†ÒÈ{U·Ë“ÃdòÁZ¹ÍvÐ8l¢kµV7¨Oñ0ÔphÖ¸¨<ׂ|z"j´t§âÚý~Þ´_DÃÇÙŒUsý·´+O–Z n²—Z³´;¢ULlÌ;'Å`—­fk¹Výž—oz³ù:§¡Y¹µGï|Ù×ù«ãÔï|Êvçb8w­¿=<©h]<^C_[`ïV\^[´±¢ÛÕ:UC¤mnƒðû $ üF7" dzŠ~hC•e#aॅž¡êVÏ+{h ˛ݰ_•F›û8m¾Z:¸-œæ pÙ3yØÒ­Ó¦îŽ—jÎÊ«ÙÁdò…ÛT_£¨×+C4u\ßÊ&»S á[ç_•·«4&='°æ1ß³ÜÇ´8*çûQëV¿.ä ÖÙúý©‚+VêrÎÉÔïg‰R“©@z³‰¬Þµ\ÍW•Söfu•CÈUìïVf–¹àù§ìÝ€„|üõ#‡ª{ýËç|#‡î¥ÃÖ?5iºe7b8£ª;ýêqŸˆ ¢wÖÙÖÞîr,­q•b1]¨0¹÷kŠmñ)Í,7]ÂúO§Ï€“Zé´49š°V!5³›Â¨èñlìkÝ/È*ô´O»Á::tOLïV¦Ý¬à¬¬¿Y¡Vɨ¨cF«x2²u»Ø­XŠnèV|)UwBçYzD°ÍwpZqe3ПIôâøÏ‚Ï…:§¡TÆÍO·‚ÏgÓI&µXÄU=«—lï\Qɨz;ÖJÕÊ ©´w&1ÏæÅûCU—'ôž s¶¬f+Ž”átÇ;j2I‚rD˜* ÃR“3LS`ûø,¬ª'%IÜo<ÁžÅQÓXž•lòîUMÑG©<]}sЩcg¨:‚­AÔ)Y™¤ªÖ«C´Ô…N’¬Bkµ&S¿eoZ³yö*UŒþÌâŽ+oTwûÑÇœå}sóëýÔ´d:ÿ;±âóHþ%aZ„Ô‡á „²»gj¢Ø´T;%A‚…ªð«ow«E1MüœŽ*ÊËõš £\Ô¨YS¹Q¥è í+*ŽÕeÀ=ݬ`Š×°|M Å=,`©rlõÔþ¶Î×ënœM½ Ù‹Ãö€¬¼–¾¦ÁÞ‹¢¤jÉYZCßOh<0³0m•[=3Ö™…™ý$*Ó{6ðPU£¥Z.i]µNbié&DªîÓRÒlqM¤÷´¸ ¥…ž¡êYÙzìFm¤Ê5-e›ŠknZ*õwªn½B ùÏ‚»F¡UsÚœ&Ê'QïV>C úB®ÍG52È÷\bv¢ L ”'`*ÇåÚ )UwB³]ýŠÔ.ÖwÇÕ±šãâ«}}1\g‘T¢˜eøóö".˜*ÌÛÕDªuCë8h‹¦ §õTSÎÀ{U:ޤëÌ<ïÚó©Z³`þ­ß;úU“”]OhV6Í`N¬U7ŠÍ4ªÖ ³5Ä>IÁ3•fxØB±à÷;`<üOü½Š–gŸb˜ýã´ó?;k²¨3ÒþÙ³ö§:õú›SL€í‰âá¬ï©ü¦‡"× aWåR¤þˆõ+(†ÔDzÕí4(Šú_áŸb£SDé9*ï5¢³Tå‹Ú•¡š:®je*•9¡6ÅXœDúÏ4ÆPɳ5»J§è¶¢ ÁV¾xnÀO¬³µþn œŠ Lú‘2eYëPJ" +Fé7¡_eÃQDŘ ¥MƵT³éyt»B³0¶»C‚®o<ðqMŽn³—j£Ê£QªÕ6›N¼Oj{tT\ÏâVX!ÍwAõ#RýC:Ñú°­8òMN€¬ç’ñÐ…'–ß YûSEöŽ„×i)ÔG‘fl&°=úgó@U*º£ïœÕ©·ê·ñ*´*Q‹áYFGz²¶ífe8A„96SÒS9!¡[ÖÎЂ´ºí\5*gDâO4§ºýM(*ÖØ¬H׊£õTM©®ºëÉÂÏ\Þ& ´—<åÉ '. f5g +g•­?³ÞÛuSy¦ðñ©9­c_RŸâËÚ¼ˆéUuØ+?6£°¨6í;n ÐàcRf6Wu…ͳŸÞKO“üí®¸e_k™}¹Ä'òZU,ãj¯P8f~Øš÷3$*8UGö|5ð‡ÔÙºN>î •Æ†æ¿bc'’{¯:P7L„J¸ ÉU´Þä‚@è\’fò¿Ë¾ªWi‹º“T¥N»¥®ƒ®U ¶ùq*…ZbZFW¨2oWg# §<«ERPTê]:F˜ÚPVÁØ*†N’Z5*VšÇpDÉž/Ý…H²›ú ½[ܦíÁT®×´`Wp龫F¬æŠãdTG$jV‹ SÉJ²bKv«F˜ÔÒ^ˉ¬‘'JµJU¿bæÜ©‘ïOsJí%N¡¦ëÁ:˜®ëÌ1*·.)3šÔ\ ÄjUiT´– Ô™g^Uà J±¼óÁLÂÓ3ÉÕl´¼krác®”H§ÌUG*UJf±a¯T †gµôÉÉ]§ç#PäÜ- 9Ú•:¿Œêî)õ¯6ô@ÈHÕS©Hg‡zµÃ@¦5~òZ¼‘üø2ªà0×ÂDz.ÔȹZ*é<·Ú ÔžûÇìt½ Î.2|Fs‚¨ß­…[Ê®ºœù0ámBÖÂ>L'y6øÀÁ”Xo •GI—:B´TÒC0œòüÖÝ„|˜GÉŽçʪ“|´#R,øIlé &LŸ¢øêEä™ñØë§÷^Ë.¼œC §ºñýä´ù"†_¸/æ4ªŸ„}Äfž>¼*œóö?Ýv§ó[öT¹ê¦¡âuÚŸÌoŠìk'gûõhòNMæÜä­ιõÍê÷§bãö-ònU?WÙ4Á”÷^tøònU?èñ¼£÷î¿“r§Ì¸,űҪyû“Dú>{þÉœ×WöìÉÁUçG‹ÓÑùÝ& ÕµŒik©Œ=Æ?&¢Í-F³j¶1­xs2?v´PkhòF-‰íà­äÜ©sûƒHÄÏÜÚöèc_Ï»„rñ z`ÄðÒÌ…[ž~Þ–pª¼_Äø¿ÝOÝêºã MeFDû‰¤ðÍ$aÁ£}Í$aâR¡R¹ŠbUk5Z¤ÃR“é`ñ-¤÷´½£ÃA¢…>0üÿ½Zþ±¬¯´o Ã…CSͧr¬m; VV7•Z¦MïV‡º½ÖvrB°´hÌþ3‘LIášHÁXNŽõc«ÚU¦žŠ³˜ªR}(%© QÑÁóßöèT­:10¬”Ãë Ù Ob¶åµ|áâ:F4=ÃÁNÅ^«oµ¸/Z¼ÝáS²›7ÖÚyV’kÒmsžGÙÀÆ:£ƒš{M×\1á°ykÛ$ªœ»#°‘íà§MÕ]q™ðXÄUóFýJØØ¬H×­Z™<ÈÞ®ÈÆùÄ”ÎU‘ãah¨Q=$«knÚ€.0Hv’Î?îC“c'k‘¦+פó‘{¥Úz"·IÞ4•Ú¦úqõB®N0©MÔqùðÕ²>›þGhý@ «\R ¥@å¯iU+ѸçÓç?V;µW•e¦vHá¦Í#Ã6§WnôªsQ­:ÌæÖЕlxubCW ]ž£6cÁfäS©W¢=hl¥»Ç “UGz¥Ê²ÔnÈ<NCjUØ;Õµ¡µÉ}i¼‹>qîU[¥Ð¢=E=ÚSh8x†¹–S‘nòˆº`ª•em&³<ýjÕI¤ ô¹§qLa¨àÁ­>Ò)Ú ?JÑG@øÕ©:ÈöRÒŸRg&Æã´€šêÒ®|Þåeªn^NÀö«=NÖýJ…k¶PíVšz*Îb©Ì*—“oWçAúuù-+Î-n €½úBfßa LÊ:Z˜Dê"ï#0©¿HÙUu˜&°5·U têZW?ÉÚ@2é@VêÒºžúóŽ ›ïH9„ê°n´IQYù˜O¦i‹í2Bi¼$p^nÔ~½ñøBu6¸]!ú8œBê¥3ë*—lÁ;’×RùÅTd·“©]ªüI…¦, Tþ±æ§«À8ATŸ ºíI¯kù¥9Á¢Jh5÷ä Ó0´îÝ„Êm`€¡ÞCæNC›S³‚¯-Ÿ­@ˆTâ=‰óQ÷ˆB«›ƒ›ŠÛ0ìöm@ƒ’£‰sºUFi+Õ†ehocPÊѶéhT]z˜)Ïks*ãœÝ.´çéaÖŸHSÛ˜AÀ‹È“_ÍQ„*gDM3–¤ê}hÏRdÔ}÷Mx¢\¯V8ÝT™pc™U>­â§­>¨aŒÊºú§– 'Ó3}™­%F¬*•}[âàJu0YqQqs`æ:·WÜlÍ¿Yƒ¥UªxÁ¨6«M!R£jSÉýèT߲ܨQs´™74ÚvzòÚS{‚ÑÉ¡IgÖ¬'ënyÀ„ŨÓÚLú“¢¶¼ì“Ãg®)K%§5^®š¡z­ý¢ˆ¬3z³  ¥Ýk5gªÚw›PKJ¯XÖvÀ2 Ë‹*3hîVã1ø@ Ë*¬èŸRµàÚMþõ¦³ÔL Œ0M«d¦ëìi¬u?´‚í~Õi:4éu÷¦Z®ÐÑÆ>ڥʲT<6_«§R¶ÁµaÆ¡nÐPäY ór?Ú,×9Ü™¤¨ÖmN´\µ>ö-8Å"ÒÚcžåi©¥ªçðŽUŒŽTì}1,â p5+`ШÐ-!Ù¶%xÉT­­Ĺ¹Âà+]9;æÝ%¥?êìqŸR¦÷Rp{sN©d¨o9¤…h¤)?“‘Ä*|›#ÎÒµXÞÐòÇäá ­'QuǦòln;J¯5iÒpÎ#Ô­„2åø{ʲCÙLŸÂOt«¿Qã΀ÙGÒ~,ûi*5›Uª©6—‘ïU+Õ°0^3TöÀøª¶'ZΞÈ09…x&Ùæoõà›g™¼{ׂmžfñï^ ¶y›Ç½x&Ùæoõà›g™¼{ׂmžfñï^ ¶y›Ç½x&ÙæoôÖ£jTò‡.Ž•RúD öqÊüC§ojðM³ÌÞ=êÜíŽÎßÀ7ëO³ÕµÕm®ˆbzõªx1¿›QÇÕþõ8ÏÎÄч5ªWJËÇ8gã3YxÇ ÖYøÚájŸ¡d²ÏÅË£ì5ÂèñµÇ‹ÑÁ®<^…žK\}©Ç½mêŽÿz8á󜣮~}~7GÑãg‚ÏÆÍgö£¼n…ŸŸ~.k<|]SÁÒ³áÍNÁª|]SÁª>§Î©ù6OGqG™;_L{=¸øŒç Læ±~NÛ¯!“;}ˆåد¤ÏÏf!æ¸täsoo±rv}¾!Ä··Ø³2›åz/{PUG³.Óˆr~ÂŽqÖ¯¦=žÜS³íñ4öw„yÑÓ½ ›ÛÙ”-ƒgˆy¨ó¡ÁÛìY`ÅÑÐV¿¹œ‡_°¬/˜wdŸý¾ Xùùøø‡!×ì+ ݱ'°­~!Ô†Ãiï(MѳÛîYº|C›O_±q®ïC`ÙíZωÍ%ÃiZ duw„EáHî>ØG”ZzýŸæãÕÜ“;LúÊÏjÖ|C‰žiS¯§Øµá´ü>zPñ5’TœÔ 3”žôÙŒ|Ni.LzÓ@ˆÕ ‹¤Ês©[¨²¥jGš~u…­4cÛíCšOÎhg‚$HBI„ ª¹º2k£}ÞÞžœ°OògÔ>zŸPG^éq÷'òoÇáŽæ“߇«¥:ŽËÅ¿êÇü©³¯V¬8>†¡M´_ÄWÓt)†¶°ÎQÕÛìG'|êGšQÂ;}ˆeÁ{ Ên±ÎÖÏ«4Eב;Èö*š¶û>wõ&´9ôÙçºï½R:@לމöe½I¹xy·½S†ìÿwjYÙPÉL`¦!¼µÊo'$9&B ‘Ç=³Û¼£ŒöïÏ×ÂÚÎh„Iq’Ž(ãÀ02š âµÊˆP£€ „~¬[wƒ¥„(Y(P£óÒ'…’˜2²Q„pk•’8ðžP‚µ]ùÚ§çrnÙßšq&ìj•#¢;1÷£‰ž 5ŸAר«Û«ZuÙpä£Ꭰ%×”@bÌGÏÎ)ü·rÃpÐŽ>¹íÇÞxl¶úÖ<)ä­6º¶·^©Á·ÄŽòrQŸJw,ÉTÜQwáøOr¦ Cg1óòTaÙ¿ÿä ÐçÂ%C³9)ä‡mYÁÛŠo)·†Hr¦5&òÑšd9×Ué§{¤þG91hpÈ C„ç#ü…Qü>ЪâÚcør˜¨#(íø&ÏÕtþ¤á.«²÷É 0øÇžþ¸Ô-Õ9€J¦è¨ÀunLäRºFNòÕég•{|íTù6–ÎÆ|U!ÈmýDõŒU9ŒÆÖ>±ƒQ‰è’@îõ¦KÛ={”ˆ½ªì+)œ"7äÄŸ½ç; >w®PíN»îõ $ÀÚG«4×_NC^u´{³ìDApØàÞÒ™èDÃg¦Ž’aYÄú“\/µ«õw¿‡R©Éuܱ¹? ÿÂ@õžôÀj?G®a7•v5©{TJÕëÜœn‰èžÄîK‹N£ qÄë$zÓ sAÖg¢šC„³Âé;$ú„¬@ëËw½]åíɦôt‰õf• ¿>Ô ´¯Ø‰×ÖÈ&uAì* ä뼬Jo(ˆ×;•2*v‚}QïL%ÍiÖu&á#í©¶û ¦:i‡»`(òfuFüÖ5jXõfœè¹ˆ|üíEÍC¡÷º#y>ÔÎ@dïöô ÈafÖ†úµ§Ä·Ê€‰;z 7n„ 8¸kXÈ÷*@SÉü? J˜!£·½Tå‡ÇâÏw¹8ˉÚC»BhºÂͦwŸzŒÿªP0o Á$v™Lä€Y•M·³í_Ë5çóªSùR¸ÜªrïÿÔ¨‘ÆÎѺ±Q$5‡^²ZæízÓ±ƒ¬UGD'òïÿƒ½J÷(»kƒ½FPÐ6Nó)¢ëC~ÏQA±`X|Ùö{ÁÀì$ú¦Ûc|ÐG®=ÈŒIÖcw½^ºXFbÚ€†¬{qïWyR6êOåßþ ©^åÞéiÿÔB§È  >´Áp·`zá kv`š.´7í˜ë޼ƒ"žø.÷ã½Uå5Îþê9¢I’uÆá€ÚO­7'6ûÀ]õOža>µ:fà´Q/ô¦=µ°Ï¨ÒÒñË?á#÷—!(à$­R³û®BV©Z¯jû±ä怜 ‰ £Å«ô¾Ž£™s.Ÿ‚ð×éïø/ ~žÿ‚ð×éïø/ ~žÿ‚ð×éïø/ ~žÿ‚ð×éïø/ ~žÿ‚ð×éïø/ ~žÿ‚ð×éïø/ ~žÿ‚ð×éïø/ ~žÿ‚ð×éïø/ ~žÿ‚ð×éïø/ ~žÿ‚ð×éïø/ ~žÿ‚ð×éïø*OÒSköþdïÚ]0MÑÖeR&£éº”7êÆxë=JÕû1ŸáÿPà®÷1°ÎqÀ{û*µ6²Êæ· ­1Ø ªMÚ@ÈÿK‘.NöÀì»9õàœ÷0T wã<…ѯ¯ݨ •x £Œ°“·WZf-©LÌõέG5chm‘¬ ¼¯Æ™ìÿPW®CõêùÙµ0hÍ&ŒÇϱYÆ£Ò¨òôSø³ÿ/½S—±£¯·¦S æ‚>äüižÏõÕ`aí?'±R}Ö¶¦½_;Ãz=Š/E?‹?òûÕ9{:ûze0Þh#îOÔÎÓì÷ú•*ÒŸÉ3¨'gYÛ#ý¿;²Nä‚GšãêÈüìWo<3hö‘ìTÍæx-^^§Yïûµ—ÈSêß™>›*`ñ)ôiTç´)°6àp@&Sé²§þ}à_ÔÝñ^ýMßà_ÔÝñ^ýMßà_ÔÝñ^ýMßà_ÔÝñ^ýMßà_ÔÝñ^ýMßà_ÔÝñ^ýMßà_ÔÝñ^ýMßà_ÔÝñ^ýMßà_ÔÝñ^ýMßà_ÔÝñ^ýMßà_ÔÝñT™£¦Ölÿ*•éÒÁå:ÑM¤ ÌNœ;­4Ø>£îLx¨${¸)Ô[y¹&T&5=IÄ J¥PU¦ÚÈâœàÆ—»!ûÑÒµ^Ô³û®BVKP(Ëî§ Ô g%ÑâÕú_GQ̹—OÁxkô÷ü†¿OÁxkô÷ü†¿OÁxkô÷ü†¿OÁxkô÷ü’ׯ™~!^W•åy^W•åy^W•åy^üÍîÐ×sœb@‚rÀ™ïB§.›ží lÚv«Cƒ¬²Ó<Üò‡¢›svšÏβ¤1š&»™VX{W÷Fï7H}XçÑ1íVgS¢Òâñvz‡f=©¯½a¦r»{«§Ú´aÖzá„!„Ƭú2ÖžiqgñhÕ—dåЬ­h{‹Ã!¼ã·³÷šè{ØÓ‡üª/›Ž9êVq«­Qåè§ñgþ_z§/cG_oL¦Í}ÉøÓ=Ÿê í÷µ§ =§Ç©¬å×ðÍRh•G—¢ŸÅŸù}ꜽ}½2˜o4÷'åTôúù_1ØÍƒ¨ûùW®ïøNγ¶Gû~wdÉ5ÇÕ‘ùØ®ÞxfÑí#Ø©›ÌðZ¼½N³ßöDy×îþXœDªÃ$0ˆÔ EÝ_sèGƒ$0ˆÔ EÝ_s8æ¶ô ÉAùÖ±Fk¥e€à«ôF’£Ÿ>Šð/ênø¯þ¦ïŠð/ênø¯þ¦ïŠð/ênø¯þ¦ïŠð/ênø«%“вäʺ®«ªêº®«ªêº®«ªê»þu+Ó¥ƒÊu¢›H˜œ8v'Zi°:}GܘñPH÷pS¨*¶órákÜæ^à}©Î i{²½J€F´"GÝO$^(òEâ¡‘÷SÉÍt®…¬¾-o¥kÓªæ0?:׆+ìýëÃö þõáŠûÿzðÅ}ƒ½xb¾Á¿Þ¼1_`ßïVSí4ËßµJ•*T©R¥J•*T©üÍîÐ×sœb@‚rÀ™ïB§.›ží lÚv«Cƒ¬²Ó<Üò‡¢›svšÏβk´HäÐÚS‹\$å¥?îù=ܺcÉßQwºÿb–U»Í/\ÖãÕ»±4P´Óçý" uåÓ’y¥ÅŸÅ£V]“—B²µ¡î,p# „óŽÞÏÞa˜çþ>rTù”ÏGgoR¡Î'míò¨rןO7ÞU¬;sA¡ÕND{\©cIàµyzg¿Çú#È¿wî;é‡ÝFwíþNœZ[·þ|ZŸEP¨òòN?;èm;½ËÀô6ÞåàzNïrð= §w¹x†Ó»Ü¼CiÝîV{+,͸Š(P¡B… (P£üêW uÀ 9à¤H it‰ìí…RÑ¢m÷0îêÚ˜âá$G+µÔô®À|Ç­ivüà´Œ»~pÚ…F9·Á ¬t–»$úíVr£ß µS˜e “P°jïÙêïAÁÙ&Ö¦þkWÚcòB£ë â…Zd†‡bUöݽ8~ðB#îÇ’/>èy9£ÉÍJkƒ€pZÈùÛâÖúV½:®`ó­xb¾Á¿Þ¼1_`ßï^¯°o÷«¶¥ªõð0R¥J•*T©R¥J•*T©Sù@iÖsñ‡ˆO½C¯1Õæn §9>j­Ë³Cü;gœ;x-¼ CñgկחoB´u¹àucIͨêM$déÀcãÑi –Î.ÆF9ft [J,q¡]„HíæüôkV–M(`ÈŒ:Uâ­·œjÏ«4~ª³êþö™vÊ3MìõõªÒQªÊm‚o³··jT´6ëcz5…Jó´ ‹ öåe¤FŒ:ô· @Ãlcë*ÊËqˆ7ÞcrkŸCøZozò†÷¨~ðdæþÍ8ûÕŸßÿ=ª‡(Ñyôó}åSÆ“g§«µ0ËAû›¼›»?ÖÔÜÕÓóëVl‚¡Ê4g^}<ßyTñ¤ÙéêíL2Ð~âøáÛ^Ï_¬ï©…ùÎpéÇ|ª>X7a Ïä™ÔæjíåË·zq€K|×O«ÜÐhu@Ó‘×*FXÒx-^^§Yïñ>†þó³Ûû¥q·¯ëñM¬›ºÿ’'–íÿŸ§ÑT*<¼“ÎÅàzNïrð= §w¹x†Ó»Ü¬Ö*vY¸N*(P¡B… (P¡B… ?ÀN¥pÇ\“žÚD€Æ—HžÎØU-&ßsî­©Ž.Dp2»]OJì³W­_iÓ‚i¸HpB­7æ¸@B£Ûàà›QÓ1ûÎy-¼€’L7ÄŽ Wµ}Òf›Ê »¯$ÓxHàÕ{WÜÝ„ô-RV²â-Ùó펾c>ÿHZYYík°ê Âv¿?p÷*sé5ÎÌ€¥J•*T©R¥J•*T©R¥JŸÌêN³ŸŒ8 @˜‚}êyޝ3pe9ÉóUn]šáÛ<áÛÁhàR‹>­~¼»z©†i¹¹rêà ~Ju) D.ÿPŸzµ2ýÀ5·ýAZY4ÅÑ‘³çÅU®¨Êîh<¡‡«?ˆ44@ýçw“pêï Ø7 x{ýݪœ¨`hN©ÿoÇz§ƒ{Ÿ˜L›¢~æe£“™Ýñ@6ZíQ¢uvª'Ç\Ÿ\ªªÛñÞ©àÆÞÂ'æ&蟹Tüsœáë÷fŽE£oÌ/Äâ2ø'ÿ{ÒûB~ Çšï€ùÚ„iý>×|.cg‚Õåêužþ 7gPþtæñ]ô}™î.sq=%x2Éæo>ôÖ5 nAB… (P¡B… (P¡B…à'R³ƒôtÛ&'8ùÉï. c3‰½V­V“/ݵí1±0¸ŽX‚‰IT^ꌾáÝ«·÷´ L7Ú85^Õ÷XÈmMåpj½«înäÏFÎü©C25¯Ä[³çÛ|Æ|2¥J•*T©R¥J•*T©R¥J•*3©Mͨ^‡‘ƒ„õ-ÁaªËðÐ5g'jªÂû=ƶ2éÃÙÁ]Ž«õú¶v÷OïsyÌ]ÿ>Õeäµ³³Ø¨`hN©ÿoÇz§ƒ{Ÿ˜L›¢~èq-'(çßÞ¨aŸOÁPÀÐSþߎõO6ö?0™7DýÊ®7§9Ã×îÛŒô¬§£çÔ†²sOþ÷¤ö„üA5ßóµÒ7ú}®ø*\ÆÏó·0G‹ (P¡B… (P¡B… (P£üomÆÙÞÊq%Äoþx[šç¶Ñ<¶ÿ<c¼âí+½ý$•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*ÃWÿÄO !1AQ "2aq‘¡±0BPRÁÑáð#3@`bcp4rC‚¢²ñ$’%DSÂÒsT€³ÿÚ?þq­Ín|»Êl5x§ê^'ú•Z&—ó8ÍJ{§ '5d㧸¶ÖšëÒ5…kâ = ÅØåñÉ Ý:£Þš‹gX÷ÀLã?F ÷h)¸Œ1+ N¤A:‘Ç$ýu¯€íQŠŒ~µ£† Rh¼PÆï/ÂSEæ·•7yQ1‰O­;Bx‡6£(Ö£ò˜GÑy4^ŽTÇ*Œ'Mà)µÄgÿÚšZn•6ÐTlÇ èGˆƒ=y&¶\æB~¹=鸵‘²TbÖ'¡F"1‘=Y¢#ø¸yƒ¼¦0Ô0«P²Ý'5dãª&én¤Æ‘$æU¯ˆ4ôz0¯I.Öcß+3¬Ghø+ø‚ygœˆCD ¢é.å2§>p@Ã.ý@˽NÈ;Êa$âœA$„PÂ÷,vOÅ6ÙÕð!4ÅÉô}ɘzºp=ݨñKB©öÇYNtºðö‰ë§õªÀš{¾ n™ja»Z“x´ÉÕñC œ“Û?8±Êµh"i±»?ûJq½UÏÛØƒ±?ÚRn `Ø#µ]Ð1÷ÆX¢ìùCzÀ„!¯1‘™Àk[ú@=P†A¤uPÉ£dö’SŒõ?ÅÃβÒ 5xçéDÉ5M曤/ý+Ç?J«XÕÃAÏù¨ç¾9ÿ2IRT•%IRT©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©ÿÚúÉdu©Ä/#þçgÍy÷;>kÈÿ¹Ùó^GýÎÏšò?îv|בÿs³æ¼ûŸ5äÜìù¯#þçgÍy÷;>kÈÿ¹Ùó^GýÎÏšò?îv|בÿs³æ«RušnÕø|7½§Pžß3O‡]”ŽE3죷|ÎMÏž¯äÿ‰Ñïóþþ©ÝÞvˆ/5AËv\ê»®Ð}ÝŠ¸Â6åCîÙøª2kTku´w”xÚç#Ë™Lh2Hµ8‡Ñ[„ÏXMmê4Þí|§¹5âøeL޽‰¡Þ2Ú|Ž÷w'»q™ŒmN`=¹}s¦ѯ6÷o[Cte0Þ3‹»¨¶ýás*¶[µ*f}ÜèÙÝ-»ŒìN³–±Ï5>Ìæ:á"S¨]¯U(6JŒÀ=Ç_bWº1ukM³—4<¸P³»…xÄaŽÔöÜqiL¦^ ÝJ3S/ÍZ*Tk²¦ŒGýj¸¦æŒŒõN¹ÛîL¦^ ÝI”ÍL´³8r{ÆqÓ×—Zƒª=ÿ :e7ï9|ŠôÚ6ü Ô#lt &#hhc–Ð:Ñøñž*ÐÆÓk¸j;}ÊÑg sî®Dë;š8ŒcZ6w¶ùö~°Oa¦ë§5â÷P¸âQ‘óF ™gõðU,à>ëªW‹ºs<‰í¸bgGÿÄè÷é¥Vî€ÀÕïTBâ_°{ùJ¦Ô¬,âÐ_9a‚}¡¬$A1œjU+<Öc–z¹;;v!ii“ Ç™2¸s®G:¥\Up€`ëV{\Óa¨:õNŸÿTîŽíæ ‚Á`°ÞYÿÇè÷+OÜ¿˜ªüaÌ;•Ÿú‡ÿoÅYþþ ý??¦<®>õDÃjS:¸CßñTÁeƒ›¸GÝÔ€‰AÐT¿¥o!w¹j"ÙH¬•Ÿú‡iî*€–ÕçÚ-þœ³P ÑÇèopV¾©ý¿GúŸò¿¹1 “V¨`Âdô @Þ²4ò»Ü‡ôô·Þªãu£2G|§™ð„×îU~íÜÉÿwO›ÞU=oíoû·´k1›”œ‹§¥ ÁìÖH÷£^žîê€àá³/ŽHW {7±Ô#<:ÖäÚt+Aœ¹5§Ô¤ëUó‹~_Z«M —¤ÎÈÔªT¦jUx<`{ÆU¤j¶ÐNQ‡(UEÖ'½Í5j9¯‰:Ä‚«–:¡4ò@–™ ¥gT—æ‹9ŠÌ'hMePË·]‘Ôuôûº ´^ºâàD‘Ÿ1ÚOz´ÈU+: Œ´·´Gh>åOÔgõЉè¨v©°Çd÷Êv»gÀ„0{]³àBoY슛¸·9iÿ·è¦ÃîiêõÀ£R“XñNx]_4úÍuJ®ö¾ §WasªúG«Óm,à =.\#»µ:¡uM×\ÊuZQRìË»1T´±Ì{[8êÔ1BÒÖ¾ðœD̺‘® Á¼ì³úî•]í¨énÿ‰ÑïÒÝÒˆ¸#WÑTÚàKß™C4ËçEkxmíÚŸEí{ÈÎ8::Ó)Td c¹nuôŽ“þé •'nŤF×J¡N£*6tkÇÿQx³2œb.ö§Â?Õ;£»ÎÒàn“é|‘ˆ)¥×C©S"›ÉGj`º÷?G82¸ül9“ 5¢WoÖcF¹cîU]}䌴¶XMÜŽaɼìcRkŒ6³µ*\ ¥çdw¡-uöfˆkøÊÑ5˜Z6Bªð÷HØ;•.G<ëÞ¸Mx¨Üþ(Ý1˜P×ñ»wØ\<©²Ú4£"ßyÅ2íÐgÜ™Á¬*lµ<^i Ζ°lò©ðPŸHÔg̺£ßÆtÿxüNŸðõNèîü"i ’3ü!OŒöD~Á`°X,0X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X,4Y-fÊâbA^Xý¿%åÑÛò^Xý¿%åÑÛò^Xý¿%åÑÛò^Xý¿%åÑÛò^Xý¿%åÑÛò^Xý¿%åÑÛò^Xý¿%åÑÛòUªšÏ5¯|”LŸýà¯Èƒ <ØÇñ™yáŠÏG"äüî<øáLjC¹{ wú½ùŸ85sëPúÖµô…·ëj85ß[S¸Ð³Ž•œ,×Á ú>d9ÇOzØQC1ÍîÐ=ÑY•´§½õµ¨àJ8O:85Éø^#jw8§#““ózwÌ5t÷¡Œt­Hz(-h¡˜GˆŸés£¯¡ œ \ǽ7Ñçüê4^<#² v9^»ÝñLáDþ©èøÈLwÙ‡; Æž¹ø'Í6ºx×orjø§ðæk½¦G4ûW{±íTø@®z3øt"NçËr÷wÅ<ûyG €á{?óDw7µSôµÿÿ§«ÉK Ë£—~0ßòèåÞry¬·¹®_ΣD ”qÏlôáðaz5æ‡@Ø@É@¸Y©‹Îf; …®yg§è&ðrú•ÑчÁjf’'Ž9ÿ0ÿ¥ð£ù¿éGó|«ØÌyŠti=¥×òáóF‘'ìÁ#™no»~0B•GbS)¾§Jm7¼ÃD Çt S,õ*8° B,ºÙ9Ì'S{¸B4ª%¥ o-¼Ñ‹C޹ì1îY˜n+1!j½©d%AÇìU¾Êuûöu§€Â1ØŽ­ ɲyQÀIQ¯ùB‡¯7¼'8‹+@Ú{‚¤È#2.œg.@+î/êñ@8—°6Eã‘Ä-Ï¿G´ª²jUk8Æïv>åLTmK•7Oq€¨E0ÍÓSÏpNmVR«»kí3ð”÷pä?íTšêŒdà#Œ\ûÖ}Ûc—ýÅ2Z*w¸&À§B÷ƒ)÷®ÔqÊïYÂ=ê®dj»Ü½ Ë£¼oÞ3û›þà©cþÓ{ÿÒ˜cs'Øpßt£Àk'+Àö‰èù  jTæoyTˆ™vRþ¼aCqÃ×·›jô\rǯþ=ÿûSĨ÷”m^×`^Qµ{]yFÕívåWµØ”m^×`^Qµ{]yFÕívåWµØ”m^×`^Qµ{]yFÕívåWµØ”m^×`^Qµ{]yFÕívåWµØ©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©S¿•?ûJ•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•>y’ö_å#© ÚÙÔOR½öM©´åÌGÅTnæ`£ÁŽJ !#ñ'?äC¾Œ%Fê3âàþ§÷ªDScØp_ù:gõ÷5Tmsv^޵Tý…qŸ«•ZÇàÂ@í„Ó5šÓÁqÓñ'?äC¾(»|8-¸2Äõ¡Áuñž#­@¹¹êNáÀ:“¸l4ÎE<îœdÒ[—âNz)µ§OSñL7ª†þ—ý|6&pÅ?Ö0çØ‰™xÔc¤ä®bXxÁ6\â¥÷1º€+Œ¹ã$Ž¬Óˆ /ˆ¥ç³Òn¤Ð ?hëÏNeMÑg¼íNv=>îÄást½èÁè:ÕO²`söID]l»dý,ÂöJnñðÆ9Qi ö 'ˆhs1HLº[FO_^(ºçD7¯à‹aî¦N"O@TÅëØ^Ëç³øv›CÌ ´\\ZpŒù‰ÁYÙº ƒ“Þ*5¡Ñ%ãaT¨¶X^s>øÅx­òçcFVàíÛq×0¨Ó¦j²ë§£‘Mº×a0¼RK`àpÄB§N‰¿$à6rŽ]áõaÏC85©ÔöL¦pjî‡ÙpëL7|^ÉíË­]û7·Yp#  üݵF&S\]Uñ©ƒ§„06æ¢N:åT©ÝAê(¼Këj3Ú™…Ó9·„47k.íF+ÚDo ª¸Ô$Œ%HcI«$@û#S X–s™¸Ê/Õ>ѱ )Sg²!?úfÒô†£lÁg('œ¸ª€+Ôsóá¼Õ7EÛú¶kø:«Üۤᡕ.5Ãh÷ƒîTkîQ†N©2»EÛÍ›¹uÊÝÚp{dLçµ6¡eMÑ©µ˜Ç1™rªU÷ dg²µݺ܌çÉ •ANdH"=þíáõaÏùï¡FúŽD»±Ò¬ßhÚdã"O"³ý¦~”ÇDwã I¢¥=bô¤àUíýQœé±»:÷9qø`®¸_qÔbY­8õaòS|879h9ª¦è¨Á˜i ómA Õψ€9ÿ"ñ £|Þ á¶;8œz:9Sx˜]÷mDKCvzÑ7œKµ™RÂiI3¯¬ââuçÊ‹‰¨Ú›>®‹®nØ=IÜ6¹§ÒÀjùÝ7]q†kö!ƒÛSÙ2›À.#ÒÔet’5¢dÏàz:‰­ ›Ê=Ê5rOwÇyd¹¹òª×wCw$ãUÐ^‰æžåð¡7„:ýÈ2y>¾7Úåì•èiîø§€×?ôüþ ”woÛÄhçï+7 ÷ 0ƒÉîø¨ã4moÿ%„O?Çäœ.ðˆŽúTú”ç½d½¨ü­PµB8æ¤Ííha’Õ qŸ3+T.E8‚ˆÏ«ȇՇ=:¯jC…’× ]Ý{ÑŽ!FfÛÚÄ^,Äù±ŽHˆÄ¡ˆ‡Ý¬ÌÂf'ëëÄôŠÎºx£?‡J“ZÊ'Yw¹I©Q­§„G@ ¥Òú„`×v ëî55œ¹ÅÝÜèˆÀïáJ‹ýÅVg ~³_}dºv¼w_x¸e IÔ×ϱ;,‡7›§ÁkçYžÈN ¨Æ•W9ã†ßr˜7²ypBñ.öÝŸ}Ñͯ—›ø˜ï‡*;ö ª9Ü™'áOO'DtfªcM÷3“Õ«£³9V¼wvŒï;¸|_½«¶ñçŽN™÷©ûW@Æugÿ™¦à×´{GªÙ3Óøƒž€.ÌkWž(Ýl~I°Ö\òœ_ú{öO½Eûáù8ƒÔª?ty~Ý'£*vkE÷Üç;’84E=rã֜٥pfq<ã.€‹æùÖã>m²iù§`Ö6Ÿ£Û¶SKEATŒ±Rn¾íYsíèÕʨ›…·½uÿÀ=·ÚZu§¸½ÅÇ_âÎȇՇ?äCêßò!õaÏ•îo‚75aÞ;Ä•¨óý}r¦}}}wÿðã(Ö=Jsó£F_ÇG| #Vû‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Áa¼9ÿ"Vÿ‘d¾FÏŠiiŽEÄuMiucHótã‡b½öu=‚-‡°Ñ9'Cj\Õ·«â‹\*:Ÿ³švuí1’t0¼DOl&°ÞÜ݃×Z§ö¤áéÀæ”$¹ÍØ%àåt;¬‘î^‘!¼‹Ñ¨áè:Ħ‹ÓÈÖ»­SáÈ8DÓ‡Ÿ9ÿ":Î œvˆíTfˆi‡yŠ‹àg3ðìUaÁ÷3.žÈ…WíO ÇX ÐóQÇÒÐ6òÎ*û‰“¬ çÂx47TtÁ”ðú§ÚÛ(>j ÏÌwíT~Ëqý ÐUÞÎÑ­^%ÅäfÐ:FÏ­©Âñ8ìÇXO7‹Æ§G<ªn½Ñ‘k[Ô› }B2 £>|çëÀÆ0]pOmÇ]?“ƒá "ÏÕàNH‚ܘ;橌ýJsü)9âFõ­/0ÊlÀâª2ã£|Ö9üPEìwÑøF´¸À^.v§4°ÁT.“O©ÂU¸Mßî6(ŒýLÊ.xˆ-0|ðÙ"#?>˜N7MÖêWçbªÓ á7/8Aú‰ƒrlë*7VÝ9ùƒ¿ö ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Ãxsó€`‹»n(ˆ@^0Èi •fÈÝ–0¼ÀXS[¡Âý>Q½e ç§?È&> «NáÃ--cMcig‰[¤àü•Jw&ù”œüW‹¡x»õ#Mã0®;b^u!N›8اRkij=í:Wñ9"ð7¯…x8CÓœÖ6ëtQ7¦QÓ¢‹nÐ«Øæ¯ÞÁøª”îb2ÓNóÈ®ÒØx…–˜:ZÇ<ÃW‹»RË{=Ùº| ÁS~X'Q{P˜4Rå(´VçDF@€[6ð\ªS4ÎÒãnÆrÜXp8˜( 0ª84ÜØŒVsF›Û˜ó cža«Å΢œÇ3Œ45¥æÌ]b¿{âî!F“Û©6ƒÎ'¸Åv+-,cŸÅ^.í¡x»µ"#¼³Ží‰Ï3‚6ªn‘Oaaƒæ©·sÎjý슩H³Zn“ß¶“ß^.ýH‚3McFÏPjDFz  ÇHYÝé`·x®D˜)­/0ÔhÀèkKŒÛÁ‰N£®ž*#yE—çdJ…Å1æUfOÚ7~}Xsóxcx+t ¨Ý|f¨š‰ÆJ¤ü.¹n ö–âÏi9á‚ëQy:)T…v–p¯ÆAÍÜ`ƒ)³ÓêÉDÊ&T‘K=•~2:©ÖQ©±n…5àˆ8…y£&­Ð­Ó‘MùˆB‹F%Ø'Ô[ W¢·GmEó™F M¨¯Æ ó}¥‡6«”³ÅT©©Lè!9×´4Á[¤ñ±_gì­Òïº^ÁØ­ÀÁ8*¯VèŒÓ_„j[•3‘[ƒ}¥Qá¢ëUâ…M¨TìVçKiWiê `¨‰mN:Ü©ûKpœ ƒRm!Oç±næsE´ßÈœáM·Z¥5óš#%º¹‰µƒjñ°)Ô^ÝJ›w!}Ù£PÊcÃ…×dœž!•¸T˜…-¢Ø t[¢¨7F_•ýˆ™2˜èÀ ÷ ŠÝ\·W+áÜ`·*g#6“uJ¼Ó›B»H¢ø0 øB¡WšshEá£ Δ TÚƒÈÈ¢v ðœnthÔn¤ÚNq„÷µ‚ërW ðwJŠCÑ\j©H·’ûº\úA„Ú²!^o²à2h[«‘ÜÝÆ s¥Ê®Ò•øâˆ[¡9â¾Ï;ª­Bâ„ÊÄ+Í9µKFM[«¶§0UË4Úô° t¹ƒ0EÍ+”¹Uæ·Š«Ne ¥:©ÖUð·iϺì[³¶­ÑÛQp­Ð+Áã†%†ˆn µHtªÌôÛ‘T…Æß*ùMzÝ\¥ŽãhÙŠmƦ ­_Di§Q:ìi­Æ¦ÄúO`— áó¥ÑGvÕbpºâÝ™¢!×y'¡z@mË–Qø³Ÿ˜€Óúg°¨óý}r¦}}}wè&tR|*¯Â4 èVèV{Ëå^(<¢òw™+ÅIÞÉRt·@‰Ÿ1x«å_+t>bHWÊ™Ð*"gK]u_ÔØ³Þ_+t(™ÐBÝ ÝxO~¡ 8„LïÃÈM©°ªÂµ Óí4ŸuTû%º"òP$!PkNuí2w³Zý¨;aN¨c‰2B¾Uò™SbªëÇ{x«åIAä-Ñnˆ¸•%_;ÀHWކ?QN~ÔL¦ºè3çˆDΊOÂWΙ(< àSÝÀa5À«Ü©îxwñ¾‚Û1kxÒï—"{øO'Aža .1¾‹b~µ#é‘(çø³Ÿ˜Õ2Þd‰ŸËdÏä€a?>¬9ÿ"Vÿ‘«ȇ΃xÀG\9«¦ñf¼Ð €yû3NàÄëOà8±Ù‰=Y«¤87jnš¢zi*{ã¦'¹]1?…9ÿ"ðˆóq¢hÆ2O!Ÿ‚›¦£3˜Ç˜D&Èh<&°cËzUH6P5“ä*Ãt´Tv ú°Ã™T;§öÞ:b;{T]£PÄÛˆëíQ60ÁÍ~ï¬ÔÔíº ô ]ꉸæ¸ê©=SÆ>}"Pü)Ïùïço©Nȇ};û¥]*éWJºUÒ®•t«¥]*éWJºUÒ®•t«¥]*éWJºUÒ®•t«¥]*éWNðçüˆ}XsóÀå QçúúåLúúúïþ:>u¼.*˜b`,¿sóYy`-Dìú÷(á]C;Ç$¡‰jùÐ&ï/ÆkD>rx7‘nôu­`yÝœ¨êå÷¨ÆHÙç2µ}k@JOŒa L}}`†>tá‰çD]0y”gçNó¢0¾½Ýèˆó™€QÊTyÜĨصJˆèóƒC­¨c‚NüùÚìZN7ež]©ÄÔ¢æÓ2çvåОC·p12ßöcÚªNÙÀžxüaÏðzÇBö¹cßñM7]:±î„Ü"uÇw¹£± óv aÓËçF9ÿ)Ðq»c³þSâOœ"ZæíO7œJØœÔÖó÷’‰ 3Éò„¬æsçÃáÖ|àÀÏ'Á aŸóÞ›€ŽO8P<"JyûˆCäîîó£Tê°'báO/Ø ‰SŽêW»ÎjŽ_pø'r, B9ç5×ÿŠÃ^‰Sµ™ÛóøùÁžO‚Ü ¦à7çÕ‡?äC¾ú”çüˆ|ì•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRw‡?äCêÈ• (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… #¿õwÕ˜î#b .ó;.udâP¦¹PûMÉ®ÿg˜bÞ¹Taí¦*ez¯^¤/9ôÊþ¾c‡2¨/Ò¸yU¥•Ï Ü»ŠÄ?ýz¹Žj¦ ˜†wŽ7½UûšŒ8=òªA©XœÄG4|SðEWÀHÛÂø&€,íºp¼îØ?ËÔnï‡ÈMàñPÂ#V\œÈa1­Fu#ŒN¥&! 0FJLÞÖ£ƒwR8›Ç58ÊÈGàŽ˜F_˜Ï«˜BÕùˆùÙR¥J•*T©R¥J•*T©R¥J•*T©R¥Nð硼"²ˆ;âàÜJºCË„oÂ}Á°ž­äð/Œ¦>)Âé#òpZ´=Á¼Pa.¹¯|çã©9¥¦ý¸’6i)#WäãêÞŠ_ÔÐþïqTZ J³ì·ýÊó‹wmeÝ9÷*ÆHÔÿþ(ðœÊ‡gÑQºÚN?XˆCÛCtȼƒÍ«¡U½¹“±Ã£›¢URáV­ÍL1ÖU8mJ"Äòጯ»²îÎóûÕ»uvÄ¡…©ÍoGR¥Â8ä÷ íÊÎꜯT›v ¦rºy²ïDŸíÇ@p…_;Cý+Çå ¨òáÆÏ<ýtÒ_gkœ¸u~L V‹GÝ•ÿš¸ÀHêT¤Rc›ƒŽ|óˆN€+9œkÝ júø¦àöƒÿ¦©7ìé5ù¿Ý ¦4\ Ö?ã¥Z1£Z]ÿ ¯Þ²1—, <áq©5Ü餶ÍEÔóÿ»æž}hÌ¡ª¼»;ïú<è}¥ªín÷\|Z³½“‡'U§ÿ1ÿêðmtØ2pÇþÐ ÉH ¿ü‚ª\ÇZ·>0&:fU úAœSÓ?“Núz”ç£"Ä0˜Ö¢Ìò­œˆâd£ˆ‚Ž" ’‡%º‘áfŒàäµB”jS.¿­k'jÈGäÀµh  “!ÚÂ!³4L†dB8ˆ(⠩ ÝANiœ1£6ˆ•®TâNÕ‘Ö`[¨£ŒÎ¼:™½­B“zþ´89~M;ì%a>¥9þa Wæ#¾•>¥9ï›Æ¦â‡º{¾(cõÉ( ËëWåpµoÚ$O?gü&âÙC¸îø¨Ùõ„¨ü®}XsßÎ2†± ;û!lYÊ&LþV Vü`† g<÷|Ç×$!‡T~W>¬9þQ«R-TÙÏøµ~rÐj4,ôȘó™oÉŒJÍ” â48ÁÙ)á^ü8ßÞçæ]žD ‰@‡eø#êßåAÿ­aæüZ¼óž‰)œ9SÑ)‚©å˜Å5ׄ¡íëu4ÞÇ¢P3Š©”*|]ã]xN‡ê d0X¼ã’n-O0Ò©á!T8B--ũ͊q ¼Ç:èW„Jkï+âc|L @}ša–#„ò™Á%º/ì ®¼œû§I0%S< «Šï2×^æO«”mÔÎÂßÀ«Î“tJkp“­OÙ§6F ëCxÄ*™B›Ž(ˆ¦4¹Ñ€Í4Þ›Â7Áñ·C‰×^OÌO(OÌÌÈRçdñŠyàà›ƒˆEðèGŽ4¿ªe`ò¸ÏæÐDˆW¡‚3W80˜e³¤ñÀ[ŸRsgœÛ¬Ð_Žo*qcE<%º{± ¢èGŽL£j,ž›‰%3 jsî•SвW8Rªe*u ^q ¦ð”çF4KÛ‰Ð\fœëÍÃZn!ð£A|:7ÇÕ‡?Ê5þò¡åoœ{®´¹XÞ_K…˜Ò¯:îƒtzWyw™=\ššp‘ Kàs•5±Š&ä„ÑtBxœBk¯,ÞŽ8C”xáM×9SÑ jnÅé /4¦Æö—‰iDÞºÁpr¦0Ò6Óë´9ÒDˆAÆèhÍÃ.„Ó- F‡bð4 ¯'ž¡ù‚Ž/TÄ5¢õäMàÝ$H…?f†7 ”ÁéDàƒ¡±­5·B¸”xáfÒå8JŽ)ΆʸuÓxN“êßåßãQæœàÀ\ä×´8+QŠæVLöówi Wn.'DkÞh47- –˜K„Á3r©”¡‹ÓưšoÊ ÇŸL •Shº!o8Q±{òÐìÑeÞS1—o ýÚÜÚ…K¸97„K´9 ÆZjqPÅçAž‡íL&lÞG îˆL 50á&·ƒK…ÄF†!£CpqO«”jýÕsËðóVžÊ[Or± ÕmÂÎåK CÇ Ò¯;O‹?‚"D*`ŒýLDˆL  Öíâi>¬9þQwÜW?«à›ó.áZÀØ‹îÈå*Ý÷sw¬­Ÿå÷é Wœ~ )¸4~R ó4xVŠ®æ Çþ ýE[¾èP…­¼ÚBÕç*qcò›¸ãIõaÏÕ»«7MËZ¶Wup3@ÈþJÃYÕ˜omóvö³´OúŸgô•:U»o2¶V4êÓV~çMÎV7—ѳßY1ÝúвñêŽUlɃõWúš]:BÕù}Üfé>¬9ú’­VÑmç*5EfÈÐç‰vùøUu}ŽJ°Ýk–ìiíVSz‹&—ºãKŽ¥J¦êÀýºk˜¤ãÈWƒÅ×8r7»Í8ÃIV^ éiïóô¢wJ³ýË9‚·ãPò7Þ­§þÅYx.¨Î]õ‡îgl«?ßUª×1ú‚´aZ‘çÒ¯ËïÌi>¬9ùç¼Sis²L­X¹¯~ :¼ÕäÔq>–=±æU´ÜÖz~úÓÈÎõKƒh¨Þc¢ÙÂkií*ÌëôZU¨Å}f¬ŽšwN¬:´Ð§»Sª²U–“ĺ®gܬ?p›aû¬œW7a:mf(=PkÇé*°••*jçÒ}XsßxB.’NÔ0CþÈ[Ör‰“)¿ei-Ôîý áÚœ}‘ Ü&Îäj²ùÉxáãnf/7-,­N¯Ê&•c¨òâ×ëÅ[ŒPr´‹†‘åí¡îc@fgB®ìËÚ.î•k@;•ר0«S÷:.*… 1âÏe<ªÑ…jNçÐq¶s7Þ¬˜ýJÑZMå\[_8Ðã %X„Yۢ̓귕SªÊ³på¢ÓJC•SÂÕS–4Z-;Œ$û•´ƒDr¨Úw{C ŸÄh¶84Ó½¶z“\/dàš”¶ôú§ŽöÝý;•« Ìþ¡¢Û‹Zݤ+hšäM7€:+Z]Mðškƒ„… :iVy¨*Át†‹SÍ:F38*Íñ<²":U6Ý Ȭ_ÓµRntÃ4ìã•VÂÓHó¢c¨Z\KU¦¦çEÎVfî5M.@­Æ,îM!7ú·s/ 8‚ØØ{pUè¶fÅ8tŒ´…«~0C³ž{¾ cë’ê?*TÈi>¬9ùËgVo¢Tˆ•B¨¥D×w¤UG¶Ñfs™±Z*eíp˜öÔh{r(Ù.’i<·¹Yª:¥>ck}Ê.!Z)2…1Q¸8vªõfÊj c½îU(ž…n¬Æ1ç\«UVT¡º0Ì¼ÝØjnSŠ«Â´So9TþÊÒæjv?\_UܪŅ2Í„…l2XΞ€›Eϱ_n2¯TT£N°Ú4SÆÕPìQÂÑTs*˜Ú˜6­Õ·*´Ü5gÍ’ÍW1IǪ´ThmíOm°4¸Ôr-Þ7ZƒX­Pfá[sÚÑØUŒpcŽ%UÆÓHs¬­|í÷¦ÚêVªæÑ#ò(‡T´æì¦¥ë ¹¸Û)ŽAðÑáZTùU„Ã]KÙ*•f:ØàÝËÂ5Ö;aTºÒkÓíŒi! º6&á#E·îÀÚB¶ýØ;ÑhƵ&ò÷/ W4ÙqºóæVW^ ÃÉ ×{m*z €{•°ªhŽ#à«MBúãÐËÞ¼$+eMʃœMô¨Ó´OÖ¯®T á!Uû[Ciû8Ÿr©Mµ[uã éÛõ­Y1?¨«>;ƒ¹[8!µ6ltQ kÁTa æÕ¦'QD¾Òæ‚ÈhÅTàÚ˜v‚·5»HÑÿœÿ/½[¸VªLúÍ9¡Üa¤-_—êe¤ú°çç.îuœñ_—>Ä*ÿÑN¸rsb­1Dn6ƒOѩުѶzjÍö5jP<㘦פ÷]k„«?­VrÏZ¶8M6œ¦z“ic]^ ÏŠ=ê‹÷[#iòǽW¥º²jÂÒçÔ¬ó'%n¥¸ý£ÀûгÔÝ)5Éõ©Ó㺭Ôà™)Ìh¶k±HSñ[EòBx­÷Ï®õB£™DÙGcæ©Òm6nc%duÊeôUE:óp«uFÓÜ˶ÏR´Z·ZN¦öÝœ¹SL‰G…k`Vº¾»½‘õàã6p‰ŒUŠ–ïB¬úEû­&°4îì)•J˜¥Rœ„󫦈V ÝÿQY–aÒ«Ñ©I–‹U•·Åc­DðC¥ç4ç5‚óŒh±}Ôr•cû©ÚJ²ÿQweåQ‚£ µºË©Ó­…Üú2NPqˆ;OÉXêš´AvzÕw5Φö™‡B¶U {N?Gt¡Q†¡ûÌùþ°OÂÖÞbŸÃð‹yð-_—êñtŸVüåz-®ËŽM¨i?q´áŒ«9ë¾»rÈw«~ÅQèU:gÆØ5 úíU¬Ô­j “ìtÛ·aXžçTù‘ÜU£þªÖ) ¾¥d¬Vsº'ëµZ-M§Àf/جԷ Mb©LUacµ¡Rµ„º‘?\ŠžÓ÷Ù>ÖiÕ- ia¥Ž¢³ñ~EJÉ]üø7¾¦•ú¦6+-¢¥:-¼ÉB¡»U):èoz´SµS‡—^ŽLGÉY©ºÐð÷qF<çà4[Eë;Ç"³™¢ÃÈ–Ì-wªU<8'¶£âîeïdüy“hÖ±ðÚoíc¦YN]™Ç­RŠUßEÙ;ïVë=3‚8G˜Í̓VŠu˜×½¨ÏZµjfÿ¤F„×Üê{8󒍨í-&™t7n¸Mð}bt!b‹^í«Þ¼$>ÆøôH+Ä雯\u«-÷ڜꙵ®‚Bð‰¸úU6fá[j;ë5XxµqhÔp?ZÕ¹»s¦ÛÎU”üdum:¥R§Y®$bæ÷’¸úÖ¶îڄµYŦÝz•;i²·r´·Ú©Ú)R¬÷K¨cЩÒslÏ¿›¤«jvzpóÅVÕºÓ"“IåԼ˖fè¶2ýN›ÜÝÚ‹âö<‹ÁôËÞûC±œ4ÚhnÌàñ†I´êZÜ ¡°Ñ«iÚ¬..£uÙ·¤Ëm=ö“¬«=Öªw„q~*ÏUôë<–õ»Zÿô{U+xõøN(Rf=ô© ŒìÚ@Qª(³áÚ£z°¡3­Ç¸+s èËsn=J¥f—R¯«å`š¶Š•Žð-_—êñ“êßÍ*ŒXu« ¾¥çz"îšl}çY‡Õc¥rÐþHíÇCê›5ZnnˆVk;h65ë:`÷‰ƒj6*T›EŒÞZÑxä*Êø±µûðp‹+>µï+ÐmqŽc"©Yn;t¨ëÎÓVÈÚµEBz6¦µ¼mRÆ×TìóØ*4±ÚÓ-.³7q¨Ò\2åVZ.¤Òçñ‰Ñá‡5“íb§¹Öª6BsCÅ×*6zvqÂñ*{®éÓ§jf· &p­¯;Ð@v6…&k@èOÒŒ·ÅZó¨*V;ôƒÚò †=)­ F–¶µÏhŽ^DÆ6›CÞÕ{¬õ*1™¾#Þ©YÙN˜§ -õ¦“ª´q†!Y¨ —b㞇°Ù‰eËÍ8ŽB¬´MpìÎ'Ÿx¯Ëõ8‡IõaÏðv|-›Íܬxº«ÿWvˆ>}âZB ïü8ódgg0ó' håo½Y±¯Xò5oôäì…dÄÔv×áÂÚ9[ïV|mÍݽ¤ëžwJ¤.ÓhäóP ŸÀ«òýN)C-Õ‡?Á³ƒm( Áÿq{i?‚¦èðsÇ/ÁQM£“ÌÖÂ×Hó«&©ýGÍUfèÂͪÍHѤì÷•°µÒ<êʼnªïÔw§ú:ŒýQÛø°µ~_¦å ú°çø;AÜëßý'³dmË;'àžë¶jŒýHæmXU¢îUàüim'ÏÚ°©IܽêÁ÷7¶“ß½:éí©ø°µ~8Ä+Eag¢êÎÔ‚+Ö¨×Ó´pƒÿpŸŽ€AÉNòc}:¼Ð3—™·ÖªÞ-Aõ¶àŠÕDÓ¬eÌ1ï̼öZ&tXmµ_k7Ï¥ë¿å1Ú1Ðþ)MâÕ‡?ÁøB›žw›­?Q޼ý—´F{Ág¨DÂËE»5û+Áâ,ÍóöÜ)‡û$b¤ághVôúâÎYìü=&_xjsé¾dG6µyÑj¢êÆÎôxÅ-ÛÅç…›ËU¶…‰¡Ö‡DýjVOY­Ò,î˜ç÷é³Ú¨Ú4]1¦­ª¥QÐçe¦Ú÷[mO¤`fóɳ¥x.(T­c0áÌìW†ê ³ñ¥ö~¨Ïi€õ^¯RYd aõ5ìʰѧbµÔ²ÓÈ´;¼á—»w™ÒmÿõÝ)®hp× Zi:±³‡pÆ0¼2ÓhìcÓžÁ=ð¼hñ«%:ÇXíÖ¨ZiZA4]0c§I1ŠðmGX´;ükßé8vy‹E²Ïd»»¾%xV»¨ÙNçÆws•à†î-©eöØqÞRµÐ­QÔiº\ÜÆŠþ°ÙªUjb9ÁyÁ¿ú½Žø+G„™áâ¾t¹Ù˜<¬â¼Áb´Ô°·‹øöè­Zž™«TÀ •VW`©LÈ:|6fÆiûDÕCì¼)ZŸ´Ö»« ëÓ³S5j˜h@Î!xU×ÙNÊ?Äp•àŠ…ö6µÙ·ƒÕ‚ðebëkªœªÞÿIÙ¼6š"°³—pÎ1¢µ²Ïg¨ÚU]Ùim²ÎúÆÎ×ðÆ­>»iØÇ¦{Ÿ‚±Û/x8Z_¨cÑŸrðuû%jEç âO÷gÜU¦¦ãAõ6UϰXëû$‡gß¡ÜR™Å«~z“¥ÎÈ-ΛÁ4óM7´^#KlçÓ0ˆƒCh9ͽæóF…F‰#CøîgîJüðÓ!÷^\£¦‹F/vA9îs¯k_ÔÕߢÑKw¤ê{U6nl ÆsKL¹¾/F ñ9+¦õÝj­-Ï\èp Åõc±o^ÆÔic²(F“n§U»£s×¥¶zŽ ÅÆï»òFˆ1;À$À[2w!žÔD`tR¦%ÙQ››‹t1¬k/TÖªSÜÏ&€ ŒR“©ñ·Ž¡ˆÏE Ÿ°oÕç ŒJl¶Èß 5òãý¤ÁHD…|ø×~íΈåíÓ—u1¤üµÆßg«©ÒÓÞ;U»Âìo‰žíg¡xB¶ád©TjY+Xw+M•³ÁÍÛ†|ëÊVŸÿŠîÅdð€´T4j0±ùÁÖè :ÕXjà·ü¸÷«§ÆìÌ­´vëUª¶7U~Ax“…h©Æ¨owb?cá`u= üSã^e1•!'œåñVŽ…(;Úk‡V*Ïöþ­Wؽx•[ìü+EÞÓ\:±M§ãVË[²Ö‚*¶dêÕ‚{Å6—» ¬÷©x½½ùÔyžgeܾÓÂÍà ë0™\جVš-ã5Äód¼KÄ­n²~†ž® ÓáZÛ…Š«ù#¯Z—Š:ÃúMÞ± Ûm6´Ý.'PÏ•YííTÅZFAÓfð¥+EcB ãª01 øUîs· {A‰ Íau¨Ô´[[‹ðÙoÅYìV­ÚGÝÒľÏR³p<'hg´}ÚkÕ):©Ô%S°Ôñ6š|Þ<âATü!J­ŒÚÆ@wj^¤iÙçñÂ=:m¿co³ÖÛ-=9vèðÝm{.Óxÿ—æþjŸðjû]ð:|)ëf¥úç©Z~ËÂvzžÐs}ú<(j”,§ÒwcD¯T5,mk³o©?í¼,Æÿé´ž“‡r³Uñamo²KºÄª4üY¾w8ÿ¸o*Þ©N·„››_‡ö·ŠkƒÚÜŠ¡gg„êZjVŤÝÍÙÒ¼h¨× §ïþ¡¨ªõE NªíBU>½µF¸àòŸˆV `¶R¼D8`F©øR[W‹4tê$f_´ðµ&û '¯PšV[M¹ßÌèù¯ ÙœlƒpãS‚:>K¦Ú<êÔ½ ;L+m—u°>ÎßgŒ—ƒí5e§Whÿ”ì“8£AõaÏÎnÂõ<õ…¹Snv*¡ fæÓ*‹®Tn.5 •,fñM®opò*«77B ÛÏÅ=åî¼­_xk[‹Y÷§¡:±/¾5':7ûäÚ˜Ó+쪴à ·"™FEç h3!)•ECqÀSiƒ¢ã¶!ö ŸH¦ÔsMàPëà0wbxÿ®¹ÊaOû:A›qMá9•y;•'ÃøZÕê,À [ˆ~4Š«ölºô5ŦB¬ÉuækO¦æq‚kKÌç ã3ÖP¬Š‚anõ/^”úލd©oõR©}£]O§E/³i«Ô¤ÌªÃthª:S"›/‘2&;„×Fƒ¢YŠÜß±Fj¾­äTênfUÚÆô-Þæ„-Õ×ÜUvݨBm7; ¯µ®}Ön2÷jL¬j:ãò(´‡]@ >.ã)3* ÝZ* õ¢æSû–µR)³si™Na®æó+´•W‡œ2 ŸÚS4úBe"ñxàæQ%S¨"ãò[7³8ªtÍB™Fá¾L€›T‡ßU˜énEq(sïÕç<%Sr±Õ!Vk3M–wä[©x>ÔhP}žÑÇ£Ú5úg€ïz\nÙîVÛc©SfáǨ@„ûE¾Ä[VÔZY0bpz,imµUå¨/ 4ø°¬3¦àî¢?(Ú­S[psœJ­XÚ|EšÞZÞß–›}‰Ö›µhºíFä}Ç‘X¬¢ÇA´F?d>!k}üWð™ï ÂN6Ê­ðu=x¿‘¿4 Ýe©^åJÓ„òàUŠÆ,l"eÇv•á!v­ž¶ÇG^ ÀÍš´ñ]ð^àZlµTÜ‚¸U-5v¼Ž¥â–û;Þ,®mÂgך©f𥡆W²éÎ&axZ‡þæÒô òü—ƒÜ-ºö‘—©÷ª¾ Ým¢Ñ{ƒ#õ7%iû? д=ú|'öõèXƳxó7â¼5…Uö^ÓÚœwo µº˜Ùé8w&'øCsw[gŽ‹M]ƒêì¦x<×ðmÚys^T½àú•ÎnlvKÁö²Ó£°vëÒþ…Øïi„uUü+R•wß±a q×'Ü5«m¶£Ë=QÝ@m*Õm6Ϲ‘ #–SÐÑ©Z|ꕹ>þ8øsë@FO†˜MŒÔnl!áSx¨Àñ­Rû Ô~ªm¯^‹-4Í*‚AL³øRƒw:uZ2g¥X-FÕHßã´y¯öž¢Ïa®=x/ R{¨¶µ!¦oufšÓN×HV¤dSí<,Æû '¬Â°‘f´Z©» î±ò^ ¬jÛþ!ÃûFxRiV®ÆÿŠÖõÞ»ï^`£g¤áè9¿ ð›»p#7Aý@JµÖñz«°àÛ0oƒÙEúÆ=?ò©Ù|)BžãJ£.ŒÌÆ¥c³6ÇA´[©[¬FÓv­#v£r>ãȪÙ<#jnãh{nâf +_ƒêº©¯c}Ç;ròó…o±‹…¦‡øD;â¬dW·W®2†Õ*¯ƒwKkm3†dr‰ƒÛ ø(ŠàÓwÙx·”l÷è°c­^ÊüáŽcð*‡…*ÕªÒöE*’· ¼ú“8£AõaÏÎLoYîmÓ¥±Y—I‚»I„$èefµ¢F#$Iq“½¦æܨªÔÝiÝšï¼l¯-˜…ã}¤ç:ƒ!>źÛÛiôaU~èâä*84°oÛUìZU3º´Ó9êN;ƒn7¯|×™ŠU8s ­@økr)T¹ƒ²*«Ã 7! 8··jžÒiñ†Ü9ªî½Pïx£õ'W¨ízQÏã«Ú1ìYèeGSâ¬ô -qiªUuN6–¸°Þ ¥V‘u‚'KÂÛ•5*•7C¼ Wœðæ6MÈze£·E·Á´mÐ_ í6s+EZƒèí¼ãm¯IÇ*Ló;•¶ÏãVgÑÚ?áx>ÚʶVއdyÆ Á ÿ§5O¦ç;¬ª”ÛU†›ò*Çd§b¥¹Sÿ•F™ÆØ½‡¹Ý#´ïmVJvÆ\©ÐuŽed±S±´†bNdæw–»3-”MäU66“^oý8©ì9®ê+Àí‹#^})=gI ±ØéØin4òÑáAwq¯ì:-T¼™[ÇhãþJÄ[h¶W´´Ëx uIïV¯Q¶T*°€sç@ˆ Ñc¥h«N«ófKÃ÷[VòOV*pû;kœ¢{h½þ ÇÝ;~ Ûhg„îXè‚îFüJ0ß¹¡àµÙb±Ó°ÒÜ©å½ð–ljôF­cb𣉶¥!Ä-!3Š4VüÀ÷OwÅ ~¹%9}jüfèðÛ“‡®ÂÕæÔs‰îø¡\w|TlúÂT*”Td{WRÚ¼j–ÕãT¶ªO²ÑÏ ÅxÕª¥—Á•^^ö <é•èShcL¼jŽÕãT¶­ÒÌ*n¾–R¼j–ÕãT¶¯¥µxÕ«Æ©m^5Kjñª[WRÚ¼j–ÕãT¶¯¥µ>µž£Kˆ)µè1¡­8ãT¶¯£µxÕ-«Æ©m^5Kj©VÍY†LAL¯g¦ÐÖà©VÏU…•1S«g¤ÀÊx¼fŽÕJ¥šƒ:x¼jŽÕDÙ,À¶ˆŽ„èm¯Å‡¼TøöÂñª[WRÚ¼jŽÔmTド[“Ø7_I>“-øTÏzmaKUxÕ-«Æ¨í^5Kj6–G·'R ÏZñª[WRÚ¼j–ÕYοZÁCüS#˜ñû»Si 8¹-ÍÕ¦¡ÏR–Àªþ'iXLr!i¢0xÕ©õ…Q¹ÓÖ©Ñeƒ b¼j–ÕãT¶­Ì×—ž„I´ ÄŽ®UV¥_Ñ«à÷ Ä<úº”(Òm p % EÃ;ÊmaKUxÕ«Æ©m^5Kjñª[WRÚ¼j–ÕãTv¯¥µxÕ-¨Ÿ7[ÅM‹›ËRñª[Uz^uª×wÙßž)œQ ú°çæ± ;û!lYÊ&Lï!r,÷܈c–øc’åÞrhä³¼åPµ^Ô ÌouJÍf'{ªwú§Do9T-R¹wœª!j•ÎTpÍj•½8f¹TFµy€[9ç»à¦>¹! :£}Ê£}Ê£zpÍ3QÓ†k%¼×#|pÍd¢7§ ×&øášäYo5Æq½ŒcF¸Yo#ÑÝ߯1¼>¬9ùçñL*˜º¢‡'jo£É>ÿˆÞ}>zoO/T}v&åþýç¤(ïCÒè÷¦ìçMÈÓß àÁÍ<£½7 è÷¦ìç÷¦ñzð£Þˆ ßwËv;ÁOÚÞØ@íϫ߼^æ÷„2±õñêMôy'ßñMâô ãprIú…8ºr–÷™ZŒíúúäÞ æø!Åže·¾ôrÞô{Ô]ÏÝô;W£<ÝCRöŽÝäÀéQwµjžnϬQËx0l ¾à€ŽOzË´}t,›¿ àÈèj…–{BÕ¤-^|fy½áIŽX@€95éøoµÞX ¸j?®µ«x=.z8´NÆ÷)á§»â²hYïNÞõ¨•l<ýßòŽ­çØ'«ë™MI<½Å]3°Ò'Þ‡¥¼ÞÿÞbCG?yY°]êaÖ{¡[ÁˆÁfØÚÖ÷bŸžóhçï(ìæRc á½ÉÑxÝËyÆ€v êúæN&÷,¬°äúëGIÉ]ÔŒÏ.+,°v'Eãw-/â˜G¤½«“ë?¢ž/4g»Üªç’4”1yçíYˆ^‘èG“IõaÏóZ¿1Vÿ0…«óõaÏóZ¿1Vüåm0B¶1­p#ZnrTFz§ë¹]‰‰ÁL—at „òÁÖcV7ìýÚ§—>±8¦É`';ßíÃýYÿÊj¨Ýórå<šôÖ¬úÏ/y^ ªúÔ%ú“5!”kÅaÙðGQ î0€‹a@˜åXDó÷[4Zª:•9¹¡QíuðqLq}0îDc˜!ŒNЄvüÂqD%@›ªO"_Y"=\¯8ó ¤Ì¢xˆÏJ‚œx§fSs@H•J¤n»…­Üû#|ÕPsãô»ÿ”ó Ò$øåúžeS ô‹ÔF=²žÇÕ97à×ËÂÚ—´æõ Ÿ—jX×ížÂG»Gÿ’ڪТÊtÌ^™è^µÖ¡lcXpq‚xß[M”óy=Èñã;,UÒzAÚœ.ª\Vƒ™h=€ôseªžÁ‰÷“Ù)¸Ô»ª íh÷¦p®O¥==y+ÑNñöºÀ÷>ÅQ·\@Ñk{‹îêV7¸’Ô2=ô3oB\’ }fŒ^GR»Â»õÊ¢õF³Q÷{bMæu8ŽÆŸz¥‘ÙêÃçÈ0Oye*µ=ŸUr«© ĸ4÷çØ›€}»wqÿV]¾¥>¬9ùÊv‡ÓÞê†\µB’§NáæAçD“šaÉw£€C‚A™umÓWÁ´+>ùÁS¦ÚM `Á aN‚eI@ÂJT©:PðuëÚ %L©C*QÅIR¥J™õpZ¼îäÙY©3:5B&q@ƉMàÃèíçåYï¬DwÝõ·¥Kƒ¶GfI¢ìóÏ`SŒò“ÒPÀýbg¼èµY(ÛiîU„…bð-–ÀýÒœ“Ë£‘sRftr+Ç=.–jË£g2$’NÔ03ÉÇÜ8 h¾°P"ï%Þ ‰.2tU Ê¼eN“in‰Ë‘eŽ™R N\žôÞCFJ« é>›}/‚ªàç¹ÍÊg¨ÈêÙ’uÞéÃà=J}Xsü¯ÌGÕ˜( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € i€ ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( € ( ÃÍŸQà°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°Xy³ê#Ÿò!óGÔG?äC¾áõÏC%Ïm3›Œ)iÀf3QÂ-ص‘³ÁuÚwÖÀÇZ|´á\Š…¹ˆžÜÓ>ÓŠšobN,9„æ–˜?ÆÇÍQôSÂÑDìw¸ª8>©>Èÿr‰§ŽsѪÁžWž ˜¸uÝú`ÉÖÔù¶‹ˆâ½Ä…Q¿fãÊ:aT¥J®ŒÒšíÒ¥™]‰èØŸŽwÞ!U<:—5Ç1Ãè*±{ƒül}XsþD>¬9ÿ"Vÿ‘«zoÅïa1ËP5»ÍÚ€'ÖGHÔ¶F3'«Úˆˆ;4b\Ö73ÿ'±ÜÛ•ÛÝúµ§pA'P¢@çOic‹J§ö…» öï öÛ[{ cÖœ.Dý}u¯o‘³õõšt7˜Iç !ŧ1ÝñD˜>vˆÝWfx¥O…L?3 ¸¹ƒkI옪„Sféª%8\½9~AÝs9 $Ç0é:“óf9ay·†ËÝ §²=‚îîÌU@Ö½ÍÔ0žtAiƒæÄ—µ»HhC¦=Ñ0ÛÜݹ"Ò0×7zQƒ„8ênjì8´ê1Òš/4»,ÇQ„Þ®{!­/9].ê |Sø:£´À)ÀµÅ»z~ºÑ‹ÄN_: ´ÁóÕpHäïNo µ»KG8C·uÏúsD€µ?_E×uF<ù&¶CçÑ1õßÌ‚;ãêÞ’ß³¹ÊO\'ðËŽØìÜŠÿ ®Øç;þíH ·y'´Êq˜äüмv|a¡Ú§¨êU «ºkž~þÅTƒQç9*Ÿäãvc›Š à]>ÉoAOuú—ù#»ÄqžVÝêÖÖž) §Ú ®ª0ìU}åÛ|í>N$Lt÷•Oâ@#­Sà\>ËK{!VŸÆ¡ê¸õ#3¯˜ÈíAðö¿c§¿ãÊ™ÁÀå3õÔ©Ï·µ3ƒsô¶ïdJp¼Ø>Áov=ˆ™{·rs¯ãæÆk¶z”p*3ÚøïNá4·{ äžëåçÚpwV¥{ rÛðØšÛ̪×dHî*ô¼¸ë3õÉ‚tíqëLà\ý7¿Õ?[4÷?Ò[ÖéU>ÑÕíGa”ç^¼u—t……âuSx—<ö߯ðÚý.ëÔ¨ËÖì1þèÁ@Q¸™žt]$ì7Ò"P11žo¡æ«ȇՇ=T•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IRT•%IÒ}XsÒÚoJe•±¤¡B«²aêNc˜n¸Aѹ¸80çñßeù—3bn„10? ™„10ÄÝþì‘1š ƒrïix'tc_>Ošò7îv|ב¿s³æ¼ûŸ5äoÜìù¯#~çgÍy÷;>kÈß¹Ùó^FýÎÏšò7îv|ב¿s³æ¼ûŸ5äoÜìù¯#~çgÍy÷;>kÈß¹Ùó^FýÎÏšò7îv|ב¿s³æ¼ûŸ5äoÜìù¯#~çgÍUfæ÷3f“êÞ–ýÅ81‰˜Û„*¡¬amI<7e†Îuf?jcc¿ÚtPh.¼ì›Ë¥YÞ_iiv7ˆž’¨ÀÝ d=á@ûÈÆäôÌdƒK\áèNZçg2&™{täusãžå•ZOì{¡ÅÕ ÷~e¥…\6;¹]Ýf­[vuªŽ¾Ú¯vDû¾x+Dšœävª:í:®Ž]½ykO†U÷}ú)Âé þ –pØîå7h9ÇN^ì•V^{éΉú×ÿ*«‹ß{k‡iUvWG.Þ¼µ§Ã*¿û¾„}átÍu:¼ûºÕl)— ŠÑWó”Þ Ó®{õóLá–‡{QÙW½;õGGâœ!Äh³}Ã9‡á­?~þs¤ú°ç¥•Oˆa6µF`ׯ¸ºôã¢LBeGÓâNª÷bç*uKurªµËÜ0޾´j<ºù8§=Ï2ã)õSŽgó/*d¤Íík¬9é§EõqhM³ÔpžŒÀïM³Ô|†ÇXø§´°ÁÑQ†›®œÓØY°¼SxÄÂ{ 7–I­/pks?š9(7®ëü6fÇ%¬„AáG  ‚3\»Ú^ Ý×ßÏ“æ¼ûŸ5äoÜìù¯#~çgÍy÷;>kÈß¹Ùó^FýÎÏšò7îv|ÕªÉâϹzUÅq\WÅq\WÅq\WÍáõaÏM6n´X˜&c—$iðcoðÝ·“b  kD`ïöÕ97¿WÇ¡YËËjqðç×>åþ)ž5ÖÄs …U¯«U 0ÏYéW -u/ ïG^®‰AäZi)Ç=y§ºxÃ|bgúc>Uj.-h{H<§áùšöæÇ8c¸`«°6û}Çë™W“SœŽÒG]§UÃÑË·¯-iðʯþï¡E8]$ÁR®ܯ\a18û†æ Ô³03úå=’žKœ ÖGxUvWG.Þ¼µ§Ã*¿û¾„}átéºa¼À=ž®Ð)˜8Ʊïú•dÁÏÞ~‡"oPi×=Îúù¦pËC½¨ìǫހú££ƒñNâ4Y¾áœÃÌxSï‡7ÇÏôŸVÿ: ¼ÀÈY£ˆ ëRo^×ø>T8&F“ˆ ëRo^×ø1ÁÎDI9¡1í{Ôœ97”¼-¹±¬¹—/Éygöû~KË?·Ûò^Yý¾ß’òÏíöü—–o·ä¼³û}¿%åŸÛíù+U¯Æ_~ì+êú¾¯«êú¾¯«êú¾¯«ûÃêÞˆ* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ ¨* ‚ é>¬9ÿ"VôÓ¢ú¸´&Ùê8OF`w¦Ùê>Cc¬|SÚX`è¨ÃM×Nz\ÂÀÒu¦´½Á­ÌþhÖÕ·‘Z`þ¼#7„n˜?…h½’׈ZÛ½£àº5)µäœGÖ¥äŠO×BòE §ë¡y"†Óõм‘Ciúè^H¡´ýt/$PÚ~º²ÊË=@ÖìW¸À®p+\ àW¸À®p+'Õ‡=4ÙºÑ``™Ž\‘§À!¿ÃvÞMŠ€-®Aƒ¿ÚtPTäÞý_…FõFUc½CƒœÆÿñ\+ß¹s¦g¾ïJ‡—°ž0gNg·µIm¢…L¦'¯YïT÷OoŒLãŸLgÊ­EÅ­i”ãÜ?37:äuHïúÖœ8ìÏœ@Ë»œ*ع£•ƒ¹Uqm*¤jË“—POà×}ßkVñóNHü?½ÎîLûÆÿ›ý®@‘M×xÓî»:`7@´Þ𪸶•R5eÉ˨'ðk¾ïµ«?øù§$~ÒZa4‡ÝÊ1äàöAÂ8Òu·¿®¤D°^üÏxM2(ÎXõó÷ò&\ËþÐŽhǣ惈h?®:88sbSðqÑfû†s ÿ…>øs||ùÏIõaÏ̵åÀkÿŸwðèÁÁÛ>{÷¬ð¥jm aõµy^¾ÁõÒ¼¯_`úé^W¯°}t¯+ר>ºW•ëì]+Êõö®•^ÔûC¯9_*ùWʾUò¯•|«å_*ùWʾUò¯áõaÏDAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPtŸVÿ‘«ziÐ/mâ@¨YÌ^{€Æ:¹‚§Ct$ŽÝ] í 0 èu*nlī޽r1[›ï\ŒQcºF(Ó{Hf›EƦæì3ì§1ÌãFÖ}È´·©To¥]8á’u7°^p€*€Ij¸é-ŒGæ D˜?†oÝbˆ Áü %4^É Í-%¥jnö‚èԦגqZ—’(m?] É6Ÿ®…äŠO×B¶Ø©Ù®Ü'p+\ àW¸À®p+\ àW¸À®p#¤ú°ç¦×Òkpà“1š–Ü-£xçaª< ÆöÇwdÕ:²çùgÔ¬çŒ0Çn©®`¨öç fy°œ>‚¼ø1ƒc†y>õ}¢µ7‚0i났ïá›Ç0zÕ"iTeçdÑB*R¦Âíg aóUjn‘—¹1Ûv9ºšTEã<0v§]eòH2àz1V—àøˆqÚdöà­O¾üðܪ¬9þñ»sVñõSü"0pvÏýë<)Z›C}m^W¯°}t¯+ר>ºW•ëì]*Ñm©i‹à`¯•|«å_*ùWʾUò¯•|«å_*ùWʾUò¯áõaÏD(P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… 4ŸVÿ‘«ziÐ/mâ@¨YÌ^{€Æ:¹‚§Ct$ŽÝ] í 0 èu*nmÄ«Ž˜„i½¦F•@CKqF›ÁºF)Ìs8Â?3·„ë¿[}ÊôJ{n:éYÇ*‰7F„N ÞÂ0N†éYÇ*‰7Fƒh½«3ôࣂ·ëçÌŽ¨' 4,gÒkœÜHW“¬¾ÇiU©µµѵ] èWBºЮ…t+¡] èWBºЮ…t+¡] èWB:O«ziÝ}&· 8©mÂÚ1Žq–š£À¬olwqÑ@†MS«.–}JÌáuí1&3úUŠÅÒ0n®ef}Ê—§Qî*Îî8B¦ñN¥N-Ÿz$œOævýãO?û\›Ç“«_ŽTìKyÇxU¤Ó­´Çs¾IçíŸw[§ç)Ñ&?Øq“«·åßÌœæ:Ÿ¥'´ } ´9â2–ö«I§[iŽç|“ÏÛ>î·OÎS¢L~ÂóHMuâ× £¯Ô&ñ¯˜|þ½Èñ[9üðìL?sÉ=ÎTÅ×6} {=þä8ŸçÿëóíOão¸g0ÑhûçóŸÂôŸVÿ‰²3õ³zÛ}¥ k°ËÊ6¯o°'Ts‰qWмUâ¯x«Å^*ñWмUâ¯x«Å^*ñWмUã¼>¬9è… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡B… (P¡F“êßò!õaÏK(´°>£ (°2óݬŒå£j¥J•GÞ:õlµ>è<‚¸Ýnj«Z×–°þm&0OmÇ]+8åQ&èÏð»N¤átÂÎ9TIº3üEèåïîÅf`#€½©G;o×Ï™3PNCBºЮ…t+¡] èWBºЮ…t+¡] èWBºЮ…t+¡'Õ‡=4ÞÓM­& g19­Ý¤8R}Î:òÂ2TÞT¹ÆsÇœœ)Ëõêé×ù¸ñ]:û¿çܫêÿ˜w…ZM:ÛLw;äž~Ù÷uº~rcð‚n83>áðÅV‡¬9ÿѲ:µ7U˜~}Xsþ=±¹­Ý/Dïϫǭ¶]hnæÞ­ùõaÏùú²APTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAPTAGÿmOÿÄY  12!‘’¡"3AQq 5Bar£±#0PRÁÑ4@S`bpáâ$Ccs‚²ðt¢ÒDƒÂdñTu€“”%³ÿÚ?ýøÍ5/hÁÊ´_‘ûßà„Ãx‰èÌÒ.ctºÙž´ð¼Ò3–º0·[¯È½ïð_‘{ßàŒ4o‚Õ»ZêýóÛð ÿíL7œ]þ³-<Íý º¾£xCÙeùÍðt$1éŒA…ʘ½Ã4Z…¯QŠó;w©?É‹xÙoMäm4Ú½ÿœÅh(¢#w®¶íoZ€¯±ˆNa!3gëÿŠÅ/Í"g•ýOƒÎÏ{^ªXŠÖÖ*SB$-vM]¯÷&ˆæ•†ñ´-[»PÇrMP/5.¿z³8±|¾Vìíª†-ªSgzµêWÄ"–R!½pG[7®¨4QË;_¤m­›íLý½©ýMD4RK!îe0M- ëË¢ûo]Ri‚G˜£Ó]k£ÎÔ¥'¬rhÜzÝõSâßS2‘Â)c¬dqÈc¨µÌQ”¦gHã{¬-‰vw£y"–3xÝš÷9èÊÒa´ðµ^9)·ƒÆïè–,˜ „\îi\yµø£ù)t`z2–už´íEò38Œš'6W”pâ8Þ„‹ o]QS=œß ™Ý¶®QµÛ9FkDL&Š6¾ÌÝÈ$´´ÌªíÛŽ¦ïVGŽDåjc¸†ºŽ,úÕœã†yd˜ˆÎ"×ê9«W¦¥ƒcµÊR×ä†.pÓ¶¸+9Aö£œ\Æ(CœÌØÖ¸.MŠ ,’Aj'';S½úºÓ3éí“É4 „lÅÍ}}t£v«9ŒSÈS™DшsØÛvC#C;ÊS</u´—û1§Òè䇪ä£t›÷Y'µ÷7‚8,®çNw18Þ}mÔÃGVb²µ†ÆG8ƒÚ,Ѽw*ýc^}pÖ£”ÆäšÄź‰ž…ÅŸÁ'µ÷7‚Ømhš; žF‰ÆÌæ<Á+ÜázæêìëA‹•íVËDxXt7Y¾±>S&{A´“’DFÍK×MÆ´û<ŽSÿ¥—ý®ƒ•íÁzb×d€¿ÞêåªG8¥,_ÑÃÂË(¿Îoƒ h®ßùïFÔõGi´\¾ãpB=l̤ÿ%þ-àe¼‰m|ú´Ró=tûU•­c  Œ£çkëj>ÆVf†;Ìᆧj ÒH2HÓ ^ýj3'¦)™Mè%‚L4Þ‡ hHb³Ú¾HcþÒØS­ó.è€( L+Õö©¥"g‹^ˆ~­u— Äñ‚ »³>ºãEçšÕ.ŽáŒÍAïlT Y^èR­Xî?hÑ‘é …™ËµW·Zõ\hœ=x²h™áÐ5£Mz¯z—¯QMgr‡A,¤nU{ÌÎU¢æ`Ìr‹}vËñà¤= ¦ÎÏ#;Zx ¡¸Ñ¸3jZµw#xß›õµG·ÔŠÙlîòFT…º„«¶„,ÓÄ =í_ÅG-¦Ï ZÒ¥iÜé‰ô'IÚM1¹Òµ§©Z g¬òZñ=o3^שÔuÚZo²ó:µHô¤®ÎÛ(û5x9fÏz;öÉ$(Þ¯F«u«Í±Ä.'ÆB†½X®L¾PÒ˧½r¾›ê¢xôv;Mm2ÍrkͨŸU °ubš+kD$Çæw5¾§ýªa­Y$³˜í1DP˜Xœ¯55.K´¼°Ë=žóMVqgbÆÊ+DZ#’g¸n÷H «5> Ç1ÉH6™-3Ò¬Õ!v ðV¶¹d´4Ö·ŸG=ivŒØõ:ÑO.ï9jwvú¬ï¯÷Y'µ÷7‚9ì¬' Žbg- 0Ýw£u8Ñ•˜l¯a¶N&ö{4¯#¬©Ì¦:Ôq^“Y7Y;Ô¸»ø$ö¾æð[¬3Z‚yZQ(H5|˜ñ7ÕG¡ä;LWÊñ\Ð5_·¤T”nK,·k…ã"§ £1cj¾Ȧ–Ý­ú´X7f+òßuüPòfríð²Éá‘ÜuÕ‰º~[ü·Ýg¤yd&¥êSW€=–ýëÉí}ÍåIí}Íó¡ì·”Ë~õäö¾æò¤ö¾æòú1غ1غ1غ1غ1غ1ذX, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X,  ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°Xx0X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X,Výù›CupéWÁÛ¯÷Þq˨^ºßª •p­çzþç¨ËÚ°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°m«Ú°mªŽ£"æ’Gæ=;õ¯7{ÿå^n÷ÿʼÝïÿ•y»ßÿ*ów¿þUæïü«ÍÞÿùW›½ÿò¯7{ÿå^n÷ÿʼÝïÿ•y»ßÿ*ów¿þUæïüª+T5ÑÈݘòM€7†×¤¾äÜæºÝ_3b82y­Ai©ê¬c²G=ËûD„TpoW•É–}—ÇeÑ^½Kž¿_²ïúQû—'îñùû'úÿÞÿ;f±r}¡âÓXý'¨GÎzÞ·Ô­V‰9^Ûm7„šìÒsYûYº•†Yå9¥&*œ…W~s¯èìQÍ G)Ë|¨Ç©±í\€vhô¶ŠJ1‹áyÚ_Vµ¦é¹­¸ó^רVë ±ô¥fw‚R‰éÜlŽÏk2;mŽR‚W7«½:×$ò]ši!­ªÒñ5°gðËÉ<›hñ+=™™íV¡j•_ÑöÎMåKg(”zÎÉk}.‘½K‘exÊ';tpÚ„8êuýŠ9¤Ž9d‘¤*1êl{TɆ0Ú¥ ,¶‚jècîíO-‹úAn;[k¥¨¯Ä^ªu+]¥ÇÅíqG$rˆ¾Iº•–kW*Ú¬p0ݳŸÊIûDjI¶[”,v°"‚is‹¶,ïÖ¹ ¿¬-ßÚ­NÔÓj‡ü¾ÄðøÕ¦Ùν¤µÉ|»«à“ú²!–Øú†ûћִ“H¹CÇ1¬EH™ý…l³ÛœJÙb™à9¨ÇØê[?õ…¢Ëf†cÒZX«,]B.ø32ŽÜ<¡hå>L¼ÃhŠÔ÷Œý&%É2Ød;Çk Ö‘»ÔŠÒÜ¿knP¥æzA^˨m[¦äË8|ÛÝ9 ±*õ7©SZí‡Êiáy –lãLYßÉå"È âº"ÚÚò–?œ&Ò fÍSoVµ ªÑ ÉF®‘ÿe«ñSœ£%àjÈ·9»Vs³Ú –Vw”Yµ7ÚŠÐ6{CBÃV' Þ¦lTíâÓ„ñ…ý ³T›·.L”ØìÅ9QÆë;2½º›ŠwÑÍâìwÓwäë‡üuh‰¬ö‰ž i1j3R½ª&Š9mE iY¡oG·Z ˜š´&£¨šJ°È÷tž‹?­ •H‰î„a˜ŸÕúÎÝÊÕ8gŠ"6¯©‘yRŽ,ÔþËëõúÔ6[CÚIž+Ö]Åŵ]wúÝj&’¬2=Ý'¢ÏëBåR"{¡f'õx ½X!¤r´—š˜ÑšˆlÓÚHº¡ø½YÞ¦´”âæ1ÆÍzjì¬öa²É¡–-÷fgmmÚõà¬ÅgÑŒOZÎ`ÂQ÷68ö«Ï¬s©ˆY„Ê•tŠfŽG»Î<ÓR±ƒ_½j!«aÞ¼eªQÞ¥ÙÚ¬ M s9?Ê sÆëÿѽžxÜÙÞ= ³_§f¿sÍg‘¥3p•+•yl°´K¡ƒü±ÿœÚ”ùF˪š;4÷e¹K”mZ©£´Ï|vQI =SøÞ“ý/‚)%1Ž1j‘“Ñ™rD‘›I[áq!z³¶µýÿ6_ƒ+D2[mv%J2²K£r§WÅyÿ—?þçð\¨yæ´4Á$¤s›»Ýí¢äßòþ÷_ÑŸýïö¯èÏý_ळ<óYïÿyg+¦Ýμ÷Ë?ÿoø+ žÈÞ3kœÆÍZºþ±*Û¤6x&oµH"ŽB”B×vù•IûÝZ@s…¨ï.Q¿éÖïwÔ¿¢a&qµYØ»éàó¤ø®Hÿ¥“ïòyIÆ:éŽ m®í*¢™‡äš/[»+E Ö3Ê]Ò5)¨› U²SŒ¬‡@ºV»N’·^ºõ½r}ø¡#ÓHÄøc«©CgޱÚEš¢ÅG¥u³?r–W³ž#³èþVm!V½zÝrLrA£{)ÐùÌú˜ª’šÎÏÔ*`#¬òZô¸R­GÖ£µÊCpAù¿áÝ}N´Ak†F3g&³Y-MÚômjM%¤-³¹ŠF‚ä‚Ýwžšø®TŸIòS¬G×\<6Oõÿ½þvT½‹…•àq¯:µ¯‚aäKu›Äe+þ/kù7õQrg)Ú-¡j´DDó‘suSš ÛW'Ìd-f€dc×C«¶§ç^.¥axpñ¢ôÔîÁx¼Dò=ù%<ÒjÄœmh³ÝÅÉõQYla„ ÃÞý~å>Mµx)Ürv¨J=„ɬü¯n²Åa¯>+•dõ;ºäû=“GÙ­1ËCÔ×G©—#Zã(Ú;™HÄúÞ¬Ø(&Šr±ÛìïXm!Õê~Ö^//(Ø ‰õ=¢--> NL²uÄCxúÉÛVKÎ%,#uÜ0\‘n¢±é/±>·«u( üZÙf“K ´«3úÑ7*šI¯s^ÍZSíð ZW³Í´°Ì82ÐOÊ6¡À­Fúgo·S.QkÂðÍ-è¨NîÃëõ¢·rU¤,ÖÍ< LÕŽV®ª÷v¨%åë\|,–F{„]®î¹1á(ÇÅ­a9ß|Y»<d´g#cz¶·VSA' ¿:¯óÎÕgêO ‚(kŽŒkúàÝÞYwý(ýË“¿÷?øüý“ýï*H¬VWµœzŒœî?e{Tq[l¯d951ß~ÊöüãÓS¨mœ©Êrr¡ÙõƒöѱÌÊͦÓÖB’õÛ¸þ¿U—Rê]K©u.¤ø.¥Ôº—Rê]K©u.¥Ôº—Rê]K©u.¥Ôº—Rê]K©u.¥Ôº—Rê]K©u.¥Ôº—Rê]K©u.¥Ôº—Rê]K©u.¥Ôº•]FÎo‘¿4é^õùoºþ+òßuüWå¾ëø¯Ë}×ñ_–û¯â¿-÷_Å~[ü·Ýùoºþ+òßuüWå¾ëø¯Ë}×ñ_–û¯â¿-÷_ÅEeŠ·#n¿*Ä $V¹Jéè†ó±^{ïߎ=jØFDV¹JðiŠó±^k߆¾ù%±ZžÈrk1p¾ý´íQËmµ=¬ãÖÁpûiÛÿë˜y­‚ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²ÊË+,¬²²55§ùÆYYee•–VYYee•–VYYee•–VYYee•–VYYee•–VYYee•–VYYee•–VYYee•–VYYee•–VYY šþt9BV¸%Iqž¯Wl­Úè*mgœžš ^‡övùCܘ‰ˆÈŠàF Î7ìe¥›“ÛCסšüþš7tFL`mxIºÛÁuˆ¯!ȵ3x)]}žS5uºÕÝäUëšî¦®µV¯Ú.Þ£ÖžSëÃ[¦vð°õ¾«Ò©éÔôòî9kÃB*:ç¯ ¦«ã…5¦;Üך괗¹©‰ŸS½ß×AïOóáñ=#xÍÍ&öVIÏÒhiGÍKÔÙô÷üí’ÒS³ŽhK,u3¶ëí~ÕÈ‹dz{L¬dÂ…£ÒWW¬>P÷.Oš]PÐâ«àÆWnü ¾ÔFnÂÕw~¦Q»‹ƒ‚/艸¶Ço¦&{Ñ›u©‰‚ãꬔ§Ø¥!r¨~ÝgZµHÄU ­]M©Kvb:…hå_µ]¼DÎç=UjõÑýe JB9)é¦îß-wQWU;QÆÇ„”kÇ­Ú˜U3ÉZ¾«ôâ¢7a{ÚØ±£ö«7Êæk×0¹žºð@BpÒ;UŸ¢pcÂGj9ÑÉ»*µ^Ôôç+=˜ô¯Ú¾P…Þ½Z–“JM&’íÛßµ…§V›¤LZFlÝËFÎz†ö¹)ÅExË\U{¯Mj2swæUØNë÷¢ #æ…jçu‘ß‘ãº,íG§Ú¦+Ï{DÏ›½=ùH.ƒ;P©ö§¾F?$/AzkÖ¯×å4wÜä‰õ•T“Fý]uûdŽŠëÆ.xõºµßï×ÙDZ]O£TWõ|ŽªÿÎå úçwjþïJT³ÿºµ8àæÔïÕúè=éüd²Æ.z3¹E$•×FfêÙ¬S³F,ÏŽ¬Ui¯µ3¸³»`®8³Õ¦¥¨ºðNÎ ìøÕ±L/¸·U×qì¢fºÔlŠë€»cJ&涬=IÙÀ]Ÿ]•¨ÝŒˆ™Þ´}jƒ³Vº™^rV¹9ÛSÑ©TîâÕRkÀÅL*ËP³u&gŒ]› ¶ ¤Oëd×€J˜U•\Yß¹5@^˜U°U¦µ¨YµSÍæZ£îeuÅœ{•Ûƒw²‰ÙÅŸ¢faffÁ¨²·n õÁ½ÛE~àßúÔ×á¾à.ZšÓ9 ¶dׅЬ¨bÄÞ¶WHYDZÙ\º×{)© ]faÖÌß®ƒÞŸÀ/iŠù Q‰‰ÅéÙ«©Z#Ð5ÉÀcYݪ-ƒz—h[Æ´z-%}2à Ã&g¼þ“Ô¸©$ 31¿9èÌøÑº¾Ä1œ‡ÅÙ¯¿G«V>¦V$7¼a„dç>¶¼/zýo=/vݾµf`†g"8¹ÏÍw­~.ž+0hãrr»WvMáÐhƒCKº;¼ÚvQ3´1³±^­ÞºR»>‚ÿÍœØ,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3,̳2ÌË3!£×Zœe™–fY™fe™–fY™fe™–fY™fe™–fY™fe™–fY™fe™–fY™fe™–fY™fe™–fY™fe™–fY™fe™Ñë¯ó\ ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°XxpX, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°X, ‚Á`°ùèæ¬ 4–çbnöÑ⤘â°F.NÑÛÉû›Gï¾8ï‰rƒ“1;Ïgps®½W«ÁMÊ N6€”hÍFv­5S÷ßíÄö@a Vë`Õû–_&³8ܸպþ¿˜Šˆ´ÄãxÅ+F®¾j´É ½ãÒ³ë|ƒOŸôwÚöÅp­0‰Öí×6­{é§ŽØi š©žyã…Ÿ !3Uid”#ë‘Q”I8\˜®‰15;û‘F×6666z×Õ÷¢hgŽWn=F˜NGj°‰³»¦ç¦|#skÛ<›PY¹>)#‚WŠñÚn×ì»ëL3Ï 2êæ‹­Zb)5óÚº±E ´E5ÜÚ3b¢+–¨Nèß{²3Ñ»Uû<ÑÎ^Œ˜›È´Zôz]ÖåiTÜ¡ZC¢Ò¿«RŽß(µ µc<ºéŠ+sÎYÛŒ™ïz™ ¯l£&¼Æò5•¥ËFÂT¾Ò³Õ©Z¿by!ž9£lJ3gdOgž)Øu>ŒØ©ûÐäŸóýŽ­ÆâÎMT~ÌÊ-pA'‹½–8yáÏĉHH€\œÏ[·ì2Žb´GåepµEx%oSö«>’89:¶a£ÍòØåÈóÚÿ$oj®ªöjªŠÑgŽå˜m€dwy¯¯Yw.Rñzë$N×=!¼U§Ø¬Éì/¢bÒ¼cK¡L¯öÓRä³f-/hfþÙf ¬xê[}þE³ÙûÓò×ñyfñªõh±!ßø®L’±ž;T¯#˘8®»³;.]–)¢µ4€Ú¬Ð8æl[[Õû—&KÉâñi\«\ äv`åÊqf¯2àõv`¹Eàbpx˜e´Y‚¬ÿ‹²”ìÖ±[ûeš;yÿÕ¸]&žY^ìQFíStw‰¡–'»,R;T÷ße³œ’ LDq3ó^V ?uTÎ6+,T³ÔDcÍÎv¥q×Ýöù_‘ûÓüWä~ôÿù½?Å~GïOñ_‘ûÓüWä~ôÿù½?Å~GïOñ_‘ûÓüWä~ôÿù½?Å~GïOñ_‘ûÓüWä~ôÿù½?Å~GïOñ^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼þXC*LÀ-NŒ? {êŽ9Rgjtqþ÷SÿØŠûµ{H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\H\(EŽGg.q]ëwûY¸0HÌÅÍ+ÂBýlÿcùV냑|sÅ „¤ñ¡ìvV'Ÿ“¡²K=£DQÉkCÚݯê\­4ñ4maàÒ5fRkdvˆ´4©övSºs³ÚbœˆØ™”a²Ï!ÈÕ YܛԞϲ 'lbËgç!ì·ï½§øùNÚâk¯=˜jÅXýbìÎɾHÜåk­½ó„jåY=dîîþWô‹ÄySúºì‘Þù’÷7Ö¿£qÚ­>9;rˆ^šãìz™LÜ€IÆÖN5lRþŒY ŠÌÖY݈Â^lFwíê!”ÿª¬.öci,Ö3v)Fšží: š;<ÒÅ%ûc³^ Z·—%½»“lV»#J (Xdºuê'íÛùÈ{-ûÄ/iþ>QhþFóÕÆ—£'õáGA¤ùg« .Æ/êƯåZm0ÇrkK³ÊU~u0Vr´G¤{<,zݨ]ªÖ#]µ“œìNîÆïÞŽÀ61ñC+ï;–¾Ýx)ÉeŠFºEyÈ©ÙWCc‚&0³³Fï{ô6ˆ¬ 2‹Þ“» úš´oÎCÙoò„§ÊHsF8í1³>­L¹´[íºkkP浿7W^­mêAk.G“Äôïg)Ffw½ZjnµÊ1ò•ˆ¬Xâiœt%áüU–Ïmäâ°µ­ìç¥c½ª´~Ç¢³Ø,öFµZ¦6c™¢w¿ZäÈ[’e{MµäJF»Ö­^3b’|Œcbb¼E–„­ãlä÷³[,ÐxÃC¦biÔL¬pÍÉGflnVc)™ï½+GìV×·D×cœÀd¾Ú¿bŒÝ]«ú@0Øæå0„Áîi®ŒCwª¿VXš+–{M™íÌEÖÏÎz—</9\kןÔG&‰HN-8Ì$Cí¢‡”’$Oc¹,Í3=Ít«55²”Ó {$BÆv‚˜cgöYó(¬¶M+iKdX>•ƒSöÕxä08ËΗ¦ÝUSÛíöFž(í:7•¥fvÔ}L>Ž®õÊGeñ€±Y|bI4”Öø ÀÖ¾M;šÝÐNò±T©Z;u'µ·'›òCK¢{f‘«+s²¿¹Ý Âó3?=‡nÖíîQʧÒôC2?© ›]:kfzÑry9Hѹ“F.Uæ¿S+aZ4QÙ/]çDõ½ÕVâ­ífÈ ›IBb»]MêCÈ‘Œbg¦£Ù\]5µ™Ê2!fÅëƒ)žK;ÙäÅâ’õyͪºµ«DRÙnÏ4‚#;?¯Wb´Ö9a¸÷ašû=ç¦4Årx´1”ÉŒt¿²ýw|‚öŸãô`{-àk4m(d}Tg\“,D6KKLwßõ!äý$f¶xÅj÷nÞ¯f+”å–@5®È6v¦a&zÕYæžÏÉQ žËé$~Ýx}Š'†;¦g‚Ýõ˜›ZþŒØá´ÚãC‰HÎñá—¶JÛ5º{9r•¢`™˜EÞ¹©‡µÛZå!xy2É4ð<1›½Ëý‘Ž*r{>—[ëæSV¥oŽC‚KÓñ8×IRê~¥Êö›¢ÄÁnqæÍz£Í¥uu®Fäkä\¬âG[‰ÕýL¡²ÃÍ£`û–Õ3Ø!ÐI¤+EŒ%›ÔM‚ŽÄ‹<|›4¥¤rÒ‹1àÝ]K”J?š;H]Ž[X‘I6”ÅY­RO|œGaw­æ~ìN@FSœŸ&ú¨î¹ZÍʳÁýW+“Ç 1i9ý­±r¥ª×{Æ­q9“ž7Y¨<>+‘NÝh³=‚Æ!4m>Þî«ÝKA\—%—Iy­Âå; p¦ûž9㉆BëøÓ³Áešõ4ïJcV¢œ´·4°hrÖšëUjmzm-òƒ£¼õ¥5=SÉf´´$`Àw¢¿Zu¶½NžÎfX7?®­Ö¤ E³Håv—cºÍG®S“ËwIÇKµÀ«ÿLòZEÊAŒyݺUªÎqÉ¢’¼ÎãyŸUãä´ÿ£ÙoÞ!{Oñò Š ;Ú˜äÑÊq¿E†;x+DSÙÞÊÁ&Ž#‘ú\pÙÇÊþ¯þ»= Ùügòhþ½.à´AÊh™íåX<Ðò~›ŸéK¬ú•Œ-–èíÁl °×Wkw®I†sÑ[¤µDÆ÷[å¡*ëo†¥gžÇÊEfŽI£ƒE¡Åñ«²³Zmƒå+G/ɾ“}[&CoåŸêòš–Y4T*êQr`”¶›1Ke) l–6”‹ŸF+®Úµ(C37©H ûÛ«óö[÷ˆ^Óü|«8Y­E ´Hò´@÷^sáêë͇[r€Z-I§^ãk¯5ðõueíü–å+ǧÐè.ú4­P°É0ÚÞØ23µæ7ŰÁM Æå,¦ò=­Øtõ­u¾Ë+Ë [%Ó;µD»GRzZm€Ç,qKA•™©ÎÔ­G-­;0ü°±hÙšŒÁ«RƒGk¶ÙåŠ&ƒM ·N@lµ+-„Xá³Ù¤úÅë­IiŠG’Ï⥿5Ƶڴ…hµÚˆAã‹Æ%½¢gÕÍ\–){“ž*ןÔú”QÌF-£3\íâÓˆ^¨c©ê å#ÓCF-èÑÔvϵÙ'ôLöcaÕZõ³¨âÒ×—äz‘wþ`Ëx A\y×qº¦­í:ð¯ôfw@Œ†ƒs]>Þ¾¤2=¢ým%Š…çûj¬FV6ž¬AFÕFÇÈ×EFÑÓŒWKw]ìT² ^qvnÕIo¸Ôôxß.¾ê:HO†cÏaaÔχ_WZ˜%´H2Ýô)Ž"íÕÞŽ–æ’QšëW£®Ôm:@'3‰‚ö§ëgêí¢" ú1”BœÆm]¯zª£!”r4—o0³jn®½ªÊØAz-3Ét}Z°ÁZíhÊQ½ZéóGÈ‹E{E_”»ÁK¥½¢¯ÉÞãàµK#Í-£FÎ °­¿z³ƒÌàß+zŒ5+¤ÌÉÌ\åŽC6mXRšö«åjÒ¿‹UŠëUªLå2ÑÃ(‰é.Öë·]ÝX ’LÇÎîgÁ¿tEí?ÇÊ‚X-e`“I(FÝ.ìâ§–{CÚ˜äÒD7EŽx} Ëy:B†2“븵SÐ)oé.ëÖõ¢ F¯# ¼²»cyêTÖžV†6‘õߺÕF!b'™˜Þž7†7Änµ Aegæ÷&•â•°;ºö¢6‚62Ä®5]ÉH#ƒÖˆ¹ƒÎÇV>Y Ä$õv!­]5ÈÀ)…9„1‰¾$ÂÕDÃgˆX± 6´ðD1Áça [³÷F^Óü~w¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤. ¤.@{-ûÄ/iþ?;Z¶Å‹lX¶Å‹lX¶Å‹lX¶Å‹lX¶Å‹lX¶Å‹lX¶Å‹lX¶Å‹lX¶Å‹lX¶Å‹lX¶Å‹lX¶Å‹lX¶Å‹lX¶ÅZ¶Ï =–ð“Ù­ZéhŠŽ¼[Ç ñŸÐéþÄ%i´EgbÔÏ)°×ji$”#èÌdTmxy%œ§c¡ N,ìûPÉ´‘“TH^¬ì¦Ž)‚I!{²½n¿­Ai†s ÃŒN=ê@ Ê7¡ˆ•\_×óz;MºÍg’•¹,¢/Å<¶kDVˆÙé~#bn á‚ÙgšVÄ#•ö Ž{L0ÈyFI\»”c$€#Ý"¥çìoÝ1{Oñò£æžW¤q_àÊ8í¶aƒJ÷BH¥Ò {SSÊï.HX¾R6g&ì®Í »Èe¼ò-€®ÛmmÏ‘¿¹‹¬¿ý ±@åajxÄ›æâ¡ä«%˜m¯;üÑ´Õ®³rìV[@Úbiâá?‡H/\_Ö¬Ckµ?ˆXBí– ï¥vÔó=0¦ªgg«?_‘l´ÍÈœ™mùi'=?:Sg×ÍÔ¡{;–Í<\Ý Ü õ7bþ’Øb¼0´€ ®¯•úÕ˜ÆÓ¶¦„¬ÖQtz±)$zëºÌžÏa´<æùLÅÄËÓ×ÛóvÛd|Ÿ`µÂqFVç«51ÕEl°IbnM ‘á´ÙìüÖ¯©ÛµrpTGÈÖ8mCw”££¹v77 úÕ®×ãpÙᚎwšî=bõÔ‚ÓnŸG-ÖŠÉ ‹ü>Oƒúú¿tÅí?ÇÊ lÿ+k†"m5h$ãÎÿ·´Êv‚²éb=5¢ŽÇ¤ Z¾Ï({—&Ç#^µ5[·šJײ٬—n•Ž#aºÝ ºë‚··)=éôCâ®M­ù¾‡®õpS´çqæäètLþ°Pxܶh ñ8´>5Vœë´&çaëP¦Xí“ ”)¨J3?\oÔO·j'„"´K dsã{î¯æOm±k•úXõJßq&¶[’·E=Z&ûËÖ‹»Èe¼jµÙt³»QËJcðuÊV˜B-1‘x¯ʰSüuhµÞä‹M®wçO;ÊåOªÚµ2‚ÌòG’k8Ýòõ°w©_“ŠÍ3ÙÕË©;d‚`ÂúÚÖ¹Lí²Zã(ãÖ0ÇÔÍñtöËqÁ¤0Ù@lõ¥ÖzÕëórÚ¹.Û Ç33šÝyÀºÆ˜+lÊ([$ÓIk‡›Cõz”6NUµØ¼D ˆÞÌ%¤–µÔßb³Âd-ÉÂ÷æJWlÙVЊXÃm’)%½] \¦¡êêýÓ´ÿ*} ²ÍIe)+%”ˆµ¾úF­0ûa=²Ìñ ¡#´vRg{¤ÅŽ‘û<¡îð>ÔQBqŒX¸êüÜ»¼€ö[÷ˆ^Óü~w3¬Î³:Ìë3¬Î³:Ìë3¬Î³:Ìë3¬Î³:Ìë3¬Î³:Ìë3¬Î³:Ìë3¬Î³:Ìþ@{-ûÄ/iþ?F²ß¼BöŸãåZm7oèb).Ö•£U ¸UFMÄGv·„…Ú›hÿbgµC΂H+ÙÛÛ+0î¬Ãº³êÌ;«0î¬Ãº³êÌ;«0î¬Ãº³êÌ;«0î¬Ãº³êÌ;«0î¬Ãº³êÌ;«0î¬Ãº³êÌ;«0î¬Ãº³êÌ;¾@{-ó‡ßû´~ï ½§øýË|á÷þí»È/iþ?; ˆ9 &ñ‡&„üm†õ¯èêVëÜ•zÏb¹§‘­-Q¼ÌúššÕŠÍâï0NÌrKzšw£;©ù"HîFÇ—µÒ´õ+ Yy7Mi´ÂóèžÐÀÌÕ¦§vÖêÉiñ$žÑ¯Å‰î³5J½ÊÉ‚È\£i´Ç¦c`f×wEnnG;±U­4×7nÍ\æõ« vûÙÿ!€Ýë‹Ñ°ïUmmä<’=–—IâßR:|U]®›sL{ʬ¦Â®5á.¦6¥|§f&wn¯Í/Hl ëW†Í1Gõ®«ñ•áM }$Ïq»ºÑ=–ï‹Á©™Û¤íRôr¶˜>ÿ*¯‚¦•EØ›µ¾†¸ìdô«ÜjÝoZc¼/Öß=Y ¿iÕD˜›µ¾|Œ°ªÒÌg/=ï5{•è]ìçÛàŠÏ?L:Ùþ»vüç0˜»Ÿè'®»4/Fo¬I­1µ"}Rƒ|U[[x_»È/iþ>\°5¹ÚÎr”—4mÖw©_·ÊÊ;Ë(ï,£¼²ŽòÊ;Ë(ï,£¼²ŽòÊ;Ë(ï,£¼²ŽòÊ;Ë(ï,£¼²ŽòÊ;Ë(ï,£¼²ŽòÊ;Ë(ï,£¼²ŽòÊ;Ë(ï,£¼²Ž÷Ë|ä„dÂ,øº¾ÐÊðþ’î¤Ä/V~´FX U^µ4¶žs³öu"²ÔsDý£á¾oÜÝnšÑik¬Ù"ú¾·Ty½èdþêÑÍk«Éxl½Yæ|i&6y_Ó“Y-II[œJ:v6»0j1ðü¤‚?jÕzÏfíô3Ù¾FaÊ_Š{ÍrPÔaÙå0k’GÀªë]’Ѹ¹÷ãöÁÖ©Ãjé£ÞeÓ z‡Zæ7ŠÇÚmR±3Z_K ÿ|͇z«ko!¡…´–‚À{=n´¶ÉšIÿk«¹•nËwë\Ô¼fÅ+¾?T»ÕMÅíS|˜0` Öèc¨Šëto¥ý—ÌɈ^¢þ kšL]Þ²3ÐsJþ®Å¢cÙµ0º¿e'‚NÆÊÿbxÍ´sŽ`ðˆ‹_˜õ+Þ4_QÃRþÕ³~’=l¯ÆLCÚÞÒÕÏŠXð3Iœ^¬ýmäݾ7»+àÔפ-@=®©-©ümñ»%»—ÿ‹a+®Z#ú’jtædÂ-Ö¯èl½BÚœÕñr’Ëéëpõ²b¨¿_Èž‚ÚÝÖž3‡Ðˆ‡3zÓ³µÉGQõx\ä+¢Ýkä,²}cæ²¾pÆÅ„µ¡0z‹¢2ÀZ¨Œ£9f“å$¹è·Rñ«/ÊYÐz‹ý‹ûEÉ¿I¾ TÂÞÓÑ]Šõ û#j«ÓÙ^8¾³ê&vz³õøYä*Wl]j³Ú º5òÏýc Iˆ]ˆ_­¼ˆà­4¥GîëZfœàîÄ;FA´·Õ6ºêôlñ[`×p•ñÔýcØÿ1©ëà(˜®ÙcéO·Ô¯Ø$ç¡ÁûÙ\6ÑN8ƒøhR¿c—‡[³wù)÷Õn¹ã$MõŒ5+ÀLMÚËå$õ.’ž·gUbnÖðk&n÷Zæ¿Ô©IhØmJôÖGûD¯Q1^ëe~BºÈt1¦2ûü!å¦{AC!k`ô[ìZ;`苪FÊê¢ìMêòŸå¤ÿµ»SG´¯u\¶A£Õ}¹Â¿³ÚŒ"}lÂõeεÚ¸è¾JÙ+{|åwI>½¨¬ÖR¬¯®kAu*°Þ“ë–·ðilÇâòuÓ+ý‰çœØå¥˜ x#´TázÓ´zÖ’Í!E]$KU´÷Y^µÎR?ø‡÷/ìrè'l)ª¿bp–Ìe/SÆÕOgw©ÊZ ¸ ¸Q r½g-4_¡<~ÇC4DñÊ8Xúk‚9}bt_½ÌdâÄÅl<çÕö-SLÇõØ×4ÆÔ‡¨“¼ö+W\dÚ‰d³¿Úë\°Åì ~)ŒïZmE–ºÉÕù ŒâëÌËKÉó3ãåþ ]š3öN‹ålR7°÷–¹.?a5Û;¼pzS¿Ü®SWéhø÷ªÄCm‡ª¥BÚµÓÆÍµ3aö÷­…_ëúUïZ;UJ/FÅPä„›ö•ûÀìÝWëÁf…£ÒMø*ZÁŠ'þö<>ÖWì´žÌZôuùQÏF]c&§N¿²ÅΔۯԴÚg³»ä°fõ®«=¾=ÙRÕ ÃûM¬Ut¬þ¦ÅÖww‘³}î²Á{»§;ÑIOA›Ì?“Ú9Áû%ÖÈaê~yû,´‡ÒKÏtóÄÎPIuzÙWä ß¶•YCì5˜Cÿwø¯ìv·ìc¼Ûçý¡+«å&8öFÚö¯“·M_YÞTi¢“ÖCDö›LšY~³ü•él’„[|.¹vƒÑ×2Õ8ú¯U Ï)Ú¤nŽ7íZk[4²¿¢ùGÔ¯GXëFô_(Þ5Ö¡7د°Ç/{kTrÿdÍ$rD%ªôAuXÅæ²¿ Ø‡réX°õ*±´¤ùD®ëI0¼ÖÙ0Œ=\ëíÜÕWMÞ7ìh´–)ôUênpºç[.ú†5z;a¹ö¶u¢•´6†ô_¯¹_Èÿ'B#ƒ5ÀÇèç ¦ŸM[-¯Òf+µZ­–Š{KŸi´ªúßÛ}ê¾BÓ|~¬Úø¬,¿÷-sŲ5UžI'ö‹R¬.ñ—ÖˆÕß}±ÎÚš üŠÿù 6­¶S NÉ£åÙþ¬íƒªÁl•ƒÔW™|µ®SÆæ«¡¯­êºå±¿ÚñÿÃfþÑ)`ÍÕÞ«o•¥œ»õw+ö+CˆýWç ¥láëjªÛm¤íõ[šÏö/ì¶I ¾°‡Þ¾VÉ0‡m*¯ˆ?ì•Þ ›pÕÏuC³Osö£Ôª2œ¿f¢¹Ö’?jGZž?´—7Åø+‘Öbú±5UélfýfzðZk ú;ØŽ"ÿb”žÙl,Øœí.2Âú¤ˆG+z—‹Tªõ‡©\~†|ž·êe¦9äŠr×A}Cê¢ÐÛ¨øIè’¼!OX­žÒuú’½áWm`ðÖÄ]\±Ž”¾»åq9~^¯û,˜E¨Íƒ"Œò’+%£§‹ëõ+–Ì:§fÔýë§aßváä´ÿå(Ød­ƒ¤ÔÚù·µ++ÅgµÚ¤ž-;CgŠñˆv–µdžžÖöª´PÁMé›W© ³Ä­ÒYß9 MòoZPªø­+Ù§²ë¦ŽÐ,Åñüì=–ù‰IÝÊC $ÜÛWìàÊX†B’=—<¯Qõ©I ¢­â¸ZÛ§«WÃ×à–yŸK%ç»Ø,°Ee‘¿³ÍÎöK± ˜H¤’g©™>»¬¨Í©]}DÚÄ›uÓÆÿè\ëeö™;F:ß|_Âàm«à¨öÒ»êgÚ¹úI_´Í|…¢X½N÷™RÓhy#ú‚×j˜Dh̓7…œÇœØ=kÒy®Ÿ½ê¹‘ˆ{-áùHêí׃­q¹w›®¶ºüž?µ–’Æú"ëÊKF6WŽ_¬OÍdþœ…¬ñ:.öZ¬ñî²æƒ7w‚ŽÕdïÉùgEª×iûd\Ëiÿ¨X•Òµ5ÞÑ jäcFøùX+ÍŒ¾°=«U¦Ÿæ*´wë·T1ÖØbÊãÚ>¬Žô§z¦y Y—kø|bÍF“ÒÀ×äSUPb ;v‘UÕœO¬‰ñwðÒHØ—ÉZåì.rü¬_ÿm“ÈNòÌøÈ^–Îog‘ñ¦¶±~Q÷‚­!»S«¶ˆÊìS³…±|4ŸÁ\`k˜Q9Dçg/ðЉîÔˆ³>·ðaU®ßý,¯ ³û>gj²r²®Ëö+¶È4Gþ Õ¶¡…šÇÕéºÁ5j&9M±eIâÓé"üáçIÔ,<äV™Ûå‹úÙá(OT3½àvôMo4²ëßê2ÃÁ΀ì_“ŠÕgb蘨ƒS«±Ë£Û+kUµLRÿ†<ÑU†¶yWf³¼ÏÔqu¯´·?Ш<8Yßµµ.ƒþçUŠ&íÇȼQо°½ÉÄÌý½iÄÆð¿S«·Jk/U5.qFÿæ7â¯@ϨZ*U’s§“YÝà¡ v:¼ P—lEEª×hÞUŽÕ¤«#ju¡µÅ£•½û9Æ4‚¹;zßȤ‘±÷¯’šx›°ORùKDòz¯Ñ•4]g´·Ô“œË 9mY o]]VÕ)Oû8 ÕÇí¢»ãs<}bï÷¦¢Ø7‚ŽÕex¡.ØŠ‹ådšfì3Ô®´NåÖV7÷Á\²°I4˜0|];—ÊJYÍúÓËd ×4O”•ØìÚ'úò>¦ZCùy¾¹øjp?k²ù8Ä;›Á¬Yû×D;¸AÿÒ¿'uP¿gW䈊Îo‹Æø§-g!c!¾·NÎÕgOd7!8¹ÐÈØÝAf qÅò’»úEÕ_‰ v:¨ƒÆý TU‚ÐEûkgZ;Hø¼‡ƒý«Åì™}9GoRÀh-ábÑÌ9de¢¶ E'ÖôIVô_éÖŠì1ÝÎZª°ð—´ÿ(@ä#Ê.úÝ ‘ïà÷¦fæµ5;ÿ©¶ù\½hµYˆžZx«´Î5æv3öö«5¦ ÛJKpM˜@£!õáEe°EÊ2餞PŽgŠHˆ¿FuV‹õžÜeÌ‘ˆ˜o³³9u½~vË|ÁÄe˜˜uº»ac@j*`M[Ôqëð{ø.{;bΈÎGšRÕ}û?QuëùÊ;U•Sy¦¿!ã<;{Ë)beù¿<»ÙT"~ÑytÛÖ˜A˜Eº›óWÑÆ!_ªß™‹ÕÂAÊc‹+£WwÖDø»ù41cnÇetE…»É¡‹v;*„@/Ú‹»È/iþ>T²IYîË u¼õÔ>¬zû‡L"2x¤×Äu³T¢ú=–ùÃïÝ¡wyí?ÇÊ7°Ú†Íï<2Ť~ºkj)%’BžÑ&i ³©™º›ÊèË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èË‚èˇË|á÷¿îл¼‚öŸãô`{-ó‡Þÿ»Bîò Úδ6»XÅ+µnÑÞë¦ ´ÚÀf¬t©^nÝJÄÍjñÊè°:)´Ö‡èΑ]*W©”¶ßv²ÄìÅ!DmŽZÕŠnm¯¡{¯ÎÕ_‚‚Ö–+<ò41› ë7êõ/ŠÐG-ç„éVõÒˆ ³ZïÊzÄJ2ÝÕehE¢ãÁwH× é{. ìv†šæ¢j8»}ù¨{-ó‡Þÿ»Bîò Ú”$Ú*¹]¤ÒèëÝëOA;5tgÖÝ­ÚÞW+É'%ÚyF;u׌  í¨ip»Ÿ” ’e8ÄÐhlC¤{9V·{—&¢Ï-˜&žÕ?1¿&¼Ír½šÙI†ÛxÜ®tºò¿'JmWôs“á²U¢„g›ÆX†:°Ñ…Þ˜ã©r5’{,·ìÉ#s' ¯Bg¦è¹¢‚m Ö˜¤µ@à÷¢1,ôêjb¥ŽQå˜Ì§•Ú- ø³Ö´wÔ¿£ÅnkL–P.E¡»âÒ~ÖªÓ½r¬Ád´Lì„:8œ¯]}tíVžTñ9¬Voh­pä+Õ­?5e¾pûß÷h]ÞA{Oñò¬V“·5–Íkb ‹BÆ7iQ½ÖüO$Ì"óÆ/@0*¨›ú=–ùÃïÝ¡wyí?ÇÊ„ÂÐþ-÷2Þì.Ï/7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfáä²ß8}ïû´.ï ½§øýË|ÄæˆAÝKÈRG£ç•ê>µ#I!”U¼W [bTõjøzüì-G~Õ•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[yemå•·–VÞY[y;¸6òèøøKÚÎø±Û¬Ãh­4O(ÞØ‚9íPÂg”d‘…Ý4V‹mž _[²°º«koÏÙo™»ac@j*`M[Ôqëù’”ĈG¨¨¢v&ºܹ´P ÔžW Ýø«—íë'¢åÙóŽO]]UfæIòøTpïØ´îîaÔÁ‹­Ã$¯F'q»F¯{ú¾vI´rݸís_üïTa)NýËJÖ•ëBÚ ^Gg-R¬ÛP˜½Dš¬ÿ90\’± ó1îZ}tÑénzTLef”IÊëGÍ«ñ¢gp(ßê•+Ãç‚)IØôw.ÑÝþß½¦…tœ‡¯V,Œ¦†X®Qî½èïJêuW9«vž¯œŠ½&ͫ߱=ð8šë›¶,ÝjíÃqbay+;àÜY 203¸éíNÚüáÊLD"Õ 5]3ÄÒèà‰™Ê¥2Wµ¾rhÇ1ƒ‹UËìñÑÜîܨZó=%cšª£¹ ŽB‘Ÿœõ®ª}¿:Œ‚ñ<•7µkLÑÔFüwD[ÕÚ…Æ8+ÍùïŸ:ÐÇ£v) ¤©¸ó]ÝèÚ“ètC%ÆaÊ/ßü&!–;Õg‘ÞýqzÝÇìBõ-nîÝ®õùËQÙôzI.ݾøpBÔ¥y¬W¯?mê)¼b+<’ÝÍɋՆ¦FÎÀŠóGPõ7ÎÑ\rÑ]'ëª}%À‘Êñûü‰ÊFˆ*$$yŸ ¦’{Œá®=këáó–rjR3¼û®ßz–Iš!šƒ ›•ÖêjQ=Øh$Ä2úaÚÉ¥ÑÃ19ǘëÔþY{OñòƒÆ¡ÒÙm#go@ÙÊŸýš- šÊæûr=+ö} Ë~ñ Ú”ÀØÅä&gîgdwÜÌÜÉãwîw¡CÙoÞ!{Oñù܃±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYgË~ñ ÚÑŒ./«±d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖCY d5ÖB]úü§š+ÓY[ûÑ¥]»XqvC4¶)¡²ô¥J·­Ço+”m“˳Eq´~0PÚ,ßåõ?jå Ž.O6kH=m²ÊÚ›+2ŒÆÌ6c“•Ì[”´¯]OÑÝõ«OôXjÍi· þAsËe(Âfðr|œ«v’»@¹ƒ¿S.Uƒ’­:X¯A~ îPƒßê/_zµ‹“ÃHô&°Hæ.Ô몰ÿF¯âVÃ’JõÂ<àÛyKh(¹9É­sÎRñŒ_Ár94-É· –GµŒŽOif®«½­ŠacŽÓ=¢Í=-vKI>—šïò±¾ ’lܳ#¹0’K€GÖýë‘ZÇ99Ehµxœ’=o€ÒŒþ§ÁrÕ§FP¹Úªñ–"÷Z­ù—[÷2Ê[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)n¿ƒZÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÊ[®²–묥ºë)nºÀ·_˲Ùb€GDÚ„äg)}nÚ+]šQñ†´ã•˜¡¾Ù6yC4ÖH%˜rÈq³“}©ç““ì§;½t…¹W½ÿ»õ‰ûßÊÑEÙïŽ`.§ep5»½ã7ÄË­ßèPö[õ„;Gß÷~±´ÿô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–ó¯Ky×¥¼ëÒÞuéo:ô·z[ν-ç^–óùì·€Æ~NåŒ]‡OLñ»¿cÕž'j±]*]µÇqß•,óÈ£2*VŒ¬Ú µµæœš J³¿‘a³È&çk“F[S?¯È·=˜N×5îÉ cνØÕ@n“3Ü,[ÕúœΣïû¼Z  svu+3Éc·Ù!´; v‹D4ÝðÖÏå9>¦mn£µYIšÄ¨í]¾]šÎÖidoVanltíðø†“û^M££å­+_ÔâöŸãô`{-àú˜¿Ü¹Íhg(J ¯ µïV¥ÊÍ1Ø#hÀí6· ­2å Ó‰rL&M}Úñv½"Ç5²ÑÍ0µ–Û!NÌú¹ÍجÖ‘€­§†Km «ké:Ã^ –ìðÊÑØã¶B%â²9„Q–k¯Ø¹^MåþÄò•š3sŠ­×ë}«úâL攎ã×å4MZ å!´—ÿå3N‘ô—¯ÒåÞÊ/ét¶‘"89ñÐݘKGŠkLFOkñ6{í› o±Eÿ«'ÒI$—¦f–õ^î$ÝN­Ö2œ×ãŽÚ óúJà¹~Ój—Å^YßSÜÆo©r-ºÈ1Àv›c1Ž<¶ƒ}wÛ /é€G¦;ÃלÁNÎÄPòì×,ðØ +(É%ÁÉÎ&õÕEc·¼’¥ªDìF …W.Xcwñk=ª‘½n50ýLçQ÷ýÞQÿ§“ý®¿£v>Q;<\9Ù!¿VÊ%^ÕËRڞϺ+A V‰í¯ÀÞЦho顇Cdˆ¬õ•ÀkNqê¿¢–‰¤hàM¥žY¯ ¯é¶9oY¥·YÂYî¶Ž^wSz×+EfµÙ¹2ÆV:Y­EhhʹðÔ‹“NÍ ”ö2w’Åjy"–d=N¹8aµY¬ÒÉhm8JnÁ3ëæ¶—(Y ³ø¾‚V¼>šmè?Ü¿¤rÚ­>P†×1YþUÄ…ú®·z‚>VŠ™¬Gkµ=œo;s‹ oUý³Û§ñ¸Èm ~9ž-ƒ^ÕÜ‚[GK S^eoäû‡âObiÞ)Qä­/b¿¢¥!¹—‹ÚÚ¥êg_ÑÎT†øÛŠÕ<·ß+“ó{—ôÆÍ4á í2݈ŸœUÂŒ¹8äŽ6¹.9c¾ô½6¦oµCl¿f‡•ÞÓδËm--ëÙ:aêýM/iþ>QAf„íS±´m©Ú;Õjµê> ­ÐÁi„ì³¹¼o©Þ;Õz5ê6-­¾…e¼'„& Öìƒyª‚rˆ `j Ž<áîu¥šÇ²»]¾q3½;*¯ÅgŠ3¸ÑÞf{½Mܼ]ìVw³Öö‰âkµîCf;$g!xÚã}ŠFŽÍ m&£º ×»Ñ šÍ œKŠ6}Š7ŠÇgãw q‰šë¾.ËÆ¼Rý6¯íSÒÏiú^c|§µÚ†(ã⣵™ Ga³FBWÙÆ!jjä°ÙŒäÎE»—z’Xá’J_19w«ãa³ _Ò^hF·»{ÑÉ%’ $1¸FQ³¹c¨Æ{ yHÙØ{”R<1¼‘jŒîµC»±HqÄœxÈFŽOëýLçQ÷ýÞ0&£‰6§Cf;,%g±Ó£·ÆÆGò±55½pÖ¥`²Â .£a¹ýý¨‚Ïe†,Ãl,èžÍe†Îå›E v)cñ+>ŽW½ 蚆þ¾Õ£³ÃýHÅ…•¡ç­‡%¤í RBÕŽ÷S!kUšKPb¦Õ è"¿ R2¸ÕîÅ£ž ˜+[² æO>†=3Ç’ï9Dzª&$¢ghés+;px¬:žðG£k¢ý¬È¥–Çg–R®g;»v(\¬Ð“ÁÑ;ƒ|Ÿwbñ¯ƒÆM£kûSKÚ•héÿ¬4¡ãkto\»ÍûÕŸ§þ°ÒŸŠtu­ íûÜÜ>ß¡CÙoÖîuÝúÄ^Óü|¢žÍ1Ùgsi[¼wªÕ{µl[S¡žÓ1Ú§cy[´wªô{µ|S} ËyZ@¹qºœêÿü{Ýmu}¿ªáÜê>ÿ»ËxÙÁ€dÑЄµÿ«îD†²aá!wf¬ïGSÖ)¡j‘5)ñW^ZKÌ:=Uׇ_©èä Õ£:±ëýW/iþ?F²ÞSü¬€Ä×HEõÎÄÎòI£gbÑW›VÁ1ß7wqò‹º2w.{ƒ¿ú^¬Œt’›»“55×½“ `Ú¿Uƒ¹Ô}ÿw—~ù°¹1¼z®¹v¦‘å’K®î"O¨j­LϺÝ_)$’KÌWŠX6µ3—2ý?Ôõ¡©]˜S¯èöŸãô`{-ú£bޝG«Îï̹Ô}ÿwæh$i4fàTêÃ%®’Й€ŸîA,oz3kÂý­á{+HÞ0Á¤põ|áË!]Œñ?©‘½à6¼/ÚÞQÏ1\ˆ®H%ˆØã&«#šshâ IÐM ´‘U‰•_ÀzHðÙ¦D^Eýi_’ŠØ61ì»Gb}®ß˜OËù;%¨lÿûxò#{TÍ÷ Õ1 ± ëgo˜·°rluŽŸ¥Æ¿e(¡´à& }Ú–šÍ+KiVüȽ§øýË~¨Ù‹¨n×̹Ô}ÿwÏ0hÎyi|‚&Êdê{H½XbsgíÔ¹=° u‘¯˜Úþ­6ް ]ýJÍ ça©ûO­ÔÖÿ h’?ÅI4@Œ\i€^7gºQ–"êS|'·I{Fíý¾H‘±›ÝŽ ÖFþ¥¦pvwŒ±l[È;A ÉJ3âîïEѽBAbe=v‰ã‹þïà‚7Æ8¶?„Œž‚-Wu§ŒH´ºX·ƒ“¬¸é­#y»Duºš;=í– ^ücë‰úÛ¹BV«)Y,6w¿£‘õÊ}_c+uƒ¥þÓwæâ­¦ØèîíÕ÷®P°þ‚j³z‰«ø ²DôšØm w>*;_%DÄZ= V—›Ñ± ®X…¤rý«Õu‹k5Ó6ga–QËp¯Ò”e+¹]` ]xëIýšíûÈãÑIg•šû­¬ƒ¨Xn‘;½Ò•²>åM3á9ìOk’xŠ^÷}m÷+Õ«”m^þ¿ ´ÌXà³FÖqgÁÝõ—à­|”õxãùhþ£õ}Žªø'{'Z-p3ѦL]ÊJÄVyb+§âÉ¢(d•˜oÊqµtm\] ƒ±5YÛ¯Á,Å–1s± ÊÜûS”Òzï6í%;Øî×ÁEslÖÈ®³~ؘ9 çRy£Ž…véãêáO™/iþ?F²ßª._RX0çQ÷ýß;5¦L±{ýJyíšív欟²Ï€¦ûêµ›þê|-g&ŽÑg&8H°«v¨Bß5™ì¢ld0³Ô©ƒx9f§ •¾ÖÖ£³6kTÁà¹KÑŽ{7Œ´-Gea*P¬ÅÿmïæðÃe²ÉnŸ#Ýdê9Ý®?T›hå99ÑÆO ™»¬¾Õiƒí€Ó´Ú‹ñðY ²4ek´°érÑš®¤Cj„®MÕuÉ6¯h¿ºÕV‹#ãdœânêÕ—"ÁÛ;ɺ˕àú¶§=å9؊˘$xÇJÎîôÅÑZe+ÑÄ׌Š®ÝhʯŒ°€zïÊVAÕ#ý4‚=Á{#8E!õ±•iðâ¹:?ÐÅ$»y¾MåÕ¢›G'°ZY¡ý=ª8øÿk©ìÃ.Ǻˆ±†ÁÖÿ0¿‡‚xIÖ\ž05ûtÀÐĶÔîýÊÑb®’iEÈäNLkµYf|î/iµ?‡“!êŒ$™öQ“ÄÓÓ’JM1Y©®÷gr†Ód‘ ¶Áµ;v:–ái-1›ZJWÄŽºÝƒ”šó#+A,¾³ú—ZJÉ5ž7gb½ORb¨¾¶u%›“! ν1ËzÕœ,ïtíÒ 4묹FÎÚ€£ŽAo²êŠÈÂÏgæÇ!õ±•nü<Ù£(Ämþ‹–Vò‹ÚÑì·êµû%‚ó†UÓi ÌÅèîû~ÿw:¿îùÛ'ãÖÓ3z›/òoWµ³ý7kñòS&íg¿Öürlq˜È1Îw^¾¦Q4÷¾L¯3îuj›YFôo_R²Xì“” 0Œ–™ãÅž™Yyâßÿò)'yeµZ ¨òÎUzv.X³ŽkE&³7i§â¬öfþìhýýjì¯Ke˜¯Å^¾ÑûS˜3„¡Í’"Ì¿fËfÿ¸ŸðVIÛP[ᓽµ³®NÐÃ$›u+lX ª!˜{ÛS«þ†Îrmz.\“©à ÛìgecÅÂûýºþô@MQ&£²äÞI=gcµ²ÅÿîPTöRµž«•f’Ñ9Ëû9~ {ež8¾ÜÄÞd}z;ÍÞÚ×ôs­ä-3ÿ¤U†Þz¢`’3²ó|šV¤ö“yÏíþm#|ä7{·ßTlïWaìðJp[ívP¯¼q5Kɶù¯5øg‘é¤Å>ŽA:}Wª¶Ÿè,á×½ášÂ@pÚ¬\™fzr‰¶„ÿÁz9:žÃ jÑ=;\»v«$ÕÖQµ{úÓ3O»õ17ƒ’ìþŒLv‚ø–ÜüØg™ûu0A(I<ß$%­Üµ(,ã„`Ãàä‰þ­­ƒyrl_¡ŠIŸíÕàäÞP|‘F}ÄÊ>’ZÊ_êÖ¬²z6¨ /´u¯éã@hC¼Z¿ý^yBBÿKUü3BøH;Sþ™‡Å©ë­ß‚†Â0`عZÞ‘Þñ˜‡¬¯bÍö©9BÙùm§ýõ –Ë ¸ºŠÅ?•XžÊ1ö;z]ÔM =ó~t’>&]nŠÜ˜Þ¯£¯1‰ñ*v«þžÎqlç.W·ŽÒÆþ v§Þ¼aÞ‘\ÒWÕJ«}´µOi?îf}\=¦–Q¼°NPò½¬§¨´…Qwõ¨­ºO¨‡°ºü%í?ÇèÀö[õG”ŸüXþhŒÞ‚-Wt2±&«+O°ì­Qö\}£áçQ÷ýß;Êö®Ãû›_­1Ó0Ü¿×NÏ FÓÌÂõkÈžÍBåß  BOyØ[¯Ã²D'$ZÀ²øC•¬qÞ1æÚ"ïñenåËj–^°M÷¨íCšË0MÇø«T­­¢²„{^ò‚ÝdÖ»)^aúãÖ*Õo!Œ f6£³âMðQ4LîöȼV­ÕÏbø^B#©™¨Þ´4bÓ“]y)­ÙY­ñ³¹ÙÈ›Wí >4Vk?¤ÎïëDÐÆ1±›°õ¿‘â¦Ïw“†F~Ãz ¦ âAžõ ºü±kL5Ü/u ·ò\'‡ÿ»ç-²vDTÇÙ×¾ŸªV'úÖs>öŸãô`{-ú…¸]¸øC¹Ô}ÿwÎh帪~©r3ýa™¿íð—´ÿ£Ùo£|^÷ÊݽDÚ.”ŸWsktÄØ>¿.®¥y¤ÇÃæÉÿKŸýïóöÏ[È öà¬"$ì×êJi:Ä]ÐiôƒQ'*ØZÐJÞßãUY[¶Ð ¬¶6ááçQ÷ýß8@¸WÆó`ý¿ª|†]w¥oû|%í?ÇèÀö[èG’GÕêÅÓ“ ³Ýq,YüFL"Ø»ùSÛE8 ¿ìÒŽˆ1h¬å´µ+;þÃ7†I%´¥æ­;<6‚쌾 aíŽ"ÿ·æˆ»ªÁûPÆ¿?3õ8Hÿfÿ,~ Oðàbÿ½NíÖÍñVØ~¬•ÚÞP—×".+”öÙø+ õë“‹ö‰¸xC¹Ô}ÿwêÿ#?øïðð—´ÿ£Ùož) î€ëwVy¥»žRº1Ó^Ÿæ¥wþüt­¼íø|Ä1ž2½ÃGèì­ÿs«l}DÃ#x ƒô²3?r³Ÿ]ÆSSk›u+š"xŸìðò€¿÷³–K@ÒS ÓÔÍE}Z· ­ÖT®¦ÑÌcÇÃhöUÞÛ0xRÀZ¨^K$±DïKåÕåÚ²2ø.FõÄ_íðU_„ï7Í»ª†z³–Ë”¿füT?¶à­õÀ É»ÝYýš®Qoòþ “ÛüZðVÿ›ÂΣïû¿Wù!ú¼p|%í?ÇèÀö[Êâas¯?gxΕºÚ7ëë×yHB x˜Aá&w§íVŽˆ4RÛµ!¥9Øu¡mšGw6º¾ß“ŽŒ„œH{Áe²õHwÙeýIøüÌåÖÀë’¿jgÙ_˜‘ÇacnûÿÁ16ÕðI;ã4„j7úð¸ì„~­ò}‰ÃôfCÅYƒëN êßUæ6û[ÂÅõˆ‹‚ÐRso œ~´àÊÞâÞÚÞ»^Å®Ïw€Cô’ñSEõ…ÙC#ãw_•hö—$¿Õ{¼<»cvîÝJÍ(ê >FO»ææ(äbºÎÎì¿ÂugöW,û -ºë’Û¶Hª›°¬ÿO^a{®­?庳·dmðVÏX äþó~ Ë >[Hjð‡s¨ûþï. {š9 Œ×ýØ}‰ ’å õµ>×Íö)ëŽÐµH𔸫¯ ­%æªëïԄtrêÑÎXõþªr[õ5¾'~>öŸãô`{-å>Ô@uwp ƒ^¤Ò²×r'Ô/ñFNåÏpwÿKÕ‘Ž’Awrf¦º÷²alR0ô-#}½¦ÇÁ1uAÚúÔþª?óÐo+þ'>‡¬Ýº»É^Áü/¢”N˜ÑÓ“àÚÑ„¤ï¤8תªVlJ‚ÛW'“z30mòE¡¦šB`¡’—KÇðr«† ÛÿbŠrë»FûTV[´k—ÿjš×'ÉûD;[À?±x«pvNïµrx~Û–ÆMÙ,^B»x®·“?®ÅX_êÚ¼GúI„T®Ù†„ÈI½&¯‚’(Æô®ØµS½Eõ³¡&b,·Ãäo ´F#ÔÔÃïðHãÒ0{Ýsz)`xßÛfÔê ~¨™¸+?wÞ¹SÖn<#·íü€¾µñàßS2' Â㈖*clÔ£w£³ö³S©þÆâ„{Šo\,üUž˜Ü>:”º"vg§Ölÿ»Ë¾òÈázþмÚüP›Ë$—jà&ú†ªÔÀüùÛ­Õò’I$¼Åx©ÕƒaëQ“9s/ÓýOWýT±¿SZãwÛá/iþ?F²ß9¤5”Åöu«ÕÕT–£gwžG&fDZ™NA­ž7V1|%ѱwbéˆ^¢èŠÍh’ÍyëuµŽÅò(÷²•Ç3µÖûPM !´BÜÒoKÕëRLØÉ…ÕwBû5+,dôm#w2Ò14f%«¿È{3ʳUX£ú·ÔÐú¶”{úüóÿîÅ$_¢”Y ê#¾]¯·K]+w«%¡°€¼Çú€÷«xöÜ&ج­õ#"û•–N¸ªïÜú¼‡ÿ ¾ ‡FÂ,î}´DO85´\£(êy#Œƒ½Ú‰ ê8þÖQÄfÌrenÕ`oªÆ\·gÿä¤ñm ƒe­I»Tó[škC\awYX{o³lª°÷Sƒ·‚Ãܤ‹ôfíö)nàqëïe/^Œ‹WoR†GÅÇ_z6Ž9-3¼m¨~Ô&/Q&«?€ëÊ-Å }Yøø9>?ÛrØËD>›=îågØfðZçþëHÀmÚØ#±¿D\ø~öV«Xÿé]†?±ùÈI°vª•Û3µÖûUžvw¨»;7vóÖ„›j²³ÀÚÆ•>þ¤ñÊ7Áú¼·eï‹«Y}kA®Iªò«<ýQJÎ]ÈÄsIHÛíQZ`äf€8»u(ìÇ wÉÏ®JÈ_¤½Cé&ð7®ÍÿÉYƒöù.s3õëð‡s¨ûþïÕð~¦ž7}¾öŸãô`{-ó’Ù_¡žç©û—¦Á¢ûpV7èÆóýŒŽ/îíûË’¢õkÛE<†qîWFArìªå¿mk+O©žM#÷ ’yvŒ_«Ö£³ÿõ ÙZ«¢W ˆ ±ÙO,‡¥:ݾŒ£j t™»zB³¯½|¬ Øî‰Â]!õ 3ëtÒ«ÈÒÔ¾õ4•æÅ 5{õ¦·kæŸ0e16¶}jCý$¦\U¢'Ë34£÷«I7÷q´MÞHG±¨¤(ÉÀuT:“kUrÿ‹wc&«Ñ¥†îΤ/© ×VÊáM&ŠÕPN®å9FLlíJ‹ö ý­~ 9»üœ\ÓnÚ>¯Š°KÕRþÖV²£»2oF†^¯½µÔS=hQÕºª¡0o•Ÿø²’_î®Ü½Af|ZrÕ³ñub“üFn(b)¤,ªÁŽ¿3¶2‡7ÚÁX;®¿üûT‚úØc»Ãø¢°ÆÿÚJGõ7[üSB-Ìf§z– ž.n.ïÙÔ‹DU»ÚÔV:àÓ1ìSÆq”Nãxk×GB]­U~Š-®­¥Õw[â®ýC!âßS^ÆWQ€Œž7-•ÓY¤€€˜ò;õº‰Ÿ0sìPY[çüîEmKDðéµ ¿RqÒß´È÷Ý©WW‰Ø[µü?VBn)‹ë™?£ýËñG`MEd³Ú>L¬ïzG,™]û8êoÚ$.YÛQw« ìW'¸ôꪀqh>XþåÈNú|Õê%g­2ÿ,ïü|€îuÝú¿#õ1…w›Â^Óü~Œe¾qÁþÇìMg´s"Óiœ»T³‹Ô˜ÐÊØÆLI™Æ€®÷UßïBò h®Ü`ìqÅ“9=\᣿­‰\þî6¸ÿð9Õ´@oQý¦Ã✟3à,€:Û@X:–8ÌO_=¸²Ò=N´6ˆÍÜ5 [)m3•¦o@´ìe5öùI‰Ô£4Œ T}z¿‚,°Jw™ÛHíAevëðJÝtªñ‹-£E¥çTj¥´_2z^íðêÕ ëõ¦{@\Œ}×íWK4oqÕ¨J®úbqaj ½P¸4ÔýªÓ#ÂG)j£q_’5{tŒ¯ÏI¥|]ðTf£)bˆ^ìÏzÿÕíZ{ƒ(ó_°‡­47ÞSwÒO#õö2wÁÏeÉö·zEÏ«ýŠÑi6¥ÿ¿ÈçQ÷ýß«öÏô½¼%í?ÇèÀö[çÈÒj+ÄÚâ Ûá#³‹±ÌmG~¢e3Vñ39v»ëâ-S–z×i¾bíù—až@ å¤À7‘7°èOê‹ðQ}¿!«Q&ÖÄØ²ÒHo4˜Uú¼##¾¦Ä{T­õZ}L-åÔZ ŠQÔ4lȈúS{ÅàŒK+ÈÌýÊp­ë´kÏ×ÚœIªÏÔ£Ui5Ò·®uWµLßXÔ¯õcfðQÚ­ëUÀ_µ™z”r8³¸Ž(He(ÊA©u³Õ0¶ áñ1gvy_ ©€Z‚ÞM 4ÔxûúÐÇuž­å‹…4€÷†¨œžô†õ'ðÙ]¼¦¿Ÿ&õ#î&Pû-ó#늜U­ÿi›‡ÍýZ?h.Ù_È\Tâ­eëá䟩‰¸ nÁošg¦¶üÀ;Gß÷~¯ÛËP–?{Oñú0=–üÎ_Ú1}gwãù•¡»$§ÁFÝ‚ß3e~Ö&V—ÿþhÃë5‰fëò,¯ÚÄÊÒ_â¿“8‹wçaÜê>ÿ»õ~ÝþS«#¾:!øx ÚÑì·æwÿÁ% ~ÏæVˆÿÇûŸðù«)~ÝÖ7Ÿ²—íÑ^úÄïÇÉ(ûm‡s¨ûþïÏÎGÀZª@”¯P¶µ~†’Oª5D=é#z;¿æÏx«×´g‚ßþAü…û`öø ÚÑì·æqÝj½\6ª~e/7ä´¸úëü|&"lNBf|<‡ˆ¦£³Òõ9µïLìõgëogõ$Qmùñ?¨bJÎH1‘¶¦'¥|—Û¿ÿoæóLÙ™¹½ýJ-¥í½4;ënçð‡s¨ûþïxXþQš®> êz¼†yNë:-Þ¦:¼.ñ›á#f#ÊÞ ã)7gb´Y›Ê£Üè"ý)°)GëÄÅ÷(ìñ=$•ñìnµ,¨\Ûà†î0—‹ÎØ?âbùFj¸¨líýã¿QIÖí­;ÆW™žëù 3ÿêXŸcêùÒ›ì\Î|Áïu,¢:7wq‰³˜bÞ–„ØêuÓÚé ²‘žb¦VSY[%@ûüf÷E±tÆx_­¼.\˜x«@ýpû¼$t[¯Á¦6îë@ψsìD~¢ó·ØþCC{å«wÀfÂGƒxJ6Ò7£áŠÎßÞ—Á å膿±@äú­Cyý¬T‡õEÝX%ú„ÎýÏà·7lþÕ`ÿ§ý­à/iþ?F²ß= 6zxÌåA½ƒ7[¨BÚRÆ–'Áú«á(c˜JQÄ[Ã'‹@v¶9†VûPÈQ&«?ƒBìENŹ±× üÛ‘;¶.ëDsìðõ"£M<@µxÛd¹~ŠÃ)ëAôûY›ãáŠÉÒ{CݽõG­ÓYÄâf¥­1 _“¤~pþ‰ÿÇ…Y}V¢sغÉ4‘?['‡N_©{ZѰò3^!Ñn×^1{ä®ß½êFÏÃ#P®“â/ƒøÍØEµ»ºÒ–S²³ó§êïLBõÖÏ专T]Zc”â†! ?kë^#1߈ڰHXû/á¸ó1ìk¢Ó×]Û´ð0^kï­†ºü‚3zµ]Ór‰ë²낚Ä:‰1 Þj³·‚1„KD¯tÔsŽ«Í‡g€ìö"Ð ãsjÞ~¡EQÑÏÝ’7ô_ÀRHL :ÝÝÂOÍÄI¨þ@é!ÑÙæ'heúÝþ Ÿô“³¿sk ;Gß÷|è[½=+ÈþËêðx×ÿQ¢û)O"QÅÅÝYO¨ëýÈ/3½çêìíR›u¥ Ðþc ‘·_­~E*xÎ2†F×tºÙ[dëdbŽNÖ×ÞˆËj§˜úIžûýÉ»%‹‹(ŵŒ x»ÝYŸë ´TbÑ·ÅYßëÆC÷«xþÃGÁC\Y®ìNOƒkV[Yf–W½ÜX|7èâ®×VÈÛ8HânàíˆKîðÌ^ª.Mý—¹µó B'£âš@z‹øJ*8¿¢ïéwx Ef’Qg¥æRÍjtuƒêІ9uÃÔOëv+Pýað™ýVª‚x¿)¿íW]Új»vz9g>y}¾$EXßîðY`êr¾ÿb¯þ–gÜ/ Œ;e½±YK뉂Í×:¿Ø‹0sìQ·TQ¹}®¹E¾¡9íeÉeÞÛ[È´[[0MVö[Rgl[F¨;èÇìEe›¦úÃÚŒßj 6Õj®•‹Ö«K¦Úˆ{hYŸ±©ß±BߣËn¥l³6m5ÑÿRmsá¡ØŠ@ôÙ™‘ÂÚùš”Rv¶µkfÇD_`ÿ§ý­à/iþ?F²ß8p[ žçE9kÿK­,;7S‘]"õѶXŽÑÆ6¿[©€sÒð÷²†ÒzÞFjâïØÊ扬0–br©ÓÔ€l¢ÑM¸»SIK¦ÜÓÂR\éOäýÐYÙ¹¬4Z8 õÙä(ÝÝr}™äl4òjâŽÏ'Ê<µyOë;¦³±Â šwÖNÝËEm„¥/îä„uIüV‘†Í>kö©BPÑÚ"{¦-ñ^/ Gj´cp:»Ýs¥ŠÂ=€×ÉxÜ6™çš.s´‡V!ëd†±6«-k¦ äášÃgƘHÁhN!ÑõQ©NåxÏÇ,m‹¿H ÷ª6¶#mÕ=£¬í¡ÿIr‡'¶b˜Z.ãþèùXŽ6îêO!Ïâ4És·•ÎP€£vþú6¨:šßýÕ4P׳­üµDÚŽŽ I°Ie{„å«WS¢x$i.½ˆ¥”®€âèm6»e†ëý§DVüTeéš»ÛÖš…öß3ý¨‚ ¥ìÎúÝ×õ=Ò¹¤½üU’ÚÚ£o‘—Ù|<~Ol¯ò³{-Ô®]k”¥ßR““¤Àyðõ‚ñH¦8 ¾gú]L´6‹òÎ>œ!Q/ZÑÚ¬rvM©Ÿí_”žÊôf&Ý¢õVù¾¼îÍÜÊåë†/x ±W É °ÒŒ”mŠÿ(Ns“ÿtHÙKgŠ1ŒL]µ2€Ÿ35×ïmHžI€iÔå­IÊzÚÙ],MØ-Õ±YlÖrqi‡I)"ˆ­Vg“O>¤nõn¾g½HÜoUûŠp°WŸ+ÿyêerë\¥.ú”ÖJ‘3<°“ý^¶ûr”rO_‘ò¸v?z{dМhÀ·Òun†gº´±·mz™_k$,/€ó›½ÊõžR¿#·j³Û[Tgò3}ΆžÐXE?jµ@Ök ½çŽýç‘ÐZ¬„1ZGš÷²˜ö:í±C 'ºòDïÍt.âòHot#IÓÙ ¡µMÌ» õuºñL†‚ýž´á/徎NþÔÔÖ6XµûEü<€îuÝó“ìºKŽŽ¤†^’ÎÚýmÚ«éôœj£ÑQå•èBs¼E hW+Vð[Oö˜62iZºÄ#Ñ{«8õÈCáጮNI u­1~×RYË$~'ø² uó¥~ÁðFQ õgtúï™=Hß­Õ’O«%6£•ñ”ÜÕˆû$»µ[¶gmŠMÄÑ‘^¡³§ŽI!`-Euž´DÁ«FÌãö+LÞ‹ÝØškß'¨ˆ{I°VbúâA÷øl¶¬W˹”gõ$@ÝQG_µÕÆèméØ^ ꋺ³Ý{³1zÔ²¿6Pk¤=„¢­›_„ëÄíÅÝg³Fì]uA˜æ=m\»Q .ÌäÑ8ö=S `Ú‘hÎä2½eÃÈsÑ»!&ÁÚªbêˆ6ëEµD•À–"ÁÍž©ïjÄÙ»UœFr#jœE}›µ4‘½EÔmú8œ¶«h>¡bÒmSZ‹ûâæû-‚´‹cË©†Ï(Fýx+ý<ío{Oñú0=–ùÊ17¯Èy„]ÏѼúƒ»Ã$á “YíÆ&«‰ö¨$’ÎV{4<öi3ujðK£•£³Z)¦úÚ»;ÐÆ t¨Íäµ®Æ $„:3zW±ÓÞ{ó›Þû_Âíb·âј13w+ÖÙŽØ~¾h·ØËòPM@À ÔÞŒµ‰5uÚ þÎ-Öåèðø(áëfç?kõ¨­$?+å´²À'#j«¨mÑØz9Ø[ÑêtÖ™…ÚÇEz´þQÅ#^j;/k7Ž3ts^¦¯Z’YÏKj›Y—ÜÞä…Ø-0½èÉþ Yg§ŒLWÎ]à»,c öU~IêkLAvÇ#]”~§P1f&¾ÿn¿&Óa³3Í&f§4ñLÞ.ÿXÚ®þ Ú7‘êTNÏ­ †W»`ˆ³3ó¥n¦L"×Eµ37€Fp¾ÂõdÌÍFl¼!F$a”°ð”R5à&£²vˆu¾&ZÝü' P6¢i­r´Åèâ§Sv÷ø^ÑbxØ¥²4˜z‰8ÞÒHOxäIü€îuÝó—?HB<| åxIµT_«±}£EõYâ§ú”‘ýfQ¹1Ò„Îýh¤ý)‘¢ÁÚŽ´aWë«âè,ÝQÌR}”ÕñònŸ{;bÉîÔˆµ‘–/ä»ÍÕÔþjën¯ àMDz´uûLù¥7'LÕÖøx%¾÷c”oÕû[-­õ1óA¿gÁã17É?J ñV™…ï4Ù1›–vgÔ]ê©”&oBæúÔíû5C/SäÓ7Jǧ⢳ÆmtèRpo˜v}lêàUÚµ×àww£7[ødŠÌÍ[5™æ“×û?¦æ³ ‚ÝŠÁÿOû[À^Óü~Œe¾b+š‰ÄY›œØþƒE!Ý»RS‡ZÑI¤wqÑók«íðR«2̳,Ë2̳,Ë2̳,Ë2̳,Ë2̳,Ë2̳,Ë2kS‹<ìÔ¼³,Ë2̳,Ë2̳,Ve™fY–e™fY–e™fY–e™fTw«w,Ë2̳,Ë2̳,Ë2̳,Ë2̳,Ë2̳,Ë2̳,Ë2̳,Ë2ÔþîuÝóÜÑZ+q™µ^¾ÝJzÅ#´-R&¥>*ëÃ+Iy‡Gªºðëõ!z´s§V=i¦µ“ lMGq®µù_»?Á~WîÏð_•û³üÜ´°Õêôˆÿù_»?Á9¢äø¾ˆÿÂ6ª3jfÑà¿+÷gø/ÊýÙþ Iã-~”½¢?Á~WîÏð_•û³üå~ìÿù_»?Á~WîÏð_•û³üå~ìÿù_»?Á~WîÏð_•û³üå~ìÿâVª‹êvÑŸà™šÕFlD‚ü¯ÝŸà¿+÷gø/ÊýÙþ ò¿v‚ü¯ÝŸàœNÕx_Ñà˜FÕFn¦ˆÿâV«Âø³Ä‚aUÑn¦ˆÿù_»?Á0¦è·SD‚ü¯ÝŸà£´03ëÕþÝ­Ùtí%믲‹ò¿v‚ü¯ÝŸà¿+÷gø"ÐJö‰½š2ç>Å* ”¼¨Å¤œ~¸¾!ö-+”‘òtC@ô\Íñ±=•&qš' Êâ不_•û³üå~ìÿù_»?ÁY${M¥õGFZßb‡”c3žØÏ[Xþ‘Ÿ‹ò¿v_‚ü¯ÝŸà¿+÷gø+T6ÓiV§jW¦9,†×mM­õþ‘OÊ™Ùíù~› ¨FÛ#Ù­cªHÜ SìM¤´1Ó[V#üå~èÿù_»?Áx§%ÊòZ&æ¹ÜvÑYkA3I!òt¢Á5jW ë}«ò¿v‚ü¯ÝŸà§·Lgabmmq¾·Ú ä÷³Êß–žfênõk…Þ¶YÜ ê ­z…©ÑŸàŠ‚áÉQe£8éO·ìObåIœd‹PKqßHN¿+÷gø/ÊýÙþ ò¿v‚ü¯ÝŸà¿+÷gø/ÊýÙþ ò¿v‚ü¯ÝŸà¿+÷gø(ìð™?&GΘèã¤~¡RX­²“Y[]šWg~oÕûå~ìÿm·Iÿ«“šÎßݶ¡VŽK¶Í£prê.÷ð~*ÁÿOû[À^Óü~Œe¾aŽù¸‹»Œo”]Ñ“¹sÜÿÒõdc¤DÝÜ™©®½ì˜[Õár'aÖîèFøÞ&«5qeS&w§9Ö‹H\n^׳Èr2aÅÝ0^kÎÕ»]tM|˜jôj¾.´:hôߣ¼×¶yFLØ»º¹y¯Ò·k®‰¡y£i_ÐrjìEÈ â ZÛȼdÂÝ®êåæ¿JÝ®µ¡y£Ó~Žó^Øž0š3‘±&wo!ÆøÞf¼í^¥z)Aíª! DFC‹ ³Ñ4 èß®¯ Eɘ‹®(š9Üs0•h´Z@Òãrö½‰ã £9gvòˆ™œµ3;âˆP#ÂÅ­•ËÍ~•»]tUŠ@‘°¨=|&b,ßBæa*Ñ9‹8µç«àÝ©ÞBVn°*ù7Æó5çjõ+ÑH2h=QÊc˜Xµ²wŠ@‘›SÜ*ùÎcQj»WWâ1{AêÊJMèóó²÷§xe YºÀ«ä¼€×3Uò÷¦0&0|^¬‰ãš3¹šéVŠôR ƒÚVò ÞPf Îå—½11àLú‘˜Ïf&6£+ÑHh=|!Üê>ÿ»æ˜Ì˜kp¯bµ0?>vëu|¤’I/1^*u`ØzÔdÎ\ËôÿSÕü†&b|ºÝT ‰°Ôè†øÞ«µpW¢dÐzù šûµn×Z¼Ä=¬èë 6ªzò÷«ÐÊh|‹—šý+vºè¯±‹‡ÖgÔˆÂxŒ1 µ1ÆL`ø½[ȹy¯Ò·k®‹HÆ::Výu"•­°½[È7y˜3;–^ôÆÆ/3êM!MÆú˜œšä™ ÂBw,1 1 à섎щåw6£ª¶¶òÊxÄ )959™0bDôdҔѴO¹5WÈ)£a<®äÜîäç!ˆ zDôdvˆ€O+‘³UUµø\‰ØEµ»º)Aˆò³–nåzY1í7¢9£<®åädÂ-‹ºÊPc,¢å­Õéd‡´Þˆt“Çì·š¾A{Oñú0=–ùé…Âÿ5èÔ®µe=½ ==J'£ŽåÈÞG¨½Z½Oÿ*Ž-éJÒ2±ÝæÓW_v¯"Ð74qèÔ®º 6†µ³›¶ªåÕUŒ `Á¾õsW©;E¦çËS™JbÅü|‹@ÜÒǺԮº'6†õè Šî«Ï«USè´÷ŒÆ áXݨÌüï⬱褊C#7T×××Z·ÿ'|™ÙÇU]µ©‰¡¼Ç»¼ÛÏ^ÔZ-=NFs™J6»ßÅ4a¦x¹Îm4tºõê~¾>Dò<q¼ë¡[úø©e&1ÝÄ£!§ckmh^RèØÜ#hèZêÚõ ²èEÙV8Q¾Í{ȲJÑÕÙÞ¦ÍÕuÔ¯âòƒ z8áxÊ>o{£‹DzB´ŒŒwu]Õ×Ý©4a¦x¹Îm4tºõê~¾>E’F Éš˜5×Gò€Æ$Ç£ ½ÚõRh¢¡˜…ýo«UT²Œgz1x]«ëò,r4u!7©SºJJA(0FQÇŒ‚­×¯Ö­ˆ˜d³Ðž6ÖÿÅKyä8š—P¸^½To"y8ÞuЭý|QJQɤ3qq ¹Ù*­RBãǼD5®/Z'"8£h˜9ãw_ðò-R=Î7„]Ø·Þ¯µiJ3yKÄ×H.jõÒªvÐÍŒEFи½Þ·ÖÔû·žC‰©på …ëÕFò-²x³˜ÞÅÿû¡-ÈNDDî.ßÔêbŽ9\4cÌ’;·hY·UU¦fÎë5ñ»Wnº?üÕä[ ¬®m¥ñ{­¯RÑÏÏr¨¸k|Zë«Q]´hˆµÇt†•ššÔ—ÜÈX¹… ]'nïw:¿îùû<š:ê&"§ÅPa¥ÙdqôXu½­Ž!r’¼@n÷Þ¯«ù©O0d"<ñq«µzŸìò"=;Ÿä„cwfæ¶½]X«±›èËœMvºêíuûTÓ0O_'¬cçUõÝvîêU–µ¼ôr®íÕVò-†ÖW6Ò‰x½ÖשGP)/_ss«ãÍuœ&ñ°ÊF7zT»;”zˆA™ÛȵY\¾]ž1ÝõÝmz¾ÕºkC¥³™±@ñ‹;õ¾=•Ô¢Öb Ïßá´ Í#Üz5+®Š84R =Ò’F„ž´ÁªÌŸä掤T–1ÒüqP´ñÎÐÝï úŸ±5qð—´ÿ£ÙoÖîuÝúÄ^Óü~Œe¿XC¹Ô}ÿwë{Oñú0=–ýaçQ÷ý߬Eí?ÇèÀö[ç&w»8ˆõ)£‘Üš7k®ÿ,u{Üzúµ}ªëQÝÉ®û?òª{š9º›Ô¤“Bî.Í#z>µÊ6=²Æ!p{LºC}ozAz½îÆV“ &’ÂGý™ç72v¦·«ë£¾ ÌÂV0IÌX‰î\'Öüíu§©X­"³Yä…ŽIN#0½]cQÉÞþ3w¯ÁTõ»=*¤/•¾Æ×)[”ø+òUÀŽŒí+êÿJ‡åÉæ&ÃÚõ© é|/wj\ör Ãu»¿ÃF«“5òŒ…ºú.\ºíMnœîs\›äÉ®ý½hšð1]gaõ÷ª;àcZ{.†£Í&¯FMwí||IvmKJ2“ëU˜HA_¶Šìz[ï»é>·ª¿ý”íH,ѱVjÖ¿jœ˜…Ú0vvÇ;MÚ™SÜš=ZJ»9096ªu7zwq`Žù3³×¯ðWÎá^¥.³ê¯ÅјœîÞ(ÜZ”® &¼,Üö&fÆŽ«­ÝÀ)‰bîŠûQÙé[®5ûèàîuÝó–©áéDuzµÒ«Æcië[õÖ¢˜šéœLnÝEd¬r\jní¯Wz‘¯KFvm)zýj~tr”¬„ý]ê™ê?(ò^¦¿¹5ÙJùŸSzÝh9µÍ_ÙüQ³Ým4©Ú§·H2Í`‚!wmòBAJ¹=ÁÔ]Xö+<#ÊqYc²Úc#Ó0”ŽøÕ¾«7õ&!ñ¹n3¿‹XæÑ¿mjØw¨­‚aiµ4CÎ6z9U™ê­q’Äïg³ŒäO5÷w=YµeÇZ9ìãf;Ig D¯>•ƒ®½WÕª;Nå³Ìñ9Ä."Z™ëJ½1ðF÷XëWe ½Ó*8¨œXŸåPõ©ÆH†àóoÓ­û3‘ÊîýzRüU˜œåç¸Þ¡“¾ Lú:ó4•­>ÕQœh@WB÷Ü¥‘˜G©ÛÖØ¦“¨²÷+¶Óã…®S¼/š‚ñ`-«׫Z²Å ö¸ívƒgwŠ×(ˆF9žë;IX ²<"V‰\æ&awÁ»Ï'‹=”m¾)£{ùî1V¼(¬ŒÅb k=Ëík¯ÙOZ²Zœn<Ñ Ž-ÕVð•ÉÆÙ¨=OªµSYœá`¾5ôuª0£À]»}nŽGyÚGlîÔçz5Ò•¨ìÝ)v÷¦Þ{º=Wß]}_zf­&vj뢓šìñ»_g7=^§u»éu7©ú“0Hñ²Å È‹³;¶Õo±4²MM†˜ÜÈoV­yõõWíQŒ6«Dò ‘Úï脞à]ÁŸ 5ѵ⤳Âð YÚrs"}e©µ·bŠÕ;YL­#´Ä1‰5Âab£ëÖÚýJפ{!”c”®ÆM|Mðnv§j>¾ ô){Oñú0=–ùÍ!Þ :ÈÑB7G∩¬±@L:Á®·r!®R‡R($8Hn8º²žŠC ÆäŽsÈDãÙyÞ¬Þ¤C Ìì_¦œåÙyÞŠèð¹sŸS–e¼v1¹u¥6gÂ×Înÿ ÷¨»ãu0PYi.ó±ÇVŤ»Î­qÕ^åVoJö=jP WÙöºv»Zµ¯U©žµ­\Ö’ï;ulOÍÅ©J½ÔkQ»ö*Ó_kº¼-GïÃÀâMQ}Nίо£¾¥DLéښ޺» Ú±j{Î[Ãuêø²‹ê‰Uõú“ ×jk«×jæ5]ûµÝO«[ºj3ê{ÕwwÖ™é­ËÕvîª3cب<^¿Gs¨ûþïœ 1bj;?ZÓ]šµÑsU: 5TçNsµ=5–)„u 5iû&W®ó«zµLâ4Õui§‰Èõ3ÐÉ˜é…æg¡}¨Q½pÚA×ÖØ&¼111„Æ%ÎÇ[=iêÁ5DÍfffhÛV {M¥¯Äp„LÃ! êr«=1mm©IX³˜HTwÌ4»þÖScuå;篣7ÜÞ ’5Y_‘v—RµhõdçNsµ*® PP 5_çÆ”ª¥ÍTf§r{­J½QN0»H÷Ÿ¤+¢å‹°ÖŒïÚɤŒ9íBÄäïÍn­jLjp»=pÕO½Ih˜oÌö‰&HWu»ÑîáztPhâ» bùÏ©‹ž¹bÀ#ZѼó± ƒ©¤èéÂÎ/ÎÌe­Ý_§:”ªp§5Þ®¨MVÅ_§:”ªq&¨º¥Þ»ÚÝßZ¥ÍTv§z8& $DÔqu£:iW"”ˆˆ›rw«ý¨­øÀHFòxÔ®O6õÒˆü¼‘h¯W«]>( –+æöv³Éò„íJs˜jüÖUúH¯iÄBNsëaÃãô){Oñú0=–ýaçû”}ÿwë{Oñù¦ú ƒJzÖ°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀUãZ±e€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°€¬`+X ÀV°èüÛ}Qf§­Ö¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å€ï,y`;ËÞXòÀw–¼°å”vüÛ}Ë~ñ Ú•!ÿQòT׉ßI!ó‹Öÿ$ë“âŽÏgˆ+t¡†w!Ñu½.5)Õ¯ÂßA²ß¼BöŸãå’r}”Ìž®E»»¡£àÍáo ƒÙoZ`nO;˜Æ ž“_nº&úAj²Ch:”me (âßzšØÀD,t¸Z™ð®­_jxíÁ`i(ÂEQ|¨ÚÔ³µŽ‚~ˆ…œœû™µ¦·½°¢¹Ôë–‰¬¶³þÕ BÖÔ9űnÅÊz.D–ÊOb(†Ñj „Oè3v/èŸö+T*2C+˵ÇѳW¹ôsúªÐÖÆŸò«Ÿ#Kõ¿¹L/Y¤ùv¤nàÿ)òo‡jäÉšÉÊ–{`ØF-=’=%`ãvVOˆ!µ]ç€5¾Ïݱ{Oñò3,ü~ 7Ÿ‚Íô{-ûÄ/iþ?F²ß¼BöŸãô`{-ûÄ/iþ?F²Þg'MŒá›öîÞº_wr±ÛmVYÏKšS³Çòq·{¿ n¤Aj1ŽAŒ¥ê5&g¾ºªµžÓãg³ø¥ÆÒßf«õÓZD7˜]ÝœM¨Bí©ÙÿZ XDNÒD1ƒ™=r{ZAã´Zã+¹@ÌÜŠ9Ïk–üO;°FÎá=/>¿R‚Õ;G04‚ÅG– ¼p,¥9‡ÉV´&g®*Í#´´NvqÔÙ†õzÿeÐZáäûyÆt¹òMÎã©»×%Çe²Ë5žÚ&úMMvŸoWZ²I$Z-2ÄSvXòƒ=/ktN0ÚmA9KTX ¯ÄÚÙõ·Îèäña‹ÆüUìÚü`Z´c~ª#‚YlÑG§’0‡A%óa®[µVGˆ˜i­eg ¥ç&kÙhøêëS[D%†ûI \qe~Hí@xµü*ž ä#Bv–’|ßíe šÖÚC8ÀÜéÖ£©r|þ+ {D’ƒ±µktIõkõ+,³Á,³˜m3ø°Taë}}ý¨L^ð“UŸæÎÙc{.Ž6kÁ8»ë¦ª;(¹:×Zm¤:W+TŒB´×RV-šÕC Z.Ë×0lhÕøÑZNXm6} c-Ùc£˜“ѵö§?žÌìô¹8ÑÿûÙ|VÕh•¡Ó¾€è5§jbžÑˆf’XB£>JkPNO ÐæºÚ6æÕµÕI Ù­e£›ÅÞ@Ž£}Ú¬Øõ«#GÆ'$Ñ͡ϭ1O+Ùíq‹=¨4‘³i±¦µhx¬òM4va´ÓUÛ®ôíBÒYmNmM0€3è´µü*„Åï 5YþzÙj…ä†"1bÂ¬ÉÆk=¤ž6‹K$QÔ͙ۯ֚¶[[Mã- ¸×Øî×µi£²Zå6‘â8>|dØÞ×FÚ¬çV›[ÍšäÔ„;]Ia,š€&ß×ö§¼ô+­v¨î=c®®ÏZñ}#i®ß¹×NÕÉEh”|jÕg§Y=ÆwÕä´ÿ£Ùo*¼ÒTm×)F£ÄâÔggPÁã¢ú;/‹VK;?huó]N>5ÒÏ ý;º±ëº¦7˜Bµ=¤4°±ƒTX\\k¯fq*UÝÂ6¶7ëEÆŽÍ9•œ†­#Ò±ZìÖkO‰Å$Ã<,ôJ5õ ñµ…ëо‚ͦfÁ¿eýx+ M/4,±Ç ºÜÓfÖõ\ÎPp±øã[Ï¢¯:µv½\/ýa[,6ƒ´G‡ Õ«^¯í.L±øÈ—‰~–ñÉ«¬*¹/GlçØŠMo£}mJêVv²òŽ‚xà+9É¡¼ÆUºŸZ¶Ùâ´8Çh²‘ª»vºñ׊Ž:Öè³WçZI¹BI¬c?Œ ˜‡]õ[±E%£”N{$3øÄpmy‹«ØÕVañËÑY­eiŒtZè÷¹µ¯íb¹^17œ­%4ÌÌ?[ÑVoëT’7‰hÇŠó5kÚú”‘øÄDñС² z„˜µÓÓ·ìRÚ¬| V'´„ìѱ^¦ÏÔè­ƒ$WV˜ÆK0™×Ôoƒ}ŠÂ>3_µ§&k×µcûJËŽÞŽÍ,‡Ék¡‹µ1ý¬Ušìñ<‘ÙÂÎe5”d­Þ¶gÊûPF9E¨ß75I¡ÒSŸJÓ]T–í3µë7‹\fÃ]kU øäu+,–[Áfaw½Nqkç:9ÕqÊÈ6]p±¶¢­]Ÿåv+c0”ÚY#ŽÝ©K¢Õæö© Í9ØÀ¬7›E|_žú»ÔO ‘‹4! iìÃ3ÐzÚ¸:·JÒ^kI‰]»K´¹L^3M%¸-¹0»Nn>¬VŸÆ¿¿žjhÿH7iR±Àv—p‚Äv7 Rõæf½Ž¬©­|£§)¬d¨Ãvë3ÕŸ¢KDhÑ4Rœ–A‘ŠbÎü×Ú‚1Ê-FùëU’þMG~•¥YZÃÆ¿(+;ôxhéë뢂k4§~~PiÜÆ*èiŽ¿Wâ£s¶ ³éŽy^h£‰©’½TÔ¬¾'ÊO¢(^ÎRèX¯…ëØWSëCmS“<€cW:V_µkj÷øœðÏÞŠpÌÿ:1Jö«@Æ1iɩ͛©¼‚öŸãô`{-ûÄ/iþ?F²Þ ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅvxKÚÑì·„Fiã‰Ë+³U\ž×'Ù$at:Kmœ/5æ½+5[µ4È2Æø=[Àö'(Z¼æò]ÝèÍ‹º«koÖP1‘î‹;æth´ÅVÙª‡Æm1A{.Økù° ˜H÷Eó:´ZbÏ+HlÕ@3Úb„+HlÕüÙ¢ t+½Ö‘ªîˆÌ˜Z®Eƒ&!z‹ëgd÷ Žuî½uù6‹?õ}ý…í5+G§Õ^m÷ÿʼÛïÿ•y·ßÿ*óo¿þUæßü«Í¾ÿùW›}ÿò¯6ûÿå^m÷ÿʼÛïÿ•y·ßÿ*óo¿þUæßü«Í¾ÿùW›}ÿò¯6ûÿå^m÷ÿʼÛïÿ•y·ßÿ*óo¿þUæßüªÏh»sKÉvµ¥Z¾öŸãô`{-áåm$1Nz0ºÚÇMzèýuE%™à³‰Y {³ÉLÞ¶VZÝwñˆu³~ÓxËÒkKÜgoD}"Ø¥Ñè#ù=Ž£z—&ÆÒÈ!•ýR¼ÇPÙJyZ'¶Éž‘ï]fwf½Š(£œ¥å†ùÌãÍ»…ítÖ§‰í11iÙ€|eÝ骡~•ªåH_Æâ¼2MyÅî×Qu·z U™ùò9õzßõ—’çÑŽ›ÆX4”×K¥©Ig‚1;u®;„å€Gõ‹Õ­ûÔðX¤„+Fejk×›])ƯÁ<¶{ðݱó÷9¹½ªk?ŽZô~+¦éË=__ðÁAk–Ñ!Æ68ä1³Ú4rFýgwû{“`í_̹.}é¼eƒIMtºZ—,—GfÔq±^ ½uôkU V{8ºÛf!|"Ž~¦®jÒÑHLPÙ„ÙõêTÖµèüWMÓ–z¾¿á‚‚×-¢CŒlqÈcg´häúÎîöö!&ÁÚ¿™S=‡[úåvû›â­WÄ'v®¶bfueÿ(~ wŽÕ4å+†zb{£¤õ¿b·Y¬Ö©ž!hþ•È£"’Ž×ŸÔ¹få®ÕK$C45œž…G·  ö·ƒ”?ê$ÿsþmÉÿôñÿµ¼%í?ÇèÀö[Â/4Ìã†è¯Íd‚c¥/I; D0¥Ð»©©‡ƒIu¯³Rõ5ÑŒYâžî@b¢ŠÏlQ`j:xÁ¢ ÷¿“úÙI ¬´„æmrƒ³±h4è?Eq®ìZ(¢ãú€4dí1ÀÏ‹F,5ýeÂÅuï [ZKEŠÏ<˜_’&'QŒ¶8$Ú€Ç=Þäñ FíGmTWî û·oS];Wì‹Tu¹ÝŸ™ábº÷†­ƒ +EšÈ2¼€ÅE¤´X¬óÉ…é"bu Ñ†íÝÞm;(¯Ü÷nÞ¦ºv(¯Ù =¨ës;»?3{€!W¼÷Z•~ÔQŒ@1•j,:ž¸¦j jfeVŒÞPɃYÝ|hc³DVöŒA˜kܤ½‘¨uÍëðÚ-Ö4²—t5¥^¿YyËÜ2ó—¸þeç/qüËÎ^ãù—œ½Çó/9{æ^r÷̼åî?™yËÜ2ó—¸þeç/qüËÎ^ãù—œ½Çó/9{æ^r÷̼åî?™yËÜ2ó—¸þeç/qüËÎ^ãù—œ½Çó+=žõýcêR´jxKÚÑì·ï½§øýËx2Åv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AزÅv,ƒ±d‹ ìYbÈ;AÙá/iþ?F²Þ“Kt©zŒ.Tnצ Då!Ö/’„ÏSრҼÃ~”ù :±õ&/]®./±Õ]ÀÄÀzÚ÷[v­ 3³^!çzžˆ¥ÑÌ:Üc¥iö»(åÝ1bj£–GºÕwýh`´Úá€ÝªÃ!³:çµC“%óf½ù° ˜H÷Eó:ÑÚmpÀt­Ù ™ÕÉíÄt­Ó6d2FL`MV&ÁÛó_kL^3ú+í{bÒZ& Ò ‘É`@õgOpØè÷^ë×_“h³ÿWßÑHQÞÓR´z}Uæßü«Í¾ÿùW›}ÿò¯6ûÿå^m÷ÿʼÛïÿ•y·ßÿ*)¼[CC¹KõêoW­t|WGÅt|WGÅt|WGÅt|WGÅt|WGÅt|WGÅt|SkxKÚÑì·‡”œ¤Š˜@¢yÆ¢lÍGùÚœ­öä£;,/q®ÖÕÎgÁXÈ$iEíÐÛÒç7‚+?:ÑÛª6Íø}ªÂÖ¶±0RL—õS…U†¤Øübkïi ÌWo5[Š´_¶Äñž“DôÑŽF¯‚äíð”@6‡~x7Òf~Ú.Qa’+\U¼ 7@0Ë­ø"þ­xFÏ¥&€j4«^« ´¼6ˆf‰îólÑ8F/êÖü?Y­–˜9Dlóz2v£^v­z±O%ìö~P’Ì%+N5 ;:yl÷á»cæ=îss{TÖµèüWMÓ–z¾¿á‚‚×-¢CŒlqÈcg´häúÎîöö!&ÁÚ¿™r\ú1ÓxË’šétµ.Q¶YùDa–8…ÎvÕZWÔþ¥d²ƒ¤Òë¯õÅÅö:« ˜˜[^ënß Ì,í¢“FõíG,tªïúÐV‹Lš8‡L¹Ý¾ídwGµèÚ˜U‰ºÿ5†Í$ÂÓÌôúÝA³Í3ÝúÝ\‘ÍΗ£ŒŽÚômL†HÉŒ ªÄÝmù«C|ªç£cÑ•Ç/«z”ªb•ßœ÷D@\ˆŸÔÌ´•Yžë³³³³ö;>ž2¼ÂN«­±òmP6g¥ j‰VŒýë ²î—þK ²î—þK ²î—þK ²î—þK ²î—þK ²î—þHæ˜"i.óûÖ°€¬`+X ÀV°€¬`+X ío {Oñú0=–ðò“”‘BsO8ÔM™¨ãÿ;S•¢ÞÜ”ge…î5ÁúÚ¹Ìø+(½¢z\æðEaçZ3»uFÙ¿µrt’ÃŒxµ aFà¹8­“½®w+øSŸŠ‡Iwú§Ç—º;·y¿é¼¥hüZK{µé룻]mÖޥʰ;º Ä(ÂÚ‡©±EýZðŸJ:MÔiV½VixmÍÝæÙ¢pŒ_Õ­ø~³[HìRIeŠÎZ# ·µ“Õë« ©å{Pòd³@7ÂÕûÔ®JoV¾¥$RU¬…V,[RšØï¸u9UùÞ×­X탊Ó7‰Æíg´^b'툾·ðBôq«`ÿ™r[Ó_7û r{Ó_†½ªÞVË|–8À¡¸w/Q¸û>µ1Zäïcw6¥5ÝSCâã¢{÷§*¿;Úõ«¢ÐqZfñ8ݬö‹ÌDý±Öþ^Ž5ló+#m’NRš9lnZ™«Îæuj×yr}£ÆÞ ¼±I0=Ú­Wº°}jÑò< 3´3&:ºúõÕ«êV˜š!ˆ‡”GJ æ“›‡U¸l«ŸÅÛäu“I®ïÙL.Ü€A €e‰›û²ºüáì}L…ý^Pÿ¨“ýÏåËþsüçÃÙo {Oñú0=–ù˜%w{лÓÖÔýÎÆ&î×$ïk=|™§9­,r››Ð†•±tö­áÿÅtö­áÿÅtö­áÿÅtö­áÿÅtö­áÿÅtö­áÿÅ0œ¤.W¹î߂Ė$±%‰,IbKX’Ä–$±%‰,IbI›³Â^Óü~Œe¼ÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íYÇjÎ;VqÚ³ŽÕœv¬ãµg«8íð—´ÿ£ÙoÞ!{Oñú0=–ð”M Ó ù4#[ëO6YíNÀ2V+´£á‰7bÎÃi&;­Q¹‹õfLeÂïè*Û=Ñ«ºŽÓip² á¥:w-1ÍÃúG.nÕ§yãh?Hæ×v¡‘¥Œ²íNŠP´DQ¢66£}¨mZ#y/êÖLØ«ÐJ j¬eUOzkñ°×µMe+wõl×kx™¾U»¸ýšÔ×¢Ð?‰ô_W›‚šØï¸u9UùÞ×­X탊Ó7‰Æíg´^b'툾·ðBôq«`ÿ˜Â1Ú¬ñÁg'k<mzC¥+NÌh¬¶I9Hfhå±¹jf¯;™Õ«]ål8ɤ ¾¶ggV_ò‡à­14C(Ž”"Í'7ª+pØ.ÿW?‹·Èê &“]ß²˜.]¹ƒAË7÷euùÃØú™ ú¼¡ÿQ'ûŸÈ·£ÿ—æAì·„½§øýË~c§»ò·n^õy1 *÷ÝÝÝß½ÿr1‰»µÉF»ÚÏ_&iÎkK¦æô!¥_ì]=«xñ]=«xñ]=«xñRèd˜´”­÷n¯³Ö±%‰,IbKX’Ä–$±%‰,IbKX’Ä–$±$ÍÙá/iþ?F²ÞKuÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×XëøKÚÑì·ï½§øýËxJ&†iÈüš­Æõ§Š,ö§`+ÚQðÄ›±Fça´“Ö¨ÜÅú³&2ˆáwô•mˆŒžè‹UÝGi´¸Ùõ¶”éÜ„ÞP`<¥{S¦-n÷X˜Ú•ìE8ÚbxGSÈÆ×[íM(ÍDú˜ØšŽ‰á˜&az=­õžÏŒ„S\ MW¦·Día–x„o‚`ÌÛIZûÇTafêoÖ{5Ás¥¦"{­ÕyAb`- zs¦«èý¿ «tqƒ™”$Ì"ÕwÔ¤&³üŸˆèÙîjÅõ+1 žÐö§±GÆvm,rÓÑ/«öÑ ZëÓ[v~gâ%¨l´¬ÒÅg3¾ßQœ[j¶IâÓɤ¡ÑBO­†—_êý¨ì—\çk#…Ñ×®î Bk?ÉøŽžæ¬_R³Ùíj{q¼gfÒÇ-=ú¿mÕ®½5·gæV(#³ÚG”╚IÜJíÆ}|ìiÔ¬fqZã²Ç!ß(£-+jl9Ô}x)ÂA‹JO™¨n=¥ö×jhe³HNܤ2\pÕ ¼•j>­ÓEe”`“@'‘ÚJ»Ýî_Ò3»Ëf gºXpC\iàåú‰?Üþ ù!ðüÐ=–ð—´ÿ£ÙoÝ0´ƒy„˜Û½°òdšK%é$'"}!ëwûWä^ôÿ„tk¬Õ|^+/—ŠËÅeâ²ñYx¬¼V^+/—ŠËÅeâ²ñYx¬¼V^+/—ŠflÂ^Óü~Œe¼–ë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×Xë¬ uÖºëÝunºÀ·]`[®°-×ð—´ÿ£ÙoÞ!{Oñú0=–ðË šËã/±IÏ»Svº(,Ö@;±ŒŽóKqùÕÕK¯Ø¢/„ØÜC§v¡;Óêà™æŽN±¼ÛhÈå‘è×Ôg8°JMWêõ~¶¦kÄÍ€†bîZb&Ž;·ÉéFDOm³³ ]wÒŽ§ì@3Z"ˆ¤ÈÆl×»¿5xb³MkFù´4æ·Úí±5¡ËGÛõ“›Fõö"'¶ÙÙ„®»éGSö ­DRdc6kÝß™ÆÞ/0Á)èã´=.‘m¯WbŒZ-Èôã¥_n¥¤(èN$ˆ»bÊSŽÓØÏFõ6íÕ·©<Ái„ág¦MœkÞ…ÚÛgv"º/¥moÙá&bÔÏØ³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7.ø»xKÚÑì·†ØñE$ÑÚX^ô3hÈ š­«Çkäßë?ìñ…úƒóš·³;+3G Æã,Dñ»·5˜›ÁgŠïöf}$ÛLoÃõºÓ,qA<-f ˆ^Bbgvç=.½]OÅý¡ìÎ:8êZéܤ&³üŸˆèÙîjÅõ+1 žÐö§±GÆvm,rÓÑ/«öÑ ZëÓ[v~il–Ùf´Zc˜C¡*5  jXfb–ÖöGfÖîWT„Ö“ñ=ÍX¾¥f!³ÚÔö(ãxÎÍ¥ŽZz%õ~Ú!«]zknÏ̬nÑZü|g¿4f ævô{©­3ÙìÖ,†ñ³ø¹ÊzNÍÕÙÚ…¡i©W¼SÆ@d]nõe42Ù¤'nR.8j^JµV颲Ê0I  ‡‹Èí%]î÷/é™Ýå³ 3Ý,8!®4ð´ÿ›²ÞöŸãô`{-û¦o0“w¶K»Ž·õ¬¼V^+/—ŠËÅeâ²ñYx¬¼V^+/—ŠËÅeâ²ñYx¬¼V^+/—ŠËÅ36 á/iþ?F²Þ …ÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÁteÃÂ^Óü~Œe¿x…í?ÇèÀö[÷ˆ^Óü~Œe¿wL ׋àÞ-€cye”®“àÁøøn;Sê¿o^Óü~Œe¿wO\¦ù½}žG ŒŒBÑRqjÝjuøtMþ¢ìþ>A{Oñú0=–ýÞÉ'õ§)G|œ®¢‚Þ¦Õå—´ÿ£ÙoÞ!{Oñú1„µ;jÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pY¸,Ün 7›‚ÍÁfà³pXð]ï_ÿmOÿÄ-!1aðñAQÑq‘Á¡ 0P±@pá`€ÿÚ?!þñ¯‘Ú³úiâÍ JÄ[>¾°Ú á´ô—§9LÀ°þçqò~Ó`H…€iЃ@»}n›zsfÄ/¬cºd¬Æ5z·ºmèŒ`DæŠ;’‡³L·&œi°± ŠnAb€3‡¸AôDo½š|'ñÔÁÈ# @Á4®F€7ˆlXNDçBëHm)£¨—ÀÐó ÌÝSVËà 4šÑ?¸K;£¢*­‹g †°a €ÀDzŠéÞðˆf€É!¦å± Y9:;Û°L€L^M5)¹„Ô=0#«Û9'@‚Ói0œâ%·€!•Iõ´$´D;ÓbA±ÑÞB  i€È¼ÕC–½Æ$|¡$ „ ä'ÐìÕQâ3ÎiÌ™ªV@òËì ¼\i¬YK‰t8Î$H‘Ýu‹úËsÅ*ì|&†–ñ˸ñÜI6%vDÔ o241 b€Ä¸!” s’ õ€îŽŽ„p"L@@0Âs’ëØ[0Zh†ÌéÞrý 8‡†©¾²s)%ˆcžÑ@$AHrcb/ŸOÀ,\yþ®àˆNˆF8‚5rîÀ5°0"CÔÔ ²aa }ˆYPsŒ¤0€æFrùäcÛ•e7buAr)¤L0}”v|‘“0Õ¨ar,ÈâÔ‡TGņfJˆµ™áðÉó¹Cq'„g!'Lf1~ÊŒrbjð}P4ñ‘œ«jPìè@cÓTæ!¾.t RwÜçd2u†'aÎÁ‘ô©Eᩤ ‘HA7(_±,¦30BMBTXÀÆ/»†tX„¦Á"‰†»*~Ï@>R@ÂZ:2™Ù€C!ÄÀ†Žˆ€T b¶ÚkåXދūtÈEÌç@ÎY€iÙP:nƒ&R:¶sA‹ óM,°•Žh:­.ìѤf’kp1"ã"`/ `TD@n«¸Ãâ29Š4bìà†5à7@GB,É…Œ)ôÒÀ:.æ`ð!OÈ?w™4Fª:¼4H" à-ôÑ„¹ §hBmô6aàM½.›(mðZú[Óœ‹¦FÀú]6þê㋦ßUÓoîN8ÀÖ°µ…¬-ahxŸÊ’I$’I$’I$’I$’I$’I$’JŸýÂI$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$©þm$’I$’I$’I$’I$’I$’I$’I*Eúäÿv "»‘‡í …ƒËðõ“ýÙ>Ü„ úM ôèÍqf`Lçë'úl$‡‰ewü+¿á]ÿ ïøW»þ#èÛEwü+¿á]ÿ ïøW»þßð®ÿ…wü+¿á]ÿ ïøW»þßð®ÿ…wü+¿á]ÿ ïøW»þßð®ÿ…wü+¿á]ÿ ïøW»þßð®ÿ…wü+¿á]ÿ ïøW»þßð®ÿ…wü+¿á]ÿ ïøW»þßð®ÿ…wü+¿á]ÿ‚trÆK3‹ 3ŽÿyI²ÄXƒÐ‚>ÔŸ¬+@ŽLC»ƒöB•ð„âˆÁ±„¸¢+¡öúµ6zF:©ý ûž>»jÊ~§ŸåB™>³ŠCÝ€*BvFE ûäÛÈb$Ä (hØA¦2¨?LZbÔ .$ÌlÒÈ»\nAz$ó†È¸áE&pÖ‰î¢a4%ÃTzšvÆ"mõÚ>äoû¸= ’p ƒ"0ƒ@ì8ŒØ 8ÔFÈC`¤ÕvE˜Å"îÓB¡Í¨Ì ç1.Ã`¤p}èØ”Tá Œ÷S7vЇϡ=œݘ›Í¶CŽÀà}¡ÙAHšŽŽŽ™G¨sª€›<|7 ÃH$52‚:Ãkzz9~ŠQà HÛȪL bªHüKé hÀeƒ±* .EäM H1P/åÈ¢ '¢EÆ( Á‰ôbSÒQÈ&Ú{€™ J—;0$‹Ñª‚5¯‡•¤õBP#´10;$ždÊ ©Ýž5S°Ì@THƒÃAI4§$i'å…€uHXË…-M>¹oƒì‚À×þŸ÷ƒbêEÀqG’nD3ˆbÁ·}täÉ“&L™2dÉ“$Ÿ£ð¸ÄO˜C°JáÁF°‡ÈG £f"EcÇ¾Æ Ðaçt˜#©BòˆÂÆÖ$P©óõ·XCÙ€fF_Ó”IŠrL÷MbA„1éævœd"ÅÄÍOIœæ,kI`mèçÈýKå?HÍ, È-%.Ôeôgåò€žÇÂ}Ó8† ÇPÕaë öý"Á†΢’ ÄŽÈÔϯ™€f–ìµS¢6OB€ZVƒ™_¨Òd÷)=J Ñ]ÄM-$LöCà,€ð0¸:%Öwè%;s6-{D&‹ÊA ¹Ú–fgÕ4F*ÉCÙÓ7³@@8€¸ôCžØ2îzëÕ0¸ Š0QÃú/“%¿éÿsÂqÉÉ`æ[ ÒK›ƒÂ}¤‡Š ‚ÀБœÑó+€Ø¢¿¢ù0r[ÒÚSƒR’pø•q" €:‰¢`Y›@@Ø:Á9F¨‘/!Á"—Ý‹¦8³—ÝÅ 7Hós=ÓwÞRÆ‹„ 5E­áé$.ý9ü€t,f‚´0r!6 ÎC™xv!%¨Mõ2&¹pa(±´9rí¢z›³ÔnhȰñÂø æ-,(]SààG8¡GqêŠ4v’`&Q¡‘)ÈÁÍŸ°Ê6) ˆ@“•úž~Œ:Ô0Àë Z&j*n‡ €È8• Ü>‚Á4ŒCjžáû=¢9x‚ñ‚&H•M™‹FàÑ›#†#žŒîâqOq‘GF’ «Tn}DÈοv™>£+Ä 9¹™š;¢Cƒ¢ ! Uɼ üyO’{€†a¹Ý Å[Á¢Œà$IJˆ:›¨(ŒÍŒÉnÁ³ö º„{rçÔ¬—|`† tF!äD"1ˆG.à€„òÕ†càÔÛýsð%òÜ`@Ñ‘`,ñ4æ)ÿ±rL¹0p»#¿g`…†3w!7oÎ`è$Ù1†&ÁF²°ÞL[Tsˆº†Gq$Ãߘp?d÷Ð|!Å‚1d<œ (©éþ¡ã^PÕ†ÈÄûé—ÀAr8¸Ìš;ý–‰3¾`0ÿ°ýÏ]µå?SÏñ±IÝ ½ã‚ý©î„ÞðÀn ПY?dI@gdiì¦nSø,í®Ìçþù‰—¢¨vªª‡j¡Ú¨vª¨0“F^J‡j¡Ú¨vªª—iT»J¥ÚU.Ò©v•K´ª]¥Rí*—iT»J¥ÚU.Ò©v•K´ª]¥Rí*—iT»J§óTþjŸÍSùª5Oæ©üÕ?š§óTþjŸÍSùª5Oæ©üÕ?š§óTþjŸÍSùª5Oæ©üÕ?š§óTþjŸÍSùª42ä4b˜‰€ìÂ5ì©×NºuÓ®të§]:é×NºuÓ®n¹$ä’\ŸrOÔN„™°p`ÃAÑAÔÉi" 4Y?݇tl&öŽCt ¨ŒMí —ê%´ÖO÷„Ÿï >¤³EXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÕXÔ^l+õ?i›Í‚fÁ3`™°LØ&l6 ›Í‚fÁMcV5cV5cV5cV5cV5cV5cV5cV5cV5cV5cV5cV5cV5cV5cV5cV5cV5cV5cQx°PýÒRb¼"C„°Ü¡«~Žca³‚&=dúübŸ:‰à&0Q› 85w,B6t4…"à‘z± ±.a©ú C''ÓCBñE¾¢@ <ЂIØ’ƒD}Dfªê„@-ÌX(q‹ª'Àè‡$ãÔ³0É“ýúÀCŒÌ¢"ZÈ4~¸t<LÄÈ)K"Xnv÷Gh‘!A¼$g§ `‹çhÇØ Ì’NÍ7Nø4vÿ´º¡_©ûûŸæOÛ;ð–éÐR$°¦Là0ª”Ù:èf†‘ »´ÐP2øhsôîP2 h~¨Ü.`ÂÑ€:EE Mjd†1S„BS2‘ÒdåéM·)˜²ÜnÚtE™u†3É÷öŠŽ ;T‡ût?ô€_åWPôGd0àâ2‹‡Ã¨‚´Ä$ I]:[¢ ¸²è]“ìQ 81-0‰‚H2Ò º#.sq„D“eâ9 1ü„#²‹ŽD¶ÇÙEûd€õEûnDH’RHqÔ$QI˜µ‹¯×ä›Ð"{©Ì`BÜ^ Zøæyu Ð"è;Yÿ¡B¤ROûKªúŸ¿GΓÏ&DÁ%±‚+0`,&2 ™‹x™ÛÞj:†í†¼u‰P°æBx”´X¿ÔNCÃ@ßIƒQ Ž@&0 Îè:hµfIÅõ7Rã‚fÎK /ž=A…3Ò=³°ÔM$ó>ß‚º¡þ ŸP@YªÎ¬êάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάêάê¶úŸ´ÍÂfá3p™¸LÜ&n7 ›„ÍÂfá3p†ˆ&³«:³«:³«:³«:³«:³«:³«:³«:³«:³«:³«:³«:³«:³«:³«:³«:³«:³«:³¨<Øhƒ'Ô•ø’I$’I$’I$’IP*@¨ T P*@¨ T P*@¨ T P*@¨ T P*@¨ T P*@¨ T P*@¨ T P*@¨ T P*@¨ T P*@¨ T P*@¨ T P*@¨ T P*@¨ T P*@¨ T P*@¨ T P*@¨ T P*@¨ T P)e?·’I$… T P*@¨ T P*@¨ T P*@¨ T P*@¨ T P*@¤!¾è·aæ!À6àå v`ƒì=dÿvm÷"K€KÂ*&¥FWµ¬ŸîÆä9x_‚‹!`‰êËŽãY?Hâ;±ˆ8%€ª–a„HYݶ@ìÐçAg&ÃtO8ˆUP°žj‰0½¨DWt¦ˆkæy¸™5:&šC¹¨u{) 3ï&’eЊ€êC>Aw?ÒPX3‹òFZ#Dw ¶ì¡1ÉÙ¤Ð>„P´ü!î–0EÀ÷¸’ŒQ¨8¸0vqô#°=léNâ&ÔIv¦iÄ@lƒèf3uØš:%2á1  È‚ ,`+‘Ò:¨Oä#êAG授-‹ì¹?Q°›ð¡Èlì¼ ,žh$>ìÙ %Á‡b‹’^4Ï.é }㸜l„LDˆ÷1˜P²;WV1±û!ì'p§)d‚‡ AŸÀAqõ a/PQ*`7ûO¨$ ý!Z3,ñB©ŽA0°5`Ž/6ZÔ‰"B gd åL£Å8 <ßGSÀµíÓ— OGÑñÿ¢šàÄ7EHÛ30p¯AS¦9R× ÏBµj n+0§LµÂû„À¸‚?»X„á„ £ÑDЊCëì?²äÿvGÐlÁvjLƒ£Ù’ìAЈY?Ý‘¡Vè‰ [-_å h`ÒˆÍ!é'ø|óÏ<óÏ<óÏ<óÏ5lUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅPî_êÔÃpLé“졆Æå¥h}Y?Þ¼$þ–ôbp@vOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>ׄû^íxOµá>×…µîѦ &§Ôvl÷À™`àI0GfÏ|‡/Y> &§‘s©@ù&¼5¡Œ˜`æ4Œ‘\ é ¾jΛIª<=ÃR3’tE:Àž-ÀÑ“d3`e„$Q((ýk5‚6»€Pb¥¿Xä´ßÙ€é˜IÜb¤5%ÜŸ^BÁ° ‡nú-jûR=]6þĵ«êŽë DEØlºu@ÑÐx]Àô“êÎ!#R>µ@&LKaÜ2Šb }÷DÐ8E”³|dƒF¦3P´X°–Bt É¢Xñ ôdxÓÌN;Ý¢Ž§è¨ËH óÌD40€Àè†p zI#Û.™„C b*ôh‚!¢ô¢nè ž¯¶Exf“{ µY¼àNôjˆë±E6ŒÔÓïÏWM¿±-júƒêìølt:nLÈŒßGcK¢±3ú’}I`ðÝÙÞ¨;Í©¤ &otÄF¾y8ÒJI4I@rIWUG×P2€Ðe­„Ÿb&t @ô€an€¡ŽOqÜÍtÂǓū¡gî3€´!.‰œ.ì;Hk¦&p ƒ}â„PƒÈâ‚\3¼7Cy9ͺE0p[˜j@ýùêé·¦ô·ÞÂËYÓÙþ=D1ÆàIŒ³´-zbAœ„µZ:¸ÃÂÆ¾ú}ýmh»¿ÂÊ´ƒÕ™U£êÙÝ F‚Bçìš'm}£Iˆ Xw @- §÷A<#¢ 63ˆÔ"³å2AàˆD@/²ËoŒÁÜ5 PqBïDif(E‰È|cαšbE&åˆ0cßè©Á'ð¨À¤¾}•@ p>¡ 9LáΈ‘‹'•+rvd¡©' N@CÁ‰“û”fgÛaˆhŠk¼ÖgìÔVµ}PÝtè‘£"ð(;×@©:2 ƒ¹>’=]6úClÅ¡ˆŠt“†ž$õBR e¹ú䚘Á;Å™8™;û•,†ðy*Lã(ÁM¯<‚ùb“'xÁBËUI^ 8a2I÷úØONá•($†aœ¹î‰"g"@@ˆÍá«#®`×fëúŠÖ¯µ'× Áa8,'„à°œ‚ÂpXN Áa8,'„à°œ‚ÂpXN Áa8,'„à°œ‚ÂpXN Áa8,'„áë=]6þĵ«íIõk`áÛ%dåY9VNU“•dåY9VNU“•dåY9VNU“•dåY9VNU“•dåY9VNU“•dåY9VNU“•dåY9On;eë=]6õyL $XÀ§uÓjÞ÷EÇÌ´¶D "™ôúOçÂò˜ ÀP HX”ˆ"a>@ËkaP?J0MdƒBÛý½…ÚÞìHì@2&™I"Éý…×ÄípÅ4Å&&$Íõ5­_P¦ L$“ Ÿ$=¼D-pbr-6Žìþ’}~3ës³O0:owñ>sÖzºmèã>óêeR*LLq°uCHqF Œ”%ÇÈÑÌ›2·àX.X&]°Î¸#è–5P€a¡>È}¤£'†h'5d&Éx»X’„„á®#|­tÍ?‰‚xˆ}¸\ñVH$\“8#}˜À…œ‚ Â>àqè™5SA>& ÀaÏc]Ñ8§³801þ¦µ«ê¬ ¬bé™…µFB·X{,¨aé'×ãQôy³D/`@Ášà”óƒ"™,@)Èé94´AÈÜ0ˆÞCˆUÇܘ9¹#!iìßj€ ŠÛìCk:Ÿð‡„(i‡€ŒŒŽ„FMCÃ@’D'¢CR~sÖzºmèQ!…p †P É,A€æ*©*»F†`¼ƒOªYÝí’Ì¢Xƒ›H£ª”È¡Ÿ,™²LП„û™‘-;{ïìL¹¨“ý:…ŠÏAÏDUx‹ÒH"N‚_lÇ.q#UµH1Á€!fm\É’;3p53ˆ¸G ÑDÆ,(»±} ÎÙßÔÖµ}DÁLâˆ@0l 8l€ˆ‘õ“ëñž¤|‚L‰±ƒ™À?ñþsÖzºmý‰kWÚ“ê  ®‡ èp®‡ èp®‡ èp®‡ èp®‡ èp®‡ èp®‡ èp®‡ èp®‡ èp®‡ èp®‡ èp®‡ èp®‡ èp‰ƒ¤=g«¦ßØ–µ}©?ž®›bZÕõw/¹˜úIÙ¬%±àA€À}>²=]6úÝ8‚hÜwE‚„@,Á Ý”ÈBgpd^©áˆ#°ài¼.I:uØ lÐW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{^ãW¸Õî5{A±¨éÙ€O“ÖÖ¯ª$9)dñ‚i¥¶Dh@\iî=dþzºmõšXºDÌÎ=‰R23©ÕKw‚=<¼w_Oýÿ\­_Tç D¶Õ I¨´K¸ÄÔõ“ë”r²ŽVQÊÊ9YG+(åe¬£•”r²ŽVQÊÊ9YG+(åe¬£•”r²ŽVQÊÊ9YG+(åe¬£•”r²ŽVQÊÊ9õž®›}Ïýÿ\­_jOàg«¦ßsç×kWÚ“êûµ¶‚%SP:òS´âÈ:Ó!Ç1w'q$æ=MJkDÝ]Š…³Ý3lÒ!È»¦€È¥QþݪpOµ#C€5\y F²EÝÈmxZÊhâ;œ¨£qÑОš2†Ýœ '@ü#{¯·^‡@è(äÑ/„RÀtiºý]I)ç£"Þö¹ó ‚zzºm÷>w÷ýpVµ}O&‰B !3ï XñÑ-!ê“êhši}ÈQp:€a£§ ~a ±›Ð¹ÃüNsØ•\0ÄgKRWN —³HÜÁFˆ B-x4 4Ë”Ç|Y²D¤ÐvÙLŒZ#T:€5ƒhЇ‰ 7°l.ºêQ(9Ì’'.`P4Pvc Dö&úÉ@"€Î®E›½=]6ûŸ;ûüy,¨¿â4ÌÎàd V#c¨ÿŽ:fN3Ãññ #‚¯ö Ö¯©ÊÆ`cŒ(ˆa( ˜¸ÆFÍë'ð3ÕÓo¹ó¿¿¡ð™ßbˆ¯ÑûôÊ[Î=Nã;TNY3ì„Hs,ÓêžP€Ä Å n–CpDÛD!nØÔì€[(гA@ì—€÷ú€b$£Av Ý šdG† ÷hØè'x{Éa:sÕq÷ÉsH¤ó€0hìºÌóyV± 6_nHi!Ä fü;éA½Ð(°2  „8#_¬­júÊCÛò?p½dúå,£…”p²ŽQÂÊ8YG (áe,£…”p²ŽQÂÊ8YG (áe,£…”p²ŽQÂÊ8YG (áe,£…”p²Ž=g«¦ßp±’äª0‹N7è‡Àg¨GÙŒ$g ìp°Fbô»š{zš²Í‚šž^BeLŒÕ%l€›ßégq(@nV¨P™ÎŸâÖ[2Ü'S>³~‡Ôè²èbì‰?©q¦BgMÁ6œO5qõ[eh8£¼¯„;µ"Ê"9Q‘$hWžÈãÓâ"e˜3'O”0@H‚$~ƒ„zBŸZ‚´Öo1RÄ£ÑhPlùwR Í Ú¥Ía{¡ŽÁ€H5(i çô4[éZ¨8ƒÀ ìèæ}9ÝA–¶ïØÜzÅOÔTѦ?³š÷kùq0…‰Zž­° O@€éR "G8?H8$´ý½‹ÝQÃñ‰á°'zvþS—k…@ NHÁ ãS:³°[¹!À(à$}¸WþF.U GDn¬\z$ñ/‡€Ýh¬ÜS…´Lôî -Ìa-T;òvÑ pÚÎÇìX &©§±_‡ë›‰(Èp»&*ªˆöôù#@@ÌÑÕäW¸vQõ•­_jOàg«¦ßp[î†=Å!ˆ„Enà¼ìÛ”¨1Gê¾P£ï§W’ ¸3HÁŒÔì€ ãªf¯ÖùFÌ1 ŠzÆ Æ'U4@°4ê ¼¬  nën]/yTÙ1ù›þÝS®g‰3éÂ.û¢N­û£V¨[iЃ_ÚÊ h2a{¬V‰6$ÒB˜ýIz~ ÷ížÁG˜¯)J}ˆÝÊÜϰ§‰Õª;‰$~ÇBÑ¥Ÿ¿xý)Ò[€¾Q÷4 p%/À_GÁ{ÛA¡ÙEaaÑ|vaúS†öhü¢A}¤Šr×ÿtD«¨éÝý $€ýT4'jOHõ ÒvAzÎg¸LÁHSÃõ:àÿp¦Iˆ=º'“¿Ó¨L 6Qd‘À]!yó¶›j½ÖŸÂ(òÁ¶U‡Ôä¹(ÆŠivŒ»­¬½}“p€Öb?#$=´ÑA G$¡H=àQŽé »ö—uZSÜ_ª6Æß䎣8Ûš"ˆXÖ€¡F(Ï©C3Ì@2I?µu]„Òî‹cŽƒ£òŠøÐ˜a‚A ’quö¢‡ìîèHèôÖ¿à`tŒÕ8 ±ÂËÒÂ]¯˜ iBïdÖPdÙÑ ö1ðž™™<¡DÉHœYÛtŒ{˜&HÅ輇°E².,÷:Ÿ„ŽIß­~ŠÔèiÃ9A!ÒcäF6¥ÝÉ"‰&ŒØÊPÛòøL‰ 0p´H*4B¸ß3ÿV÷4ŠT¤£Ñå?ÈXœ;ešÒIð~éjU2[!ÕÕ¡G±@ Nè"ÒåÌS~ÁfÄŽê\Ôì}“ Êâ=1·U êhYÞƒÄË~ËE¢CeûAX]š&Ñw‰U¨ü@œ©°!î„Ó Mî¡~ l„IÜn´§ø[ ¹0Ç‹$PíCýOèu)%R9|©îô‡Ø!  ˆ'¥á6ˆ²!‚ôX@3î"€#„€}„¨V[èŒï¢41àFEºÀÉmê-'ŒAp€H"ógxZ6Œö)ÿ6§`šùS?º(ùñ6DuGIÎnkr„nõŠ?pkž‹3þ^Ž@³ù*<ëjæˆ;£ñ°Bw4QüaˆAÇèV’H˜t PÉ.‰íJe“ë,î2žQCF%X MÄm€Ëõ¶*_:GÑdaä7(…ÒµìŠ3ÀˆŽ±Gš¨Ì¿BØ)œ iTdذ AÍ/ùP Ž}•"q¿ÑkWÚ“ê:!e‡îc ٽܕ è¶êûÂs”W¾Í8 ³º©¢ïrL Êž®›}ˆ§Ý<Òy!a»²™Lî,‹Õ<1„v 7‚É#nº†tY†õNQÏå1›p6¢ë:ºä 1LšåÕÐhmLÈ„ÇÔ;èµ9jS““‘Ê ƒÜ&ãS5ºèéZ_* VŒ:ÙÍs²s²"²=ÓÚ ŠŒ8"¿ìSEœìœìšH儱îÒ-¹ Tn¦ò¥†èŸÚ9¢ö´Z5‚!¬ú©ÈF¬§;';'_`ÊqcÓ‰|€NvO’P/$4[«Ôð´µ@¢¦ ö¡`I1-Ês²s²s²s²s²r†Än³M@=˜&—ܞfé”F‹É×Ð×Ù=põNvNvE"y…àÕ; ‘î Ûo£"§‰rêŠs²s²jçBf:-¦™gtÜaUS.: NvF$aÕ¦Ú¨Épþ®x…î¨2Nï§}“V$î©Nv@ÂЯœul‚Èçd- AÕ9 ÄVˆ°ºb}´ Q9HäG=Š€®Å¦çÝ45…Çi"\Cgá²NvNvAH»t¶taP! £G-Ñ.uk¢Z öOíHƒ³½Â%”ßq4í‘»• ÃÿI«Üìc¨h˜Œ‚àòjœìŒÍºŽ=•Žt]½"Kå9Ù9Ù9Ù{ž¢z²2û·âƒ4:ˆ˜µï´Â0¦FŒ~ˆ¹xGÚAvÊŠ';"³N‹„Ao‰Ž'‹àiû‚Jµã 5ˆi `NvNvNvL÷hÈŽ‡E,(W±[s½Ç°Q,ÆîêDzÙê(šíÍ|m-û8äa#ƒ#‘² Ølçdð 4:¢‹ht_-ßàŠœlT| õ%kÔCNQ‡Ak¸æ‹n‰ÄH¾±AëpO@j£¤³Øhœìœì¨ÒáìNv@Xo¹bKæØ„À*}Àœì´yP „-úPÄS¥±:Ïhèdǧ:ùNvDBgQnII?õ:GÑuŠ|tˆ˜ÃG°E¹M",s²s² ²® ÂØâßGOtŠÂE äõµ«ê8ž``´¡ú@ÍXpîOI>¯„¸pÃK‡±HÌ(d”Z#N…Zn  ^hV‰ñ‡`1@ÀÌåOWM¾Ä—úCªuDE’àDàO/AÝ×ÒÍ¿¡“Â>ĈG‚ÐHÿ €ÅKíœM € >!S}`º &Z„Üà˜a!üŒ|­‹úögvR‚€ T €ÿÃå] ð…';£ôõí¨  œ‚Ãé63î‚£š@«Zýµ}U úÁÑМ§ ¥=Ìë#XúÉü õtÛîY·þ´µ¯ÑkWÔH ßKiÜbCúD¨N¸$˜T¹>²}rœ–S’ÊrYNK)Ée9,§%”䲜–S’ÊrYNK)Ée9,§%”䲜–S’ÊrYNK)Ée9,§%”䲜–S’ÊrYN^³ÕÓo¹fßúÒÖ¿E­_jOàg«¦ßrÍ¿õ¥­~‹Z¾ÔŸY¯õýÆ :¨9ÁK°KVJ6xI0v`c"Ñ‚!pð€]ÐÎHsˆº@¿Ø ÝžÔCTYF¸!†x·I¶<8鎩¢ÀÁn>ÊM½îÛDëëÑÍÄíüIêé·Ü³oýik_¢Ö¯¨ð•±1x%×dðZ[}À* 8võ“ê#"?$NÍõ0b /kxhžcT×J$œ< @½™Â@ Ø4Ý â601Lw ˆ_¸”% µž jâ@ñ8sœÙ*[ ÐÄ HÏÉF© 1&©Ëã2 ›?Äž®›}Ë6ÿÖ–µú-jú‡"@3QBØìª}–”“)ã½Â)é'ð3ÕÓo¹fßúÒÖ¿E­_Q"Ž$¦I  õú$úÙ%d•’VIY%d•’VIY%d•’VIY%d•’VIY%d•’VIY%d•’VIY%d•’VKÖzºm÷,ÛÿZZ×赫íIü õtÛìú BhXnì¦B;€ "õO @!„‡MàpâHæ$‘ïþ´1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1Œ^CA-Š"Aý-jûR}a`Ìç™Ý|`¹$6ø h2,K €‘kü¹êé·Ø!ÄDY.IÞôòðDÝ~ÈfC—+ꈻ+]†v:ÏDØ_`ì HŽèm¡ 0œÏ¡Ñ¡÷8@ƒ°(Àò%!&)  Ž#ÙwnŒ{#²ÉœDct¾éÜëqvÐ1ØšJA­€%¦†5®Æ™2v$¦`šƒ÷ÊЈ‘Q—DB3M°~ÖtS8™ÎÍó›©œƒ¸Ÿ¸ÝÙ¤£Èƒ¡GCn¥úŒî¨Ï°8L€«¨’)—¹û„Ð)[¸ƒŒy@6pbâb`M´Ï3‘~€h¢>'·D&¨ŸqÐòY=Ô's:.}LZf}ÓE!6€„"Î}& ¸" €9.Âj-Ób 1.:;£ Bà8‡MÑ{¬ 3¸ û*äÀç°Dœ€/ ‹€ÝÓ”mmrž1ìpˆc!ˆ‹ê¬0ð15û€Ð;˜d䉡RÃÙk70¡2 àé$G¬0¶„I=ÈQÌáŸ}ÃdÏlntFN(Žz‚#ÕŒƒ€Ìì÷F¥ ?¡‰ìXÓî@¤AlF>â1Dp†.&&ÓÅ9x&æb@£ Dp“rŸ]­_P¾;œ%"¥€7lˆRm"…ÁQë'Öáú‰#ʘ'p9Û@óŽÌqü` Û«" öæ€L`ϋžèå0)S7Švhó¡Ã¨{!QhG¸ž¿v=< A ãñº‹ãŽøÀä4¨CÎ0®Fˆƒ>#&8&£Ÿ¸p&RÀĘ£²¾9¯¢âîï PвÁpÖ±¤÷Š´¥‰ lL„þàóáŒXIr¢Üï°lu{6fh4æb4AA š`$œ’ë÷8æ¢KܼJ"h SŸfÕ!ì3¢í¸œŠßº n]ÜÄH}vµ}@P Â1ޱ"*Ž´&24]€k2ië'ð3ÕÓoìKZ¾ @H , Edþ²=]6þĵ«íIõ°…„,!a XB°…„,!a XB°…„,!a XB°…„zÏWM¿±-jûR.IÁìgL åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa+9XAÊÂVr°ƒ•„¬ åa)é;P9D)3"^ÿQZrµ/¿`è 8v¤°}ûP"Þ’}Ds¡ B;`F@O]Q-haIÑóub$F=Ñ•Âpg0°%¸ pF$u¡# ™‰Mðû¤JdÇIÁ ƒb©ÑUƒ d>(r—è£å7/ŒbáÀ4Dìžf3 Ø/Ù;@mDèAþxÁÒ¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òð¯/ òðœb`†*9W—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxW—…yxLéT𠈨LvEñ'=Ô9î#˜2GÖO¯Â±OH8Cȃ4npwEÃz7NxWRxlU¢`‰ˆ!X€rx~H é¹k" ÐB“°:`OÀ†k‘ÙDßšÎLÀîŠ#ˆ™‡àŽeCf ¢õCö@3Äœ C Aî‚i”ÌT‰šŸà“ø¿×ý 5o(U~ßôEÛ÷ª "S[ðÁE9ÉœšÜÿ‚²=]6ÿ¡¶Q|÷íÿEkWÚ“ëVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±UVÅU[UlUU±_Yêé· cÆg# ͺ¢’2 ÜPú¢Äb0K lúÁ›‹ßA hâ ˜ˆt Ú°L < >ÈË"ê¢jøëeÏ~Þ“¨C€Z°@âò%ÃÉýEu™%:ñƒ‡i3XAù„púéêõ„ z;ÿÇZÕö¤þzºmêÄ ^r“Â〤I‰BXëÜ0eT@K:ƒ'Ýã „`Ð0jŽ/ø#ã Ô*ÿ7qœÐìFÓL‰jÐ/0ƒ ›Ó³ÇûlÈ®Ð"Ð àM®lDÞ"èæ‹o˜ï¶»(ϲFa5é²  Ð:)îAXÐ : c„,íM.h„Àq´äù!hEˆ¨CEð#ˆ>Ÿñ–Ê/žý½T kì’`w,â­ OªKoÌøÿÙì™ †N„áüU”p€¡CdpD*Ž3ê3Q(;%Ã6­5§»¨† fbçÙć!´M_'1d¥ø/|¼uÿãmjú¥Ö7ê‹+t¹úˆ¿¬ŸÀÏWM¿èm”_=ûÑZÕõy08¸E:DêKy!*F°M:@jzIü õtÛê“e5íì ÔÔ `Ðİ@}ÿè %ظ=>¨·|X$Ã10@ à l3%áÓ¦5Lj˜Õ1ªcTÆ©S¦5Lj˜Õ1ªcTÆ©S¦5Lj˜Õ1ªcTÆ©S¦5Lj˜Õ1ªcTÆ©S¦5Lj˜Õ1ªcTÆ©S¦5Lj˜Õ1ªcTÆ©S¦5Lj˜Õ1ªcTÆ©S¦5Lj˜Õ1ªcTÆ©S¦5Lj˜Õ1ªcTÆ©S¦5Lj˜Õ1ªcTÆ©S¦5Lj€KeÏ~ß[-ð܉ƒî#‰j¡ÛÀj‡ðyÀì ¦S‰Ú-tA«Sc 6Aÿ,œÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsT ‡ôµ«íIü õtÛê}ßP¦bÂ¥š”tœHDXàÕƒêfK:aØ;£­ãD@pÄÛ­P¤Áÿ-l¢ùïÛë:f®XŠ Õ š?LÐs2"K'5iÑ#§[ "‹º'1"qƒðÍ ·à4¿t r–üKZ¾ÔŸÀÏWM¿äFÑ4Ág÷þÙEóß·ðÐh3ï Uh‡Pቑö p}NðK‡³ýÇ¿Y:r™ê êê·„‡²}2– U• p°Ä"IC¬"<[Z„$–d§­/|CûES˜Óø9€8Àîz}¡Ã„¹öý¡Û7n>ÄMäóêgq>ÁL¹D@#ƒ£áZÕö¤þzºmÿ"Hè…þ¶Q|÷í÷ŽÙ¶„^À VÝ@ˆ^ì äûŠ=±Ç¯‘â°¯O%<Œl>Áˆè¡“+-sàû£ŒNäßé3³A3UÔÁô;ŽÉ(;§a¡› °o¸ðHçNcGÀøoP’8v€L ª}P?PA÷ôÒÝ€¾bXb Ñ>à Ó‚À >40 ³˜G‚)“8°ÑÄÒÚ (í™cIžûA΀‹ƒÙNŒ ÚX:é‡×(ЉTýééý[ û q5]¾ú6é–Ü"Eà $ÇrÆåôÍo^ÇB:;U™,è òÔ3–7ÐÄ2˜ QØÑøÐ @$”D‚„☪¯]}œpB„Zð€û eAçd}ó‡Àþ¢.¸á4û¥ ¸P±mÐ0ïÞ~À1“/@JH…)"^ä^ÿfÖ¯µ'ð3ÕÓoùµ >l¢ùïÛîφ7vžâÁÀTí$À pŽó¥ì@³±J[½ 34"Yþîr&?M‘SùÁíƒÚl\~Zž€„0(©rÃPN?²ˆƒèEjDÐè›$¯¿ Ñ 6fªîꜲδ” ‘èð°¢–ŽÃÝN¢ z¢‡EÞ,4Áü‚![¹]cçáL¿Ê*3€áh¿¿ï îÉ“¸]£¨èרcÈ¡½fà†ò»yRÌ£±êó8#{¡éåI-ÝÈùWU›ø%‡§¸qP'OQqS"˜^CØ Ü'lS’6µ(K~ ®-”ø¾o:iúiežË¨¼Ð!Ñ|ýEÈ=Ç6þ£۬ѾAEœ[#Á ®uî€b$ l°À›vD¡‡9ÏËn>»=‹1™'íû@-Z;ÔˆB4±à¶#¡Hg‹“”{yM›ÇØÂAFi‹¹ý:øZ€F œ@FÔÒ ÷tF? ˜ÄkC¿d1ZzØŒ”;‰±À;£[¸I³¡7D E—lïì‡ðP¡=zv[³ZÑ›+ݽÐCjýsô•i §Ÿ£þ'ìÓ굫íIü õtÛþF=]¹‚Ô'ðèèø[eÏ~ßu×÷G ¡’ÆÒ9û1¾ƒv™pÎÆMô(Ø|å0à¼,HÕ¡5€â¡þL‹¿÷Ž6…çþ¡ÀáC‡J{[ëÁ¡œ¿Ò6¢i¨$Ì]ÉA)·ÍåvfyD°&÷§¥\v„n«¢ß¾ÉÆ}[¿·°¡äÀeçD"<›š¥j ÐâJl:¡`èýSá“ÊBqñîµä "@Ç`HõkC¼eòÍû”éù(šüGßrJbMô&à|=u Ðä÷ô#H0"d‚‚ DNÅZ–vC¬ûcÞ³S×@då9 1!´N‘Ñ;ªQÖsž€ß Q;cDúoð@硬b„ÀN^ðtĉ =‰Q(|îÂ~›Uììƒú[˜v~}ú4?¸ù@q½Æ^ Ñ 6z>ÐPý‚}X|QœXNá—¿¬ðçìd+.ìõèК†Pî‰{+(ª4K-7áׯÕd2liÝYÔ0º"³ŒìÌPPƒa¸tŒu·òB¹ý£Ù Œ„çdDRhI˜’>ß"2 ìL;ý“är±B‡yÙѸõµ«íIü õtÛþF“@Ô7Ús® Gu˜Í¡NLàÊ€6ög[eÏ~ßt `¤•îÞ„Þ.¿C|(„ŠiXƒ ´½Hß,')ŸS$¢ê$võ3™c¾,…óBƒ1yº €pæØ0£ ¢+x&¹=º{Â_ê,Û‚“:Žl©Eɘèã  ÷!²“KÓ–2¯Ø`ƒ7ÇäJ÷™õCƒ0UvQÀ‘îd8ÙÁ’?XßFí qF»†ØwÔa Æ1#{¡çœN¾„\hŒZx^Å#{ôóFe“‹FBa‚SŠ`lbÏøô¿aWæâD½NÄìÅø%01Š/1½$äàÅÐ4ANŸ9;ŸÙuaÒåߢTM`/ˆTz‡äz}Bs€Au¹zÆ&ßÉA»¢Cû’™††0 ©`=ÓÂ0§Á†‚D}¤§IN„zÚÕö¤þzºmÿ#qMö†L@ëqKìA;¡ïõ¶Q|÷í÷PÀ”}Ýé¹1ü$ð›G éþNÀ{°1{þwý‰)ÞæQˆ(ïã5¯àÅ@ s×ëkWÚ“øêé·üCñ‘ð_dösCÚž‘—þEC6ûël¢ùïÛîG!u>J„ì{`OÏü–ÝŽYÞ¶µ}©?ž®›Á AÀu²o¿D–êá]¶û%¶|$~T1¤z#ÃtŠÝ­²‹ç¿o¸B‘†š¢| ?ä¢MØ­­_jOàg«¦ßé^ˆîÃ0Às°ùRŒ@}b1ä£Á6Ï¡DßÛŒ¯ñãûñº}âìàDp؃0ày(Àdέ})I†ú¢Ó=2­_Ü‹P#åE¯‡ÖÙEóß·Ü—´ˆ7 ¯üœ1'µ"þ¶µ}©?ž®›~ဖš7D 0ì‡Ò&F-€@¸qô˜Wm !júºpïo£iÈìÍÏwj=jù-ƒïÚ¨ÏÁtRûðê€HnÌOˆ€ž"ÍÕ¾‚€îÊ —kÇÕaGð¨?œ–<ζã=ëê¶Q|÷íÿ?@´ý}vµ}©?ž®›}áÂÖ¡tÒD‡ÛçíbAžÑ¿Gì ´ õøþ¤;RÛñ´ {1ô7DnOè"˜.@&¢ô¤÷rFwu >Ö `0v“vQ·qÏÊD¨†d~ÿS„Ñý€­«ŸWb5‚~Þ#HzBO0&h›Ï$Û>Ÿvúëèù'nÓà}b,ID`±ƒÔ}½P`é§¢ÌPÉzз#hé™å_X±V0¾›ÊnØK­ŒîÞ· Lèã¨>¶Ê/žý¿çá* Þ¤õµ«íIü õtÛê8Þ€" C#¨ Hç9’fk¸¤b@ðE»à Á&‰‚mXóa˜‘(0Š]¤ÆªbX›Å! ×ü’cTÆ©S¦5Lj˜Õ1ªX èºJÙÓ¦5Lj˜Õ1ªcTƪ)„˜?¥8’’X ß²1ú]‡è¡è~øâcT¨Æ§–' bŽIý -ûqúLj˜ÕÉç&5A)þ‹¦5Lj»ïs„ÇDÆ©P@F„=¿ê˜`X¨ôƨEí¿ô¦„ë§ÈOÖ6t E1ªcTÆ©S¡]LtÜuo„Æ©ßDÃn†.5"Z?„Æ©S¦5Lj˜Õ1ªcTÆ©P•f‹±¢$LÔ8§Ož‚à]óFPŒéDü!—ªáXÕ1ªcTô³ „#,ü´5‰‚ÁÀ¦Ù,g`Ê0cª}-”_=û}oF™ˆ 2øœitö1 31˜š` ‡ðyÀì ¦S‰Ú-tA«Sc 6Aÿ,œÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ªsTæ©ÍSš§5NjœÕ9ª |TØdpþ–µ}©?ž®›}D|‚L‰± YŠ©êXvL9„Â` ‘ Ì À°ˆìÑÖñ¢ 8bmÖ¨R`Ç[jâ6¦ûîÚLìF(D|ÂÛlpzšr£sX$º#ÊFv INcw ؼ}'X "à2}NÃvÌǦýù#Zïd<(¦Îu ´ò4AÐ">U<÷Ð…h_qjº»_¬D666ô¨éøLJ»ˆútAöAH"Ft#Ó¨R_¸ô‰êOÙ´Ü*ÓÔú´Á;@ž ÄìbŒ 'j\‚Ú:€ÇRú`)²ÔÄ2ˆmOj7»øEÔŠÙˆðè°ßиA!”³¡‹†¡>1èô’*Áç&oRÞVg!Js\ꛄÀ!;‘‹öOŽÙÖe@~A¦IÑ’‹0Ä„"4žn€ý¯öUq+2;€$’5o‚Ä  òL4‡XÛŸ¶Ê/žý¾±@ ¼™u3µ"F$™ ædD”æ aÀ : Ätët@ÑwDæ$N#°ÊA©S`ï[Z¾ÔŸÀÏWM¾àÃB’5sìá!ö‚NXvE‘ÃWH„ÇÔIàL>® ,Ka=IÖ`‘€g#p¶ÞÜÜ›Ê8"0"©A^’ùE’pçp›÷£|Çô£î¼¥*~¯up º=˜ö`‰ú žÞ~r}…ìZ÷(fFœ¡=DÝOúGlhG¥œJÍØ‹ Öæ¤H ¸1*NO’m—€¹h™uFÈ*ôŠ“À|‚ÑRZ™íÃT ¤—`LÑÓäé>clÌ‚}Ô„f²£Œ{CÂ}JÜÐzlà$}Èrœ]'ä#7j[ŸÒrPÀÅíI+~ƒò¦nâÕѾ¸Ôf÷ŸÚ¾Eóäi:Pí)ý«lxô~΂6ùO;,“…ÜFÍpQƒ:Cæ÷\œF,„Þh`ÜbP­É?A£×T(óPëˆ …ê ¨ k.O³²s\^Øà|)¦u.oÓ ¸ÿ[`7X´l ÎªÈÁ.†ïãÐÆh׺JfkÛ¢PXÇ­²‹ç¿oùøš]­_jOàg«¦ßp0èã20Š0)š‡.Ï{‹÷uJhêe@ˆ{9¢ûéö(ü] ]P _›ôмQ åC¦k|–¨’ʦ~?I£  wNdÞ àM†Òì™äŒ8jï $¹ (”e¶S² óHI‡ ½œ"\ú¢ì‰ù3±þ‘ÍføAj¬ð¢§vDÊ<@×ÜÎ~…È]ˆÚ‘!œDm@ 'TþDÔxˆVÉû±O…4-h9ùLdìF7C£!p €òLĉßFD È $pº‰´[`«>SBEª$ ä„>‹cþ% èCìÊ(ÀLƒàý"°$ð›Íá™CDß(¢gú§µf"™S´| ‡Ô|ºur_ÊVbèSÃCV) |Cö'ªIöÛy|¨¯2ˆpÚˆvl@Û >Q.ÙÀ}Œ9¤”g¸1úZ¨î °—ìP` 9Ox‰ÝŸöT ͸GªÂ!eõO¹ZÉãØ“~™+Ó'‡w Љªa=!ÄQTƒÎô€320@¸q‚Ó.¥>‰õð¬°p gŸ¢¨/¹Â˜° ›òšä$©Ð/Ä‚ehžà ܨ2É&ˆ+‚èõd{‡Ñl¢ùïÛþ©l=kZ¾ÔŸÀÏWM¾äuËBšâƒèKRD¦¥õ¼Q7C;©Ô X´6L±ÂIª:1Äۦߥ)3·`€ ‹\Þ&ÁѾqlš<ƒ]“ÿ#»T.œlTZ+ hëBˆ£fÈ€ ½‹w÷D²} ‡²ARHrë¢ôŒ +…ˆGbP°Ã±-T~Ú°>ߥé4SÂ|d ~àS%n†]ÐÈ tô(q :a)66pâÊ€%ýˆr oBoïLR–Y¶Сs§îótGûÖ’m‘${ž8tÇÐÀ6 ÄHÔ[§’Â'ãÊÓÏXÓ@ BApûû³û£I"$़"Ù[„!•€öŸ€ ¢^V¨Jx@e‚ТþA†ÅÙñ.ǘGRÿ ›¸Nm  ™jH½ËÈ ,Š­vq%#ÀLB ªJEw|‘.U4|½2FÛqtžLB$l£UpXn"’Þ³ÛÊdn}`î¿B#‘쌵ìËÊ*Ù¨{FLH•%@=“²(˜. …8.Ë¿t2Ú`»§2¡l[ØS ÇTYPàÀm^á±Ò`;ô[(¾{öÿŸAÃKZ¾ÔŸÀÏWM¾é‡À(…*™ O°—ýRŬ2pô,Wx©§‘D¢ÑæÞ™¯Ð,7ý*íná4­Ð4":¨‚Å¡’ƒԼà3#~ë™!EÿÜõ‡8–é8ÀtEú$ííèæp ¡6õ‚ ’îPð ĵZÜ"fJ$#èé#Æ›…f_Ѥ¶ÕËV #¡$@£·øA€Fè@°B1’s€ÔÓrɧE€úF‘„èrLY‹Žu(Àh>£’GØ¢€™>§aO@›[&ˆdŽÎ辋eÏ~ßô­zZÕö¤þzºmüõöq÷LH¡02´Gß×G Gß“Ê#{¸³Þìr»†ûG™ØÐàè!ôG÷û¯Å¾“?ýåS±ñö‰ ‚DGð-”_=ûσژFç6¥­_jOàg«¦ßÃ…‚YG­þ£tCóZ>>>Íø™×S‡³}§3U°1“’ÿEò™×Q·ÒP“&©›ùVÊ/žý¿çÀ9ááÈäû}-jûR=]6þ]´WN¼…&2E€l>ÈѾp®Ìÿ|h8@åô½ÚœPÇùvÊ/žý¿œÆáOq³tjE¸v=£èÌAhH Ëè$ –úœ;/[eÏ~ßtZøèB-;è§sF%û"ý³ïÔ˜F‡ÔŸ‰¯¨ ãàÑïLfãÈNí ý¹ßƒ ;1C ÞnœÈUH^1#úNMÕ¯Ð@F@qè'¦šYˆØT?¶OxµDÊ “dR@`rXP:5ú}ƒbP™Ú§ù2€. Ô|Ÿ Œ‘µÇ K›°V8Ô"àæ)ÔC —-/ôð܈vCqê<ûØ-²žC-. n6¿à‹9ÇÜ7é‘F`vøú¡ »‡¤Üåkê\)þ¢›F/@Û)Ñ$/›ÍúN$Iw½Ø¬`!þîþýX1ùzµ«íIü õtÛïFÖ8Q/@œƒ3$ë5æ‹oPð-à›E“.;x  Q€é¸>ØðƒÀ ”Aúéî‡îZ3âΙ=×IÒaðȈ™³W’³=C}XlêO}oY;£œ4IäEH‚àê£ä'B„" .è§nÃ0 K ;„¬æÇ³­îG=ˆ"_Ö2¾áí— Ä›““o0ÌØ&B Á@#é`qbŸípذCgÑdÜ^Þ’AŽÃ7¨ˆNJV~…(Àâ ݾ‡ÎqššrÏ N·n #ÓD#ÛrMŒxîHŽþ3–H½ˆj‡„Ö ‚¾ƒ š…™€Ø¶ÇÔ$°$ ©Ÿ 6Çhzÿ™ô[(¾{öû„€$À " åÇÌ€ ƒQ"Zi¹ú M`ØØ#K@oÏÉ tÈӫسºº ¯‡ñŒ0 ¨¾`„&÷@Š*,hc-óŸ(Ÿ1„¿] 2v@çP=ÎÇ 4”•g¹}܉2QÔ“cÔ‘ŠÔ_î°É ”>{ Ta}ì'‚`„î%5r÷1õi§©‡•xð†–¤öZ*éõ„Ab}Àú²‰MQpËÒêä÷ã¤QЯØ7¨ÉÈý¡mÈ…ÝN‹“2MV“nbã×-,~^šÔ_D_ö©Ñp^›{©Räz5#pÂÖ0÷ úe»z"éi?sÂЩ½ï #Lëþ¢ˆ“Á^× †¡ï|`Eö’idý‘Æxµï‹t!\»¿šˆÛ\èlÁ_\’¡>âA‡eÖÅI“Ep`îD¿KWýÒ?(áCßêBÖ¯µ'ð3ÕÓo¸Pæ]5&áQN¶ˆFÖÜÞ×ÂyfBN`nÉÓ–5}x:ª÷eö‘ê‡Þ«ê€iøìé„tÒ€NT>P5kÜ}Ñ:C ƒØ¡Î˜‰ŽãT!MNhð¡~ù:_WTU¾íA´I¢ó¸ †¨uŸÙÅ…@ìº6Œyé0ìž2º8.Ÿ¤_MB€b@©XÚ= ÙÝBPÔ{ÎÄyì'QEÁÛ‰å½àèg/ !Ðtdˆšg>aîŽ6uj´÷/ëáÑKæb ãû£–”HoLy†«B?HrzH )ȧwßþ…­†ú=`q9¶ú„ÇÜ’‹U¦-[¼†A°$&:èeÓ¦oCÜ|"r¤(hdiÌ]B2ê‚GéÔÕ”¶ô²z;E®ßaIíåGÁ³eêíà„ëÉ3‘@<© z’Š+0šPúªÇòÄLÆóÀM¦d>¬´Þ÷u‚1;˜=Ór` EBÀ$4‰€óÇŠ ˆ/jà’ôÂ… æ>·=Èó‘’ t»“ì_Ó2Ýøt”!”á´ÀáÙC´BN`lgô:¨Ü0¾À \P-!Kwp'¤/ÀÁ'ì$KééЀ†01µ6gZ^íbbI:æ¡äâgm¥ô-”_=û}Í"!®¬ÁÈxE@4΄@=½øÀ(}O@‰: @sXúQ,¾Dqö?êÁР䢾DG¨ÆÆ¹¥Ph‚)Ø·I”HÅ‘ØêP  K»†!ˆCgêØ®¢³°Gh»g‡é |í‹HÄ9UDÂ@ÊÀ-°A#æíA(uDùøT±ÏoT/”>PXño(·[ïô´ 4}ý1¸„¥ QùE¸|öí8»²'çÔv/uAV’˜µè †rþK ®¿5!(4ƒ ´_a(ÀiëòØ<:–¼:¡œˆA;jÈì"J€+’nãía~‡2…R~àLˆHó&þ,iÐOÝS2‡%{0‡¡hðõ­‘ò«YljÖcûCgÒAÑ‚ƒÇR‹7oàÑ0D¢pA Ü`È"8õa†nèÑìç~€-Z|žÞƒDѧ—¡VFZŠÝ¥‰Xúµ«íIü õtÛîFD;ý¼ ã“§¨ˆÌ ù&lhüÁwM é~€x nƒ:0h>“Ž‹<ðšzÿB1ˆ)Ú!.FÑÒ'OûcJ–¡Çè]Ÿ)÷úôà€ÙÈEöã7tì ô=ú9ïõ€r1ÈŠ‰tȰ؊*¶„›cm­þ×vVX±¢°£zr *ÓM‰B¥BµÀòãc@=)˜|¨þ€à#¡þ ù‰rúN¸€·œ uÓåV‚D 'ÝL>p(…È%<:”@N…Ú7ËéEPbæÅÜ#.zŸ ï°n†/-™EO°!‹Mç êÈ1žKÎ}6'` ahR±ÜTD%¯ît‹ìº{7tÓ‡.Q lΩț³‹û_áz©æêZXè PH&ô¤$Iž †ÓC—D/ÞN „Èëƒ#º’±Šш 0$nÔ@ÌtG¨fÂ~áG âÿô@’ì\ŸT[¾¬aˆ˜ FÐp6‰p舣‘VVVVVVVVVVVVVVVVVVVVVVVVVM ‡»Iê­­­­­­­­­®‚­­­­­­­­­­­­­­­$Á™ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ<Æjz[(¾{öûZzA AÏ0Uàó€&'ÙAL¦?´4ZèƒV¦Æl0(ƒþ'}<ÓÐm¶…)Àïé4ûEæ¤f®Û@ »Û}ͦÛm¶›m¶Ú"¸ŒÂ`@VÛm¶Ð|‰E„f F8`à@–GfZé4ÔaÀG*ð¹~—,I€óm>‹m¶uNˆŠAÈ„–” féÑ”ÑÄ û:û¦{=èsô[m¡vLò˜&O›g€~½0 zëmk/';C±;(9 ˆ4³¬Ð2 ï‘×`Dui" Äa†êNo MÇÐJ™› Ô½ŽÇª4Dnsm‘ì¸h}ÅŒÐuCuq„.±¢dPƒ¸¥QZó„o „¢7tQ|ìÔ¨R?)¨Ñ ¸¡ô©öÜ;¦kÜÀˆžtV¼Ä!Ûè¶xG’NžèB÷vQ$ì׸>‚îv~“Pq܈uSšD:§Db8,Ô_¨õ¶Q|÷íö#Œ·É¹,œÔ §DŽn€ˆ.èœÄ‰Äv ,’ÈM‚7qËž BÓ$fp2$i"¢ý™¨¿Qô H €&[ÝFƒ(À”ˆ ìGÀÄ!Ûè! 3ÜefKCâ§ÝuKÁKc€OqôEÁÜÛ'J†Ý'ª—RyD÷²P¼@Dê¢a™x #̃‚mº18) ¶ßCry°'B†Š!€\†î€ÄÆbÄí#Òžãè.÷aé0…ȽѼ‹M@¸q/¡‚ Gc‚œ·uRÆ3:%â€"D¯¬”/Ñ:­pº–eEÒ2DêHI`5R$¬‡‘NÀÁÜ &'t—ŠˆÄê>"äÀ$¯`= TO;5åKÈÖNÿ@V;–À •Ç„ªtðY¨¿º‘zðFŽcôZÕö¤þzºm÷‡™ï:CwMü‘´¼„{¨‹¢HØYèAÞÉõ ‚E’DÂÐÉÒ?A.qèŒÃu šã·@²qƒÓ„@>Žðºw‡xJv}h¸Å¢3UöìEq¥½ª€‰»Ç¸„`P”T](d#¸Hm}jù ˆöt'û´’Ū¢)6ÄZ„“â‡LàØuö} ø´BfPºâ€Ô“?âF,Ïa'Ð CNœü”:}`òD'g( Lƒh, º‰àŠp‰>ÀXîŸ<‚gÀˆ“¯³èÙÑyÝtɳ&Äbq€‘פSt¨ÒÔX2'™³!€”ŽÀ€ÿ@YÁ çV;9ÖR Ô‡< Áá> ÜÁäYº"2h"ßD¾-™”¡]@“O~ÈÀeܔɲ$^†êxX6k(ý‘àÁa4¾N@f²JÚ¡¢Ń;÷B#!€B-ôG§K0æD &pDCq D7Ä` X0ÔÒ1NŠT¼Ô 5Â#Ew>S‡Ï1 02‰„ŠH­.€R¡¼Øu °jâCÖÙEó߷߇£ö ºz vEÓjM]ŸÌpâ:A´lO'X`öú7d4‚ïò·}O8†#ç"™`DÆZE cHh»$:°ú )ZÁæˆé‹¬AÈ—J§*l„KPˆ’îˆ/bZÓDº!È&?A(œr¢4n‚+…M„L‡©ðˆK€¹’àäÊ3,#Ïö¨ £à„DË“3‰ƒ‹$cjà?¤V‚rÀ†OR‚RPc1“ôG ¹ˆ!Ô†7Dd`F™ „èf–† @pšJ3,#ÏöÐ5Â#Ew>S9¤âÂc¤4Q˰“t@ˆNHÑúå„ `& oª{¢1Z.ÐB¤ar C³n¡ÉDÉDz€º0nDL¹31ÐH˜0á7¼° ‰Žw Ðtx–¨ðf­:{=F¹ÁöP/¾¢@‹AïÔW|+ø‡ 5‚…G$ B†¨J&H2#Ôyžó „7u ÑÀ$‹ï.¨Š“ŒdÒ±)"i*¢ò‚0IFGñÂî>¤h¹Ç¢3 ÑÑlÉÆ@&^ð'Cgj0tvMäñóÁ„]ˆêžZ3"­­_jOàg«¦ßô6Ê/žý¿è­jûR=]6ÿ¡¶Q|÷íÿEkWÚ“øêé·ý ²‹ç¿oú+Z¾ÔŸÀÏWM¾à—ž¼v¬ÔØn2Åæ£| œ…ª™#»dNÍí´Ì9?3ãeÄEâˆ-¸NdHð…T’_\d$ gŠ;Œv<€ É<.2ˆ¡%I6RI72D¼‚ÝD4-Èý"q`?@‚I‰Lˆ#ó°SÝ8ì‰!C?ºÿjs-¼a4“'‡˜»„ök \Íäˆì‹…ª¸á·Gi³Ü ¼:|¡¡Ð08rƒ¨¢,Ë@É?̤ÁÓëÃÈ¡¨zH ;g ?³ }CÕ€ i'(ë:¹ölB­@bÓxEa’Q²©¹‘p$ã½l¦D‹5‚48TèÍÔ~„Œpš":´ì˜øÆÑ׎›¢*$˃ˆÂæ„^Ð.KD™'‰c6 N`ÿ?l¢ùïÛîI gˆ;þÈ8Y3$kºo÷Æ£ÊȱãlF=/c¡ÉwÀ&Hhö‘xâ˜GGZh@ƒá‰ƒQÕM˜3êøAŸÜéKÑ:´· [c0A$ªî㿎…„ÆY€'í /#„øRnC7Ú: ª~tØ"ö Ôä@@xh\„ÑÌ@[³™z¤?‹€iˆ:¢8H €!D€ƒn0™a¹‰ƒ¡ù“Å&/ÙüÝ7š(±ˆb]3Ñá3ܼ¶D@„€˜ÐõBψ‚G¸S6%¹/T ÈŽmR|rs1k¹ åÄ“‚‹À Œ3‚ X½É~X¤·›{(’®]Ì :¼¨ž¹±Ž¨ °õ`BÆ‘x bb.ú¦‰.1&ä3Ø2Žðx‰s&³¸W—àÌÞòi¨Šm‚ÄÇD$l1t#RB‰ö29Tâ™ñ¤Ãƒ!ȉ5I! ãмAŽfMíBÕÝÜ•â7PŽãð¥­_jOàg«¦ßq©Ê÷2 .u%¹(M’sͤšfi\Ãb….ÝÃ@¡>ˆÅ2Ì^j†"I 4‚i8fl1Ms$zN¨»™û! !(¸c„Áâ'ÔÔ C³(s !1ÄH™«÷êhz§…ÄÀ·¹@(É‚7[qÁä(q(#¡Ù¦MSøQ Ž"DÈõEli°vÈ.¨bP_"ApK€Ãà§«aƒ™°°öôtCX¸wú¿Ê \“'8ºƒt!@œx8¨FÎK§ 0é }^¥SU˜@\„HÌ3€ºvaÃì;~ÊÌ„D˜h˜{(E3’L`šÀa#6e52‘8ýÍŒ±.Iš“Ç[(¾{öû‡ŒîÌ †;ÇáϹE&" ËypAÌ0A´·ì ®Eï=¶bÁ¸¾Å{Å;³~“ˆ£XÉÞ; ¦¬±8 2SQ 1œ €³|“‹wé$žîÉ %„éñ¿9{Î8-€€Xh bÐ0i"Q˜´ã4FP‘·¡F¿ƒ¸M÷Jwö.¢•"€$PÝ vý”2À€€CÁ¥èÃ'´HŸéGÀ2–"D$XÃêfˆPX÷Bˆ\—(¦AÑ"TC¼LÌØ(žt䋬 j3µT_ð‰¦ ÑƒqœÅØMG„Ä`1ô( íAÄœš7+äU¢%ž¡9™/ûS”* …ò*Ñj: $ÇÝ>&á‰`&dÛö޳z­ J9 0Á–䈂nöAH ™®”É=+L|dátÃÐ |HÀÁ/ÂÚÕö¤þzºmÿDÇÎ~ßôVµ}:ªêº®« ]Q¿à@p˜FŒ™%<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§• ÌMØŽ žV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓÊÆžV4ò±§•<¬iåcO+yXÓʃ @<¨I‰ûFý?À˜ 1,‹ð²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]Â˸Yw .áeÜ,»…—p²î]ÂmÇCáD%OŹêé·ö%_VÓ Qºêz¨ns9—3f/Á©êé·ö%­_QôøüS$‘‡B 4„SÕÓoCÞ¬×4H?²p…²jyƒ1’?éÎMšãBªð•4h¤Û€2$Ú Tžt}ƒ£1˜º;°ƒFPM "; À%„ ¸ˆÆ“P¨Ñ3…áÊö]Ÿã`t’"2Q¢²ž¡Õ!ÏÙ‡#QýmkWÚÀÓÕÓoAÞîãË š% ¤TÎ5ùñ°t §½XˆG¸M4ãÒíú›öƒl´ÚAK¹g—¹…$G&c!)M5_¾ ,DzÝE&Õ(óQ‘ÕA· ”îih¤E¦[j¡…‘ iŽì€£xÂÐ@g_ëkZ¾ƒÁu»S±uû[± ÇØ ÀÏWM¿±-jú2dÉ“~ zºmý‰kWâç«¦ßØ–µ~.zºmêë 'y˜è˜!5aS‡øAÃÍÇ¿ SAçHh£¤žQ0bЂÿ¨yVØm"湸Ì$¸w&M–`bæg-¢Ä‡mb¦‡Ä fä3PTÄ%á;${#¡pë$éL€ÙÔ;d3bê?c:{¸Ž{"D7$ì™ø,¹˜Ü !Ÿ¬Xî³Ü}Ñ 0KÕT2‘t”œG ÎȇFÚЃ$ôŠk± ï|;<7N6P0@æ”CˆVƒ›FƒÕè…O»ËMÔij¢¡âcˆ;ì¡eú ²öÒ³EÄ>°“Ä­ …âwF³š0(d‚ " Û:3¤¡s)¡#{‘ ΈfÂg‹ ŬQƒH=%bÇWYµSl8{Î$™¦+èŒBM.΃‰[‘Š ÉËK ;ÔØ°\¹L¯P– SL›&…P'¾¼·ž‰íá˜êƒ‰µ ‡Ý‰€œÅ‹| d¢W’Í C$id~ð'$‘;48À7~É’t_ tåEÄ,F¯®‰§£œÄ$Ñ™Ã:"õ‚‹’.9$AÐ@ćÌ“¸.ÎKšeÛáÚˆ@, ñ1aå×x~'´:!t²Ì‘é¢Ö¯ÅÏWM½OlC ë’%ã¢uƒ ¼<øÇŒå0‹·vØÑõQ¿+gpo2=$¼Ââê#õÚæ4¼"&EÐH‹Pàf}P’OŽbþþuW€j&Á`ëÀ_H>¨2pBòdI‹wÓÙŒäQ˜âb%Nz‹k 1‘mp Bp˜¹è£i‚òÈ´ÂJŠ2g`ßt&h&@cä‘ Dð  _ ÝLö£.)‘#²€? ‰`_ÎÉ‹ø‡h0D EÑøEîó&6!¦ftäeD)@û8œæ3bë¿ N‰µFRE›?Å)‰ÆM %î¡Ù(A@‡Ûý%l28ÛuKf+.¬™{Œ Á‰3¦£>ÛîJ ±gº+zä5ÙÀ™ qdÍ9 ˆû'‘øP „àE ¡”¶N:¤дsæ’uÕù²{­#ˆ<&ƘÍ>( W€ÏÑ; ~`,e0ì”ð1i}ïÙé}ˆìýï…õPp”PpŠ.m¡0…eDç00&- —B¥˜¹è‡W'¸”XbäðHA°:fD_‘Á‘(Œÿ«°iSKSÿE­_‹ž®›bZÕø¹êé·¡8’Bu ±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅЀÐzZÕø¹êé·©D{z^jŠC7bQÀ.»2ª—â\Ýôy ‹ çÙ †r€"D¯ý+> XvÀ)ý!—(À—•í(. ˆþ+> XvÀ)Éøž‡Sì½.Œã͉°dxô(À’‡ðQ #tEr€XƒQô÷,„ÒKøÀÙ²cë?[Z¿=]6õdHtEè¬ÿ 岋gE‘L6Uø«D˜¨ºo½qòp§»3;Œ‡o †±£Òî:}ˆ?€ùI ÐA ¢°H@Hcü(/ˆ!÷ê;)l[>`£·…FpØFr‰ÖeÓc£60& ®Å48F9%Æ‚pE30ü»-jü\õtÛÖ2)?a¼ a†;g!#1Ð7¡0ÌB˜} ¢‹µâláã$0!@<έg}Ü¢ô IhØ£$cØý) ø °×íÁ…Vÿ¥"Ÿ|„Î61=ÑQ°HïRR´˜vp€Lît‰ì#dLdru—VÚˆÁå`‡áü2)÷ÁLãcÝNŠNt’  ;lä"~‘i-°Í¢&29:Ë«mD`ˆr°HCðþapÄʧtnÀCà5w.‡Vl›ÃǦ(76Œ‘ĘpXÜËl•‡I·™î€ ƒÓ¹d ÇšÆÍ›IzÚÕø¹êé·ö%­_‹ž®›z‰$'R XºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬] ¥­_‹ž®›zèìT²•“ c9Ì"ÅBÀm„!î!H2~ F$•(ª&.C ÌP£p+P‹œþB;}”(%3ñNCÆîÃþ¡þÚš±(x@rmnÅÁ‘ÅgØT ÃxOeŠÝ‰¢‚.<ŒdPë‘"ñK‰„Æ·S¨•XÛE:8Ð(B"Š9À,A¨ú{–Bi%öRËWb;±,ÅYгf*ÌU˜«1Vb¬ÅYгf*ÌTf zÚÕø¹êé·«™ óˆåô~„f‰€fÒŠ£Tt Fªíè` !ÖN=Ü‚ ê Õ¼OÂiÁ.‚:™ÙÐY¯{™ÜìÄÎ ‰Í&€ˆLЧ!@9¥Á2äÎJ›Õ` à„â Œ~¤å.`‰0wiÿLJ¯ ¢q24¦Š`–NÃL0rc¸N‚2IK0šCXÑ„iw>ÄÀ|È$è ŠÑX$ $1þËd΂@¹$áŒC¡1À+B%ز žì_ Ò,D™!¬hÂ4»ŽŸbà>dHtEè¬ÿÈ´ÑÄ»h!êNF† Ïéì!X¤‘I-ÈdŒ™Á÷Ø9uÀs`uÊ'Y—MŽŒØÀ˜€,N»Ð áä—f ÁÌÀOò,ºmëkWâ竦ßö‘1QÓ¤‘9ÊŽt8MìTŽÐ‘1‘ÉÖ][j#@C•‚B‡ðȧßa3ŒOuðO»RDm19âÙôG‹Æ@ØQ1‘ÉÖ][j#@C•‚B‡ðä×ec£ –3.XÌîLP8 € ¼í´'$·k×P 1בÅcÁB£hyÁ{WèP&E”t-ó P§ïpc0F¿I¾G¾ï‡Ö±bŋ̈́ RÝ`Ï+yX3ÊÁžV ò°g•ƒ<¬å`Ï+yX3ÊÁžV ò°g”C3‡­­_‹ž®›z¹¯8€_GèFh˜&` (ª5GJj¡Þ† dãÝÇø'd„FHMÙÀ$â'gw÷^w5E¤ÆÒH;bò˜á E¢°Z؉3Mê°pÂqF?Rr—0D˜;´ÿ¦-˜Â[ >I‘“¤€8ƒû û½à"Æ¡ÓäPLÆx£®¨â© XKfl „A:&ëŠáCC†íAT d#^V"@X뀺ÑXBL†äPLÆx£®¨â© XKfl „A:&ëŠà™Q’$Z›@85K£Õ·µ ¨¤Ùâ‹Óó,â;,5†»kÉÐE5¨ì˜ôBlYPy»›TϪÁÔƒPÄ".H“Ûù Ý6õµ«ñsÕÓo²)PÁ@’EìëÿÏüf‹êˆAžA¢=>t‡l#–Û­bÅ‹,&™8¹h,˜ádÇ &8Y1ÂÉŽLp²c…“,˜ádÇ &8Y1ÂÉŽLp„.@Ñõµ«ñsÕÓoBqhAbëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹¬]bëXºÅÖ.±u‹ @ ƒ¨ôµ«ñsÕÓoìKZ¿=]6õ 0Ý‹ˆØÀ9¢zhAÝSR" ™ØÎþÕS¤7u8”e eLUÀ Q-²1@a†[Ú A~ˆ›læލÛqÎ>ÅÌ7ƒ<±äîˆM‡ ìáNï&ÀàVˆ¼ äq£) 2c* 1,ÏÀj";¨j$“ÖÒAŒY4TžUZßÀnÄdí_þ€6&†Ö®¡Cœ£® "?Œ,š>í´'$fAµÕ6d ö@¾$àƒ#üCëR ÆGBØðP¨ÚpSø§A¹ EEœìÎpŸ¼}ÁŒÁý&ùøH¾BÅ‹(k½æ;’`Ï+yX3ÊÁžV ò°g•ƒ<¬å`Ï+yX3ÊÁžV ò°g•ƒ<¬å`Ï(†f[Z¿=]6õaAAð"CDÅ Ò80‰‚ŽèÞ)!p„IŽz¤¦Ü˜6ÈÙ­1„ Ði0‚©‚X!‹Ì†$=Ùº|ºÃ¡[“É5 EDäˆ bI¨ˆ¢Ñ ‡“ F‰Ÿü%Ø?Ì…ÉÔ’Q (s¡Òz¡ÂV$H4L7Nh´û!’n¦ÿX\ ,„Q@IÍèÞÈÝGt‡ßqÿ@ËÉkç§©’<1ú1x§È ˜ŒñG]QÅR°–:ÌØ‚tL×?¨"È;¬†n‚5%Ct^ñwÑ‚|Š ØÏuÕU!‹ c¬Í0ˆ'DÀqCü( R¸Ø@5žÊ2D‹Sh£©tÒl.ÐQÛ¡®ÚòtMj;&=›TnæÕ3Å*°u Ô1ȇ‹’$öþEŠºmëkWâ竦ßÁhæ'·f”þƒˆ•»RBO¿ýÏù ÿÆh¾¾¢!<ƒDz} éØG-¶?BÅ‹+k½¢f`L˜ádÇ &8Y1ÂÉŽLp²c…“,˜ádÇ &8Y1ÂÉŽLp²c…“,˜á\£ëkWâ竦ބ¢ ¸íá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^ÞíáÀwßÒÖ¯ÅÏWM¿±-jü\õtÛÔ64Àv.#cæ‰é¢5uMHˆ(2g`o;ûUNÝÔâ>PI”2@ •-JÀuÑ!‹h¦¸€$¼°§Î,ÃØ/:#çh›0GZ ”bXe8'ñC!mé܃ê`ÈêèÓ4-Âsè€q`ôâf·Q8]÷ ˆ„}SL€Á3›Ê׎,9 ¡CŒ“w ÉÄ4Ín£:(p»îÿ xû‚pÒA¤{EHå 99nPÐB b1#±!; K6àP2gRw8 ‡3DÎäwLü´gmšzÄT+8€ìôFè©È 2VÁ[l°VÁ[l°VÁ[l°VÁ[l°VÁ[lbÀIíëkWâ竦ެ(2>ƒDHh˜ DG0@‘ÝÅ Ä.€Âoé1ÏT”Û“Ù'0" áÑEžšF$"IƒÅ3&òç**4ÑÁÕ“¤‰q&#^(¯ävt,)0ÿN,0BÀ$“@¦Þz•1nlhÁÌP˜"LÖ¶Íã!x€Ö0IrAY8ÆÉ™ßÃ<‹ÊµK>­ 'Ì4ÀŠ@‰Ùæ o:Fœ`… ‚$ÍklÐN2ˆ c—$Õ“Œl™‘müˆý®¾rq€3"¨&“H¢ÍlÐЧ9wâÁ‹™’Öõe¡£õEÁâ‰0v‘¡Ð#zG}¨D¾Š'è.ý>‹-¿ÄºmëkWâ竦ßÔÍ^>ä1œ¡_¦ YÃ’Ãw¢-ö—S`&­’¶JÙ+d­’¶JÙ+d­’¶JÙ+d­’¶JÙ+d­’¶JÙ!ÁaëkWâ竦ބ¢ ¸íá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^Þíá^ÞíáÀwßÒÖ¯ÅÏWM¿±-jü\õtÛÕÁàL8ˆ‚`ÐJ)éH¤1 hm£ ÉÜ ŸÂ2™1¹ÎÉÅŸDpú¼Š 3×þ´P@Ârlô„1Xw'Dâf·Q8]÷ ŠÕ2šwgŒ%‹˜'9i'›öN!¦kuÑ@ó…ßpÇønÑmÏ ‚æ$ ñ¤`9$*Qšæ#;N’͸ ™ÔÎ!ÌÑ3¹Ó?-ÛF&ž¬™$7VÁ[l°VÁ[l°VÁ[l°VÁ[l°VÁ[l°VÁ,žÞ¶µ~.zºm곂Âã¶<Œ6E§½ûEÄP'…I<2-4>….¢Äm…8Äy×Z¦:À¸#åo-vA@I£!B`‰3ZÛ4Œ…âXÁ%Éudã&d[Ûña˜n&ë5E ÈL¡B`‰3ZÛ4Œ…âXÁ%Éudã&d[§ø(dcC`KÄԢݓ! 1Ið9p„bNÌ·¨(- ª(Iƒ°0Ò;í@‚%ôQ8GAwéétßø×M½mjü\õtÛú™«Ç܆3”+ô¾DŽbVÉ[%l•²VÉ[%l•²VÉ[%l•²VÉ[%l•²VÉ[%l•²VÉ[Z¿=]6ô!$=Py,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?Égù,ÿ%Ÿä³ü–’ÏòYþK?ÉàjKZ¿=]6þĵ«ñsÕÓoìKZ¿=]6þºÑ>Cê2ƒtA2Ò#·®ázýþ‹Z¿=]6þºƒ‹»Ájñêé=ä5¬PdÇà·Ðµ«ñsÕÓoëÚÃìHŸ]­_‹ž®›bZÕø°rGƒ¨Ug ³¿…Y߬ïáVwð«;øUü*Îþg ³¿…Y߬ïáVwð«;øUü*Îþg ³¿…Y߬ïáVwð«;øUü*Îþg ³¿…Y߬ïáVwð«;øUü*Îþg ³¿…Y߬ïáVwð«;øUü*Îþg ³¿…Y߬ïáVwð«;øUü*Îþg ³¿…Y߬ïáVwð«;øUü*Îþg ³¿…Y߬ïáVwð«;øUü*Îþg ³¿…Y߬ïáVwð«;øUü*Îþg ³¿…Y߬ïáVwð«;øUü*Îþg ³¿…Y߬ïáVwð«;øUü*Îþg ³¿…Y߬ïáVwð«;øUü*Îþg »¿…]ß®ïáWwð«»øUÝü*îþw »¿…]ß®ïáWwð«»øUÝü*îþw »¿…]ß®ïáWwð«»øUÝü*îþw »¿…]ß®ïáWwð«»øUÝü*îþw »¿…]ß®ïáWwð«»øUÝü*îþw »¿…]ß®ïáWwð«»øUÝü*îþw »¿…]ß®ïáWwð«»øUÝü*îþw »¿…]ß®ïáWwð«»øUÝü*îþw »¿…]ß®ïáWwð«»øUÝü*îþw »¿…]ß®ïáWwð«»øUÝü*îþw »¿…]ß®ïáWwð«»øUÝü*îþw »¿…]ß®ïáWwð«»øUÝü*îþw »¿…²dìôä†qOã ÀTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTUEQTU¢fÿÜŸÿÚ ’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$—/'¤I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$ši ½Ã<ÓpÂss kÁf»˜O’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’–†Pd†™ ÃÚ§º"bKæ-釘~‘›’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’–†d†?¤C$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’$†I$ ’C$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’$†I$›mŠI$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$´’I+m¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Û‘)+m¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Û“i+m¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûd’I$’I$’I$’I$’I$’I$’I$’I$’INÛ’I+m·m¶Ãm·m¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûgÿÿ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó›m¶Ûm¼Û’I+s0µº–´êÃûR Ͷí°Ç·œ¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶ÛfæO=׎ÿÿÿÿÿÿÿÿÿÿÿã4¿W“›/ݼÛ$’k}• šØWõß½ ·i›ºÙP¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶ÛeU?Ðo[ÿÿÿÿÿÿÿÿÿÿÿåïã›7°å¼Û’I+bV5¼â„« Ég­¶Ûõ¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûgÿÿ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó›m¶Ûm¼Û™+m¶ßm¶Ûm¶Ûl&Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûe¶Û­·ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóI$’I,Û™+m¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Û™+m¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Û’I+m¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Û’I+~Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûmµ¶Ûm¶Ý¶Ûm¶Ûm¶Ûm¶Ûm¶ÚÛm¶Û’Ù+w×ïýÿÿ¿ÿÿÿà~ÿïÿÿï3çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ¶Ûm¶Ýÿÿÿÿÿÿÿÿÿÿÿÿÿÿ[m¶Û’ù+v»À>UÖ [û?´¤4%‚`EÇÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ·|y Mäïÿÿÿÿÿÿÿÿÿÿþÿ[m¶Û‘+w»Ûuóì¼¢¾üÿšNwìößÿ¯Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ·ü¼ÅûOÿÿÿÿÿÿÿÿÿÿÿÿ[m¶Û’I+~Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûmµ¶Ûm¶Ý¶Ûm¶Ûm¶Ûm¶Ûm¶ÚÛm¶Û’I+d’I$’I$’I$’I6Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm·òI$“m¶Ûm¶Ûm¶Ûm¶Ûm¶ÛÛm¶Û‘¹+m¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Û‘)+m¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Û‘É+m†z»mŸ:ͳí†Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Û’I+mÏÕzaëm®µ¾i§Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Û’I+m¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Û‘¹+m¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Û“¹+m¶Ûm¶Û{m¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶ÛnÛ“ù+m¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Û’I+m¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Û’I+m¶Ûm¶Ûm¶Ûm¶Û jÛ’Ù+pw·m¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛy+~hm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ“©+dm¶Ûm¶Ûm¶Ù3Ô/ér°ÿ JI$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I7ïÉ¿2FÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù29Õæ½^’£©ÚI$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I ÍÎrFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ‘¹+}ùÇÜj ¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ™+}É/áµ-¶Ûm¶Ù2ê’Kô‘%ì’IË‹É$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ‘¹+m¶Ûm¶Ûm¶Ûm¶Ù2HÌ’I ^9\’HcßÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ’I+{m¶Ûm¶Ûm¶ÛlÙ2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ’I+|’I$’I$’I$žÙ2!ü’84’I$“_$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ“+wÿÿÿÿÿÿÿÿúÙ1Éô’1À’I$’ÊŒ’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ‘i+wW¶ÿÿÿÿÿÿþÚÙ3ÉqMë’I$“¶Ô’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ‘ù+wüÿÿÿÿÿÿÿÿúÙ2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ’I+d’I$’I$’I$šÙ2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ“Y+m¶Ûm¶Ûm¶Ûm¶Ù2I ÓiÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿFÛ’©+m¶Ûm¶Ûm¶Ûm¶Ù2I$½CÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿFÛ’©+{m¶Ûm¶Ûm¶ÛlÙ2I$’CÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’CÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿFÛ’I+y‰»ë0¡u¶Ûm¶Ù2I$’CÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿFÛ“)+v¦x‹u¶Ûm¶Ù2I$’Cÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ®¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙÿFÛù+m¶Ûm¶Ûm¶Ûm¶Ù2I$’Cÿkþ_ÿþÿ÷ÿÿÿÿÿÿÿp˜?ÿçÿÿÿÿÿÿÿÿÿÿÿÿÿÙÿÿÿÿþ?ÿÿÿÿÿ?ÿÿÿKÿÿÿÿÿÿÿÿÿÿÿÿ¨¿FÛ’9+{m¶Ûm¶Ûm¶ÛlÙ2I$’G(wð€ÿ÷ÿý?ÿ†ã¯ø>zÿÇÊ/èÑþƒÿÇš¨åíÇ;Oÿþ ÷Ÿ%•Ÿþtÿÿþ§‚~ß+û²Gú()³/þe?FÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’E¾h­ág&£»‡õÕgs¥û‚C ™Mô¼ÃúQ00+ž÷veçíõ¹|¥c¼ —ý§Ä÷úž¼]xŒa >–Ë52FÛ’I+oQÛm¶Ûm¶Ûm¶Ù2I$³av–KwBL#LL&Æ$“r9R|• =¯heÂÓé%Ó† É@“}ÓÂ#\’tm¶Ûm¶Û2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$ƒÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ‘)+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$ƒÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ’I+{m¶Ûm¶Ûm¶ÛlÙ2É$“I< $’I$’I$’I$’I$’I$’I$’I$’I$’I$ƒÃ¤’G$’ ’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù3}ß„üÏ’$’I$’I$’I$’I$’I$’I$’I$’I$’I$ƒÊ¥Ap))v62I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ’Ù+m¶Ûm¶Ûm¶Ûm¶Ù2HNÃí¨…$’I$’I$’I$’I$’I$’I$’I$’I$’I$ƒÈú•+’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ‘©+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$ƒÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ“ù+m¶Ûm¶Ûm¶Ûm¶Ù2I>˜0ƒÉ$вÀFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2IŸ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$ƒÉ$™eä’I$’I$’I$’I$’$’I$’$’I$2I$’I$’FÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$ŠI$’I$ƒÉ$’I$“EäòI$’G¤’°y$’I$’9 òI$iI$’I$’FÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$žI$’I$ƒÉ$’I$³¢æIŒ’Õ¤ÚTúÆäŒ$’%10 ¸I$“$’FÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$ƒÉ$’I'ÿãR4ÒŽËëyþ~ä“G¼’mò…¢àîî9<’FÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$šI$’ItƒÉ$’I%šI9Gå%멎/)4NE"îA{±Åtþgÿ!xo{<šFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’7LƒÉ$’I"’IÄžC"¬\I I%ÒHƒ%Á$ »’¤Ò*ºžFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$šI$’ƒÉ$’I’I$’I$†I$’I$’I$’I$’I$ÚI$’I$’I#ŽFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’1$ƒÉ$’I ’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$ŽFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’É$’I$œÉ$’`ƒÉ$’I’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$žFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’Hn’I’I$“É$’I$œÒä’@ƒÉ$’I’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$žFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$‚I$’N`Iê‘i2’I$˜I$’I$›9$’ƒÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$žFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I'’I$I$‚G#aÉ£I9…É$„Ƥ’I$™L$‘ðƒÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$žFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I7Ø|0ÈÓñ°+ ‚À¹,‰DƒÉ$€2ÀFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I6_îÉöŠI”$M'Ð „»$HÄÀf¶i"§°ƒÉ$’eä’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$žFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’C·,nG`H›ƒÝæœõ•9Â͞؛€A4ì1Ÿ@yç AôƒÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$žFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’Cœ¹…™My}~hõŒDØL42gI¡³àäƒÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$žFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’Dgß3Ëÿ‡®°¹%rãû)U[[Ìx—±µ"÷»±¤ƒÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$ŒFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I«2qÉ$ÂH"’M&®I"zuŽr1g$‹é$‘K¤ƒÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$‹ÆÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$R3<’I$’I4’I$nI$’!$þI’I$žI$’I$ƒÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$“ÆÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’$’I$’I%’I$þI$’S$þI"’I$’I$’I$ƒÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$šFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’$’I$’I’I$&I$’I$þI$’I$’I$’I$ƒÉ$’I$’I$’I$¯Ëd–I%’I$–I$’É$^Hç’I$’9f…FÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’$’I$’IŽI¼’I$’I$ºI’I$’I$’H´ƒÉ$’I#ŽIìŽE&V‚œBÉ-’I šHå}G¤v+í’)¤Ò;SŸFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I0“I4‚I$’3"VOLËê’Y$UÀÜIĶ“9äƒÉ$’I+ºIß^Q0¢æýöÉnG8.DuI$N2’g'±R´WFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’HÆÂ(^…ùj<Î#@?#¨K 0m^q¹c>É®^i¨$ƒÉ$’IùY¢;Õ+P$Ù5Z+Ô—pu“ˆ2F߉™ ˜¡SFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’K$²I#’G¤`I•ÒA"I _"ªI)çšH¤îA¤ƒÉ$’I+7{¿òIœ‘‡$Jz‡ø\¤Ós&“¦‘Ž„—Y$’ „wFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$˜4’I$’I$’I$ŠI$’I$’I$’é$’I$’I$’I$ƒÉ$‹2ÃL±^‰¦ÓO6’yÚ”j”Ûf¢OlÌw…$’y¦$ÆÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$Ÿ9 HXRKR’H”‘›d‘%$ˆù$LÉIÍ2OÍ’,ƒÉ$“eä3 ’™+ÞN’>œ½àY®'¯1=dH}¦FÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I66Hþ²Cj’¼‘?¤•O$i%‰IrHÓRHn’¤ƒÉ$’I$›ã$û™& É–O2$}’ Á¤ò¹'Bé3FHôÆFÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$ƒÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$ƒÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$ƒÉ$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’B¢Ýí .‡W_97àÖ],Ù$’I$’I$’I$’I$’I$ƒÉ$’I1L°Ë/ìñ*¥/t¢­’I$’I$’I$’I$’FÛ’I+m¶Ûm¶Ûm¶Ûm¶Ù2I$’MBlœŒv; m?ÿ[¾P‰$’I$’I$’I$’I$’I$ƒÉ$’IûâÓ¤;D5¸ ¨sˆ³Ødðš’I$’I$’I$’I$’FÛ+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$“É$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛÖK›m¶Ûm¶Ûm¶Ûm¶Û$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I=’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$ÚÛ’I'm¶Ûm¶Ûm¶Ûm¶ßd’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I6’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$šÛ’Im¶Ûm¶Ûm¶Ûm¶Ý2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’NÛ‘ùm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ’Ém¶Ûm¶Ûm¶Ûm¶Ù3µþúq„’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛ’I'm¶Ûm¶Ûm¶Ûm¶Ù2F5Cä’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛŒ¾+m¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛï÷Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2:A’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$x¯ÚI$’I9UwP~I$’@‘Òì{þI$’I'm²@RFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2jg’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I%‹pÒÒI$’I Ø‚I$’I–¿Üo"I$’I!áµÒFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù0’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I&FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2 ˜ÆI”’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’<’I$’I$’ Ì’I$’I$“$’ÿÿÿÿÿÿÿêFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2Mþ‹´’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’#É2I$’I$’.Á2I$’I$’šFÛm¶Ûm¶ÛrFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2£ìjl’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’JrRI$’I$’MZRI$’I$’.>ÿÿÿÿÿÿÿêFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù0’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I&FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2­Ô#$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’G|’I$’I$’¤’I$’I$’,$’ÿÿöÛm¶ÛnFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2>¡5N´’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’AI2I$’I$’+y2I$’I$“ýךFÛmïÿÿÿÿæFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’DRI$’I$’LRI$’I$’o>ÿÿöÛm¶ÛnFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù0’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I&FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2­ÒS$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’E\’I$’I$’~œ’I$’I$’F¼’Ûm¶Ûm¾FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2>¡ž´’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’BòI$’I$’BWòI$’I$“º >FÛoÿÿÿÿæFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$†I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’@$’I$’I$’H$’I$’I$’’ÿýí¶Ûm¶ÎFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù0’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I&FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2`.çr $’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’H’I$’I$’N¤’I$’I$’Ï<’¶Ûm¶Ûm¾FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2Ac³§µÁ¤’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I—òI$’I$’CGòI$’I$‡¿ >FÞÿÿÿÿÿÿæFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’@d’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’H$’I$’I$’ ’úÛm¶Ûm¶ÎFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù0’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I&FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2`.—ä’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’A2I$’I$’Mc2I$’I$’W ’$’I$’I$–FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2Ac-K$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’KHRI$’I$’LPRI$’I$“¼Ø>GÿÿÿÿÿÿÿæFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I4’ÿÿÿÿÿÿÿêFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù0’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I&FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2snÒI$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’H32I$’I$’H³2I$’I$’? ’$’I$’I$–FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2{#’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I€RI$’I$’HxRI$’I$‘ÆØ>ÿÿÿÿÿÿÿæFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I4’OÿÿÿÿÿÿÿêFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù0’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I&FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$H$FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$‘I$ÒFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’H$’FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù2I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’FÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûi$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’I$’Km¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶ÛFÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Û6Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶žÛm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶ÛÿÄ.!1QaAq‘¡ð ±ÁÑ0@P`páñ€ÿÚ?ÿxç:ªÚÕ¡uàô WI%[ U›Õµëâ¼4ªèq¢¼^¤¬°WbicFޏêy¹µ0EkB-A¶7e{äõc3dË»~ÇMõÚ¼  66 PU³yv´Ù°Ò[¨Ø‹yÚ{‚hx {¯%¾¯©ê§´¯?x„S^m¾ ÆoX(dº|ô½-û2‰ðÃMí]s ·›ô¥ìG ¶25Á»ÅåƒpªWmxÅ™Ó$ Õ+­àðR†Y@Ý:ÇRëuå_¾ÞÖ²=þ¡Robb‹ùzµÄZ½åWŽúwÄD YÖ$…ôýïNœéŽ¥z¥÷ÅQÅe‹òÓÛmeèpˆs¯Ù3£FõÄ7P«âê¾æ—]c¸×SÁCì6õâ¥sl^÷0[ÅUê38|›Ï³é¢ K—ލ½J?¢LW7n;Vºl²èt%£©E¯n›Ž–ƒ…‚u±aæfô¨e.ªç>Un¹ƒzÔuê]]9•¡›#® ìÆj‡:J™QHæ\[n™¾’ëBE,ïfÛ’èõ€Þô®îñ,Q)ÿΉÛïþ¬:ø2¼N¿Aô:M¨ÈðuôÕÅ·kOQÔÛq¡©Y¿CÃNE ¥–¥ ^ò›""  rÚ³Ü|CÁT ÝÚú×FºÈy´<¿Š@>éïL8:ûGOž~=vz’ÔÍ*º%ß5«¾+h2û÷[ƒ‹¯˜ô/¼V®®õõqÒš÷+^¶âr©Ó<ôwk:â!¥¤!ÑÿÓþ!AÙòFßoÇ0*ºuÚÂyƆýzLÓׯb{‹ä¹`–¡ôÿ˜†¶ ïF…oÍôÓ1˜hUn+iß$Â@¨;¯±¦3(k¥×šçÑ‚Õ(€›*úR`ôsë¼½Ð;X_8tÆzË€éçÕíŽ#Ñ_„ëà)胜~oh÷ú[ «Ô&;‘À¢ýNöúuŠúk¥#{,sŽðeAÅ&-®50êã¥gPÕ¢1®47­3'Eh+|¸€¯ýEzÅi]m‡Cp@8_V«¦·&(wÐ9L=6Œš¡l…º^oú°ëàËñ:ÿÓdºJÐÐaÿ\¾ T UhUÕµzêøz&lMDÑçTx|ü IY`*ê€Ö‚Ý]sÐó†‡û\ëõ”Ðúö¹×ê:ýtÚSiM¥6”ÚSiIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIID£ÿ—ÝÓMsŸçˆˆˆˆˆˆˆøŠaô¡ÜÄù?,ÿ £Õ“k³Y½/§ÿ½«Fþ¡nÊ]é~UçÇû>>g/å–¡Z_. ù%Ñâ–tm5=qÊÿdØÍÂäìõ‹3¨Õ¬•Çœ] ôWˆ›(÷?5÷8— íc¾Aíw\Çz!ê CÒóI×ʼn¬5iÐÇUÔáéLCG¦3IÏß»6³›>_]fIÃEð¹;=`"Z éWN‹Ž*®Nž_<å”VÎLö~÷G Ùr­­îGB¢•æ°ôz'{7¶Ê:Vé›.¶UŽêËJÜûb±ó_Qº0nô>VÖ]‹(ò1ïù¨§¨ïe_8ô­[Zðks¦–¢v+vÙ&«®ƒ­lÿë‚–þÆVkT±ÞP5_ Õ­õa`[¤êºÐªZj¯J ëTPôúUzñoÐít6:·ÛcV± ¢*õaÉ‹2]ÿ•`Ô¨Uzwã3 ¨ØÃ«¡DÂa[*´‰àIE] uÅŽrb³ K2˜µHR«ØL%Þ&2E, 5š»B”«/¾X° aqjеp­%¢@d5¼Þ: †oH@Z7Z¦ÚjôÒLX¢—¢ÖÐ šº½áKè”È1`ÂúKÚút¼m9.ÕxùA—ü£XTO!`I´@®7ÍuÚñ•Å*ì»}t1eë›.™s,_Aé{_N— ç%À¯(2øàš¤ò[î=%bï­|Û»D:°mGZ]›b²Ýs*cpêWávê%dÜÚò{Ug—‡0a4‰á«¨éK·|VJ¾2F…;€Ý96kS£q*¯©å}œ{Ô2Qÿ>´ñý‚‘/WC!Œ†‹TKɆÜh¡lšßA¬SX``7¢½J­o\ RèäµU`1‡Q–3Ë(EZv3ÖËvjÇh£%B¬ñÔÈ‹i‹‚@H)B‚Ö´À¥…†"&¡ * Ya…\QLC!`SY3wXsc3$­)׬NE>˜¨ðÂT !Æ–åX:Dt[,½…¡ª]1|ÆPf9T°ÅêR\iÖÕ•ƒXÃEâÚ/¬¤ Ì5®™ZXlbÖ(ƒ UJéF´Úqf`qk’òÒðaª²ËÅÊ`<Ûji ]a)K¸,½M.‹uñùœ¾ŒÌÌÌÌÌý¾|fäÄÁ¿´Àß_`_Üõš‡ßí×ødó³P(5ÿÓöq‚h‡¾«²ÒwIHV…wÊçœ×`—Õ¥7ß ž3}Âf.ÃÈoÒÁˆ¨\%«ÏîMx©Ua±ÔmOL¾^¼¨'þÍxß¼|æñ}hlLóùð‘^êÝäû»ÔveËs^·«Ñ¹ƒµ[ä•÷ƒ4=Ôªsà6D÷ˆ|®Ï¥üHešãS\Gy~xúÓùjS8t&w ­t¹patͯ(-»«Ä§à&‹a²º/V­LL…-run¹¥Ðô^#U‰9E]Ø¡¬ïu‹È·e!ƒ¯S |J—1Ø I¦·f‚4dŒ#H>§=IkQF¬1£aOZè5Ž%çÖÚ¶…ê… Õ.8;I@ªªº68÷z­åR×í1Ñ¡^®í³¦­´V²aÙ© Í=:ëޤ UU Ý{½V> z"Y®”º:ÕéMÖ£yÍU¬5+¤ì—ΩËêR1zà¿Z˜–¨sÕ»0zɾl'jtŸlZà'È /|íðÙ x1“5»t^–$Óx(»PšPZô.ÒäVÔtc\•œ0J¬ 6Èin(S5g q WÞ»ù±u"7›1T8Yh岩¹B‹e²öN ¡M’¹+26hVÌò b¡x(ÀlŒÞGF”ëUPl\§] h(>˜ÄÖЊ/TC®´Õ=eƒd˪ºµÓ@ ˆÀjŒGÕ=Z‚®N¢™Žô*¢å‘VtjÔYw–gH•” ]kF/®.¡Š&™ÏS5ÒúÔ&J yR²ÄF/BÙÐΣ¨£‰Ÿ$nž¤Å^ ÷ÓÇærþS¿#Ù¦<àªÉFëPè»ñúÅ´Pë!C +yW~´ ×]Yy— öùëÖX«Ö~tý¯XZd;¤çZõéšÙ{¹}Üqâõ«PÔã“öë¯Öº×Lü²Å ¡{kñ™Ã_L­óÚ+FÖyÏoC% FówF"+Dêéø(÷o1_qz¤ûÍØO|K6Ðq¨—O»÷éVôVýný¼%…?„çð¦5ƒºz?uöu–±ꋳÝoðJmÅ)6D®/&Êï/´½kTÛƒæMÎ¥m‹ýÁ¦à¾™Çj óˆëõs²s¡­öÿ]ÇÌåý‹ rµ|7M-ØéúQþ„‡‘)¶¹ÓóüÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌøt]uÇ”´‚ÐZ Ah- ´‚ÐZ Ah4ÅÿÓêýFÂ¥`´:µ¦š^-/ØT\¶‡BôÁ­bÖ¿ûÿÃ5C[Yu/øÝßFÿÃÕ>‡ÇçÿI~<}AhoK<\xó4kë]QÁs¥Ã%Éd3|KÂíóóþjÿ?ª+š×ç\ÖŒò̼ƒê³·_íÿ5³ù!‡®Ú~£N (véøÓlFÚ:å÷ù´3äݧïY_¹ž±*Ûßµ~â[~~>f,–õï-IÓîHáCcïù©Ô;‡µüëÒ-Xpöºù´>0üøÅM7»Ýš¹î”ùøŽqî yà m+ðÙ^Õ3›š8]~=uóœLx_4éCùéåÅ$ÇzhÏ™S¸|W˦#AzƒÝÍúcÖRÎ9& õ»›Ïõ™Füó¬º->iðõ„QÍ<33y>ÍΣ­?™ ìü=|¼§Iÿ??yÐmäP}³ç´Nź~&‡àoB¼´õ¿³:f4i¾ÕúÅÇ“ƒÙnNØõ5±¥ÓÍ+ÛIš¦Ÿ¢}ïÖjàÛÙ÷¯9¯åuø'ù«á¬µd¾€VkWF•UÈB§“ ¢›££×7‚h_~÷ÔÕhFÕCÞ…!åkaí¬vèÖù[ ¬fŒÛ¤vZ'›Îìí©¿YA®£Œ¬wºÂUsxV5…½Ø(ˆ8½k¥’ÊfÛtTj¬ï©Z ’=1Œg_ ´e…Vö}tcˆ„FÿÛíÀÖŒ„_#ù 9Ö9)ŽuœÎ·âcIG†…IEWI¼¬W€“wyD:>yN·ë5+ÁξVÉ·ŠÙ:ÜÒªQw:î† &Æ’#cc|\ë”ÍJ*(†4•Šù¿ù«ázlláÜu<¦³ Cºì÷g\ë.é}.Ÿ—]ÙÊíæ¾"–piùV‹Ë˜z?·©¶`è#Ýv{¹×˜@pFƒ¸t»˜Žãæ[õ\iÄrš«{ý¼EVk:¸ÙJÃöÁèmÓýÀÿø¾åÿ»êI¡n¯Ö]TU×H ÔbˬV˜ÓýßQV²¨ºnËó×ø°cxQKVV ¾ÂŽªCZzj&j úY~šÅ-YC45Þ‘ìŒwCï :¨¬¢UÞ+¾€©6…ëT]ìé€Ð"fÚ(êuèéŒ5S¹E -­hò}!ã‹AA{H6‚ô?)h•bݹÎ0=fÀn¼öïÄÓwn²»¹Ç\4ú8veŠ—“è‹T/ ¿‰jœœ<&íMöŒ€ÑON°äZòüº¡Gñ©Üë´¾¦R9²ôÛgG¤]A–[¨ÿh{ •ÂÒ®.ï´ (ïE˜)Ûd¥d1Œ›§–—¼4µ—r9KÆ­i´L2ˆ3!GUU¡ sšBµ”3® †ôRIáÃh7”3NµŠÕ±Öè®ý ÏÕQXA²ÚS×= $0µõº—{Ö;cHøˆJ/®h¬½>å1¡W…×£<ã¬Èur¶qì˜̠ÁÔ&׃–¶ƒ »KºQŽkNÕýÌ´{å4ÑÇÐN¸Âš¥æ/¼â+n¡±·rì› ÌêKÐuS#¾j¶H·Âžç_fkáê– å} $ÑA4átk}ó/q»ð¡ÆŸþ·¹î÷0ÊúTó§4ÀmX½F÷XØrÐú~oÙ>oÙ>oÙ>oÙ>oÙ>oÙ>oÙ>oÙ>oÙ>oÙ>oÙ>oÙ>oÙ>oÙ>oÙ>oÙ*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T¯®¥ð/2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®es+™\ÊæW2¹•Ì®aõ,¨åí¯P¿ùS( ›Ý霮¦ÒùØ´î!ßg+‘š,êbé7›³g_H€…¯=»ÌÚ/?ÔšìCê@ÓG‘ÔæuÔö:ýKg_ɈËöµÄÉÚ}š}!QPj³nÊeÒ¯¤e(K1|«ZýG/,¨vzm×Õ`°ªìÖ¶9ÈàëBÿRh±¨W©”«NêÅòSÌèd*ƒ¸1|¶óõvÐ<&^¡äÓï*¡Òƶ‹ß­Å¤z¶|´èzO*;t‚Ú ßž·Oðzþ¤ÐðÄŠm;ˆg}eî´y²mÉ×Q#b¥Â³ß:gS:Õ¡ƒÂ«+ÎéâÓ© _/Q³Ó˜upÞ†qÿ–´có;#ÖÔÛuÄp1õµ·7©ÓÖ€::è´vîíX ³°Å—£‹Öˆ¨´!]…[¹oÊT6it]ez§|ìÄ(t§K‘28ÔÄ¢Û Kã8ò‚<•gGk§¡×LghQ6Q4º§ÖkNu¢!Øp+S;¦j¢Aª>Hèú6ñY¸ï*Þ+GÏ "õ؆®±U¥ù>êUmœé32Ò¹wN1šÉc-oD&ôæ&Fµ¨nkmvί`j¸üºXÐM=M}ãä¡A«lУ.iªt¾‘QX…Z–*Ã:РtAlð`䦡w/•4&2V­Ú£ÒT²k/¬ªºïÓ]zÄ;Dµq¡C‹6aê6Fà š WZÌa. ´E¢“²g LÒEà¶««SDÄž'öÃCà ÕF×cž12F¯–Jùíœv__«Ké1 ‡üý<Ÿ^ŒÀ[mÕ­1¥ÞnT!v6앦t­é¿¹À4À ¾˜Ïw7˜èh“ÔR:º¨_›Ö‡Q`U à/ç^ˆÊãüǤ۴¡ÔÀÇuΪy:(ëÀ˜­E³Hœ›¹!<¼Ôv—V¼º¾­À5nÃmÝc]­÷êÁ¬YаòÅwÎp[Ê€èQTÝuÍgÎÂî_2•ù†‡EÕyÇ1½omévK¼lMìLc½÷)æ_W^¦ qš½k˜ÝXï:'ZÜê¬"éÖ4çZ4/VªÝ|2UzÍWÅu—Ì:ôg^•§]ÈêȦLŠhtb VÂZš²’ÞµM#Dd¨lt\Uã×MzKÁX*•}Ròö£ŒÂ¤ÝùiY†ËÛº·Ï>šAjˆ5e†BË)u:gè?¶ìCêyÓOÑàum»}X.°p×]zÌšk£­±CµÛÎ9¹‡¥<‘?k>P‚:®›Ð'p*–4[nèÊ~ ÎâX¢°ì8°Îqޱq—ê@sžÑ¢²Ï°^Í%Ö,æbÆï!ïžzÌ褜뎼{(o+°êÌš#` Ê÷4<°ôÚSêr½Dï0.z$ê÷¼Þ¬ÁÁ±h „;¯–c[·×Rºþ? 4?؇ÔЕʆ œº_¶éÖèÝiÈáÒøi³N¿Võ©æ~“ê‹Tò+z²‚jXèYTlœÇIµmõ Ï^ý!SÓCª´§£éísißWRî·RÛC‹Ðé)¶½rŠ÷³·qs@GŠ>ñi1ÓpÓ÷ìP]arµwÑà:—3½,oV8ç Òçesˆw„;¶_ï+¦¥; >ÇÞT«¾ÿÐÙê]k_*øšíãå|ykåà­þF·Ñª£<梪1aÞÑŸRUiÞ4CéÅù¬ í}þ޶öN×BcªG›VÝ—œ]7Æ“­W™ëgLwÖ*÷«•¦zƒ{â’æA× ¼äÅlKO;=fݯCK/6m̵.élÞƒu7[ ôͶ–æìÔÇ´AeöÑËn·£FÍD9/{Ò½÷×èé¬L½ë<®tþ.×μÕxRïJXñëZ×VÝZY× ÅÖ]¬]»‘É.Œ ÍÝ/L餴Øì zã\k)‡Pèu@íG,lÀ¾¡k·OS>ê#êyM[o.ñá7Mœ;ÿe4> Ëþĵïg•iê«ÚÕ¯­®®F ­Öi»¿XÆ+ËnÙe4q·H€¦“£¬ë)Ón’8¯,ã¶\rývç~y‡Ê¯¶;DÚüý¾³Ôýë( %ðßí®[Ì¡þ¢?–¥J•*T©R¥J•*T©R¥J•*T©R¥J•ôìCûa¡âåZ5:Ï'Òii½å4ÓaÀµé[ÞÜý!T)€Z¸êõ¡®9²ºÇS­ pèöz€SX†¥¤FÍ”oÒ:0_.‡ŸMÿÔÇôŽBÕ/ÊÓî?Ô ¨[hóÕq«¾—I˜Á3Õ¤ßwX1FŒåK ícÛW9Y%ÂÐGsÿ±*6ŠŽŠ ¶f¯¢Ø–?EË6Ò°ÿÂß8ÃEläkÎÑìÍØ™Ý\­÷e¥0áËã®”gWO6SÑè×J4V…ÆÄ •mm­Þ+wÌ2 ACæM2Âú´^å^—\PÔp äL­7/[ªí£‡..ìo_õ1õ&øŒµ‹­kWIÒ3yAÛ%‡ƒ¶WÔˆMÀäê·.ï:Âæ/]@á‡]+1ÝôÈÚïB^‘U ¿ƒ¡xÖ©»!ÑMZÅÆ]B‹mL†ø¬Õ情졽qýA¡àhèQÚ×î±´1ë`Îñmp@íåA±ùêÅÉF ô7‡«7Œ²¯D£—-Ùlõ™nè…xé2Ç+`è¸ã­iß7nµ qÎ6ËÓ«‡GÏ|¶• × IÿJŽCT7mÉÚ½åÇñÙ!IÑåç§¼@WR‡A uÆþP¸à²Ö®û^ ÿÛ;m µ49и«V¸:nl‚y.7ÍŸêcúÖ>@Çõf‡ûþØh±톇ûþØh}yíÉ÷ùù鶸oC)Ü/\çYŒÆèß•Sçn˜Ç EZdzŒt õÊ¢,4eÁK¦yÒ|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýOœþ§ÎSç?©óŸÔùÏê|çõ>súŸ9ýEôµ­ ú˜*@î VóY Ü:lû)¡õêT[³YE¯V9»ë¯?(ð÷úÓW·Ð}YƬ/k*5¢‰„k]]£§Õ™™™™™™™™™™™™™™™™™™™™™™™™™™™Ÿ ÐþOxÿ­5{}öÃCù=ãþ´ÕíôÊi›°óz‰rú–mbÕñO8 À:Ó'ËÝ‹%ªã¯e@æë\fޱŠ4¶UkÒüâ4¤@n–ŽÍ(ÖØÌ^*ô·VŽÔkÝ/j2\_dˆÎiU¾* 7VéEÒÖï¦à3Ù½u«µ–«Ev/â‚’ÍK¯³¶»âÐ mÉzvît–)+µaÔqŽ‘o~À·ÕtÖædlHw,þsCù=ãþ´ÕíôË ëé-~y—E 7çjpv¼AP¢á®r Â/£Z­-îëBž&8å: KÙ4Çý›Àö‡ ò&@¾Y¡“ÍiQ4b:Zë–×õ/xTyÍÃêWQ6 ƽñY:n…|%Ý_G‰®0ŽÈžw.Q  ªÝO±²1…S ¶^Îõ­½áðKo0aÀíЖ Z­0SÈ…F®vh®wþsCù=ãýÁCUiÏ~ðD‡+T@-_öô t‚Ú¿£W·Ð}LÆò»£¦5 ¶b £ÉKµÓJêíý”ÐþOxý SÿàÞO§wà?sXÔÃßêבþ‡Ÿ¨ Cý!ªXQÔ"ÈÔ50ýÆ—½õâÝþþ¥¬°F Acý™š¥íÓ¼f?˜[U-_óƒ.Úå긊5Ïsù5ÿb¶_±˜'OÌÉã«Ûè>ºú³333333333333333333333333333ôÈNX¶h¢åBeÒ?§õ鼯חˆ7= ¿ìÅ«³*úp{ôúm:Z¿©@}íò]€tvbA¯Ž¼™Wò¿©¤hÑ•PPÔú™¦]‰N¾„¯ByAôëÝÛ3$cêÄ[¶ïK>…(Zöï,{§ê`н¬¿HÞÍñëß÷/rµ¥;¬q¨Å‡±û i൬‡ÁÎýyˆ;%Ë-íé-'C§‹T-hL«jÇî;?s0Û,ñÔÃ(¤YôæË>1•Њ©êW”tXú1-`ìâf'HvïÞuO¬Û´fž¤·±û™âPÔñ6ÌCXyâR°£Öh@eÒ1¹f-«v;A•¯äMA>°.([„Ö—âË)Ò®ˆ–òé¤7?P}ñh+ˆ‹ïpAgЋº7”u9 Xúêõ–o Э 4 ã>¾’»Q¨hñÿ!\k×àÓ§ØÖº»@†ŸLaï,iŽŸ¯T ~‡is*ÐÈ «šò ×Ù€>jÄu²˜$%ÑpÜÌB,˜ ‹¯ïÀÑt—J.=%ÚkžŸò,~†H‰ ƒwuùÈó5A½nu—ôîÛyxêöú톇ò" ÍXšt [\h¿GoÔuгó–¥ú?ˆF#¿fnû¥½)çÀ­VW¢¾ãú=âÖ+ïžzO²ƒ[Ö`úÕïµÜûÁšG^ÐiìuîºOC<ûç,¡xsæ‰Þ‘¶Ï$·UÔYš¬ÝÇÞdî|/ôdÚ§}áý.ƒD™k¾ÓFO¬>Ê\V—–©xwéó «Æý¢]G{>ðzÑš©és@_¢¹Ï*š.;|¤#©£éÖ;ÃiW_Z+PwÌèÒ·¦ÿR‰ð:¯×ÎþBýóðÀlÑèóýÁEKZº¯èðÓtã§ê #‹m{JâŸ<¡Eóéç–¼hþ ±Ú|Îý¡3m÷ï¼ÑÜ ççí•:?5&ÈùÔøù ÝŽ7~+–]•ñaë~Äc¢ò.óä¹Ó'c÷mÕhK’íýyÇã#£¤¡ÐùÇQyf+]ÉgGvý Àr×Õ¼Q[áÃ-G‹~ËÁü «ã- =zÎÛ‘¸GÉ‚—}ŸÌów7Cï©|Ï'¬z uZ¢°´óˆpY~®ß¹—oa¿ÓÞ:/=Ä:€çRa±›øÐnóÄöz÷Ì2ÄtZ«äÚuo¿ýé E/h_FSòúÁmZÍÍß–Ê/§æ-¯µöÁƒÛÜÝ{ÍÈtWi•£¼¯{1_×oÑVÀºô\2‚«ÓÞPÕ<àªT:ºÃøÆ½K{Ö¸‰* ÷Ö|‰ÃÙýÇUžHݧ˨°àÔBžQò/gS´ ]ñ ÊÞ/J7Z]o}⌌ó{V=%߀"ykçI{E|iž;îŸ÷ÓYÏ‚YõäæPÅtüœÊšzÒíWœÅ—¾cöûŸyÉî—jNÇî%š¹@¼É¼WlúÃÌÅŽ÷zBŽcQÈþža‰ûGìùݳÿ`°wÚ?Rvïï?äGP~f.rêô;D¨³£§¤» =f|; ôûÉqe=µ×ÞPXx¿Æ&]kwx[â‘ ¹Èþ¦òzÇP½¿žoÔ+Ͱ=âÅlŒžî"|ºÇH©1©hv7‡ÂW ú+§¯_ìÿä¼ç¿ÌƲ¼+ªõo§[’Z?d6…ó#˜ç|’ØQÏIf›ç¡ äÝãcà‰-`BS¨ìõ<£¶7ýøGCéôÊæjëíœzÀ@êÚšâúÿÚfª,:Û¥o×jë’îHJ^•Më¾Ð¬š}ð6qŸ_êÍàÁòL‚CÊž·1˜Ýòª|íÓራXöqŽƒ„¹TE€Œ?P-uW¸ð[ÁøþÓ5‡[× Š«cØKXN‰oÞ"V«Î•+‡ `<}pfÖr“Ò¢ #`~n-uÉ—©ú˜2ܰìEIkâ“tK ’:C]€ûG»âu˜Ù¤ôa¦†ÑÞ=â/Õä×Úf a£÷+Ý᫊é(ÑÝßG<ؾ¾£51óðY¬û¡?Ukåîhÿ’?rÙTèá=l]¦È>úûËm·örùp=¿2È2:Žr\xëKõ˜ ߎÃ;‡ì™z}ÿÁ^"Wñ€PÀ‹™ùt|£ÖWÂþÒÌüPAAè}׫à~¼ÑºO=¢ûÍ'¶f`·2õÚ EôýÇÆ­­Îð…>ã>¿»ˆÐ4<!ù‚ØNÍaVξgY  ã_3RXÐ 7îôõ𨅚Žýæ1„ö=?1"8£›”M&®íûmÿž")ÓÝ](í4.í=5e߀´µÞ|Õêõ¯´m6È÷üDúA ßqýñBf至ÒP(m‚~æ¬o¹ÿÒÇ ýîv>KÁŽûÑ|¶lƒ÷€è60z…ž’fS®hr6xš–ù\ÐǪ•D:kCž^_m¦& x_¾¾ñ¾ÿîæ«O'X- „üõ!+"l4<Üýù´vÖÞ³į̀ÝêßyÌzöšP;àúhûGD>_´ ¶¾ÇîF·sîÁ*UÈ0 ;פDö¾VkRƒê at^Òþ¡)€>WÑ+ñ-Ça7AG~ü³®6–Jª×e]òœªû€©m¡}ï°ôèÚð·õf‡ð9³YE¯V9»ë¯?(ðöƒÜ8GDÙ€k¹­s½ý¶ÿXÿ ªÆ*­ú-Uxú†w:&̪f¹ßú}b;0)Ê¿Z„p¶ÿH(Ù)¬kwú2:ˆÍf@úZµ1¶Þ~—­§ˆm:wfŸ ú.ë\Ýv/ÙäöúÓO¿Ð-Ë—.\¹råË—.\¹råË—.\¹råË—/è4?“ØëM>ÿAý°ÐþO`­4ûýò‚f~ưՙiÏmçXÁ<΄A3 ¼ŠúíÖ¦\š[ÚëïˆÀÖ>b¡¾\qÖ¥6ž†Ÿ³Néråj½^Ýt•»šóÚãRú¯"ÇÕ[õÒwŸéMäöúÓO¿Ð}LcS^cF›xÇ\â pæ·Äí§Zú±5cT›£¯WLûaA†ùƒ½0Ö™Î÷…®‡VÔ§EöİZ±,ZïTì\ÄæOF'åÔ:ª5’Ë'+ò._F9*7J¬j†š±Šáz‹ÉãwdAZõ0Õ5=Ú[¹ožJë5­fÇX÷˜^ïô¦‡ò{ýi§ßè>  ÐÆÖQPjEÔmýÐþO`­4ûýÕ_]%%%%%%%%%%%%%%%%%%%%%%%%%%%>ƒCù=þ´ÓïôÛ àÖ¡h(n…‡›‰ŒÆèß•Sçn˜Ç EZdzŒt õÊ¢,4`”8'8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÎp3œ àg8ÀÀúåÅx÷ƒ¡ô‰BÑ‚%ŸÖÀ5’QkÕŽnúëÏÊ?„.øùóõ uyWìùR˜tǺ’ÿi5ø«âê¾æ—–Ÿä j-lôö/yX[_©Šïxÿ™ŽÖÚí^]wþ^£¦ßÁ¾ÞY­U>­ð·Z ëÛmSRäóö¯Ù‚ö×ÜjçÕé:&½Ðû¤éüŽì÷¯Sï¦azHQCQNj¬9É®ñèZ?}´¾çòj×ϺÄJ3”ó>9ѬDgØßó½gI‡Sÿ/þwþGt@ i^CgãM/ é^õ_qÿ¸™[éCÂü®ø×ùÚHko˜SñÖ¦žà}p{À¥ê]u¦üº=-¨eMšîëéÞ½`‰n5ö×ßKÑHwRÏlùf Ø”Šy>ÿÈä]õSäéx[n4§©Ÿ¼³^”·¸-çmCR ÿ"XuÒ¯î`¿Xµ®Ãä´{âZƒ6ú²×³9Ò§!ºz5WÏS]ÿ“PÞ¾|íÖ%5ܾÚýžÄUFJ¾Å×γª÷òyýgÕrþª0¶ºwûþˆv1VéÈtW<ÝõÎ’V€ÚÇÙX1]%¢RaÂþ[|ÿ¬4?£TÜ.ëóÿ¤ Ç4_kî‚h9U¼íáCÇòäÄíú=åÞŠžx= _.òÙó„ÏKÑ;]éx×8þLˆØ=w´½A¬¹… M•K/¦Ž•—B†í^î_伟þt-~Úzfη© ´bÀÇTnÝ5ÓÈs¤ T(zmνßäR¾­Ws#Ñ}.,Ž÷½òópºú(ã¶ÙÚŒ(Û*þù2ïÓ+j4íûq~!\™úY?Žo¤Ë|ÝõÑǫƚmübDŠoC<¦…íÕÆ{Ëu‡’?gÖ¹šEo­½žF9þUËiPàUõν:f‘Ôƒ‡Ë¥cˆ0¬¾ƒœ®Í2kœ%¢ÊW½¶×X€qöÛÊB,Ùmð•ÆV”PµÔ*ú«^Z&;`ó¡P‘OAû ¨ À‡¢ýßÙMö!ü´J%‰D¢Q(”J%‰D¢Q(”J%‰D¢Q(”J% ÐÿbÛ±þÄÕrþ¤,1~£ `êõÕ:Ò62=nÿ¤ÖjÔ;ÜC[мï0€Üu¾þÅ>L U"Ʀb9 <úÆ¥‹]K…)Ó ÒÌçXʱ =p®xÛÎa\¨â¯¹Ož&è5Á©Ç’òÖƒ¦¢¾§´ÏD+p/Euèv)åZÓwƒ¡ãW~ôºœ›7ë,Α&( ܸ³EråË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹~7.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—õ†€¬¹ Bº½#nï\¶Ç¿ÕºÍ¦ÈJÎq¥v¬G•úšï¡®ÄÂVœvÚ Tè ëF…ìtš®¯=å ̃•iÇha»¾Fï½æ÷”[¥nº]Ý÷µoyj_ §œÈÄ=%4qw]/~ùc©Ö‚úÑ¡Øé·ôF‡ù ¬ê‘Û òYÔÿ"?–¥J•*T©R¥J•*T©R¥J•*T©R¥J•ô ÀZìs´.èâ³Ó7ö¬÷> G–®½mìVòüUÚG"ÝXÏç螀ò"ú«÷QE•fOðçYÔðm@µëj§LÓ}Ÿ¨XÚ´yÃuO1§ßëǶ«©Ïo›†·r¹­Ã톇‡¼@ÕU·ï£ÂÁì°´ây]ÜÑÔºá8Rž7Ý KuÀ º‚¿+°¡uui³:cšDAR ò|—{W%ƸpÕ8Î:äæêùÃʧ™5Ó î{õ좸 ÞèßlÖÖÌTæ¨wõ¼kŒ¯Ý곓Gv®æck͆7ÑÓeЉӭø3ŽXj¸Jt ½«{™-5f9Îv˜¬vlväÆy–¸V.¸.¼û ©±­Èmóÿ uObûÂΦC¨.ݪÍzv@"š ;õyÅg8òªö Xé{c0ÙºkqF_,±„ô -:¦Jï)œ’ÙÊV)»É¹ë(òmLƒd½©íŒl6Òõ ÖÅäÛX…jcN¹®Žû×È릫yÀ£±É‚*ƒÔV o‹\Þ:¥n¬2ºeú´¨)º.z™ß™…­NT®^ÞóèTípÜ—pJã¾®ì:u¾OSxXYP¸ÙŠò‹@Y] Õv}íÚ‚ë?á‡Õrÿ²šS¢RtMÈài³…ÅœÖ%›.šqÛhQ¥‡Ú[—œËErywwó˜S×™…‰(¾ .wëlz¢òš/'Fik­àŠžŒõÆ™ã¦Ðš5Û×ïz]Òòš>]6éW“Uå¥v©EŽÅÜMg;ÖúõÎùЍ®—\]mbv&Ξ’•® ‡Aâ:h/­Ž›†:Χ‚!) ¨u:6Û{ç=à«0téÈÛ¤V›©O#éHh<ÇHwëm×ykÛ,/W» kR#]0WŸ¤µ­†R•ÀØtûÇ)è”››;’ÜŒèvÍãlç¼4WGþùÖCpèÛmmÏx¦­ÓN;z³¸té14µÖ—þ}[ÅÙuWWš¼]|¹¼]µuuxºÅ×ËþÊhºÎ§ùõT¯ì¦‡Ô™¦¥óÓÕçhé W]Té¦+/Vd¦–<–Þ6nñSso!i~T»Ö‘Æ]õ)Æ›Ô/üYÖu>½pÔû©ò)Âê㙡4ºÞñ¿LÝpL•˰?éít¡ïcîsu©:מZô6ÿ?¶UŠpN¿1ú”4ÅW—Ìn“-óo.þëµçY©}}Ë/h!ZöÀÖó 4Œ‹:Χ׾µ|×ü¶'¡wçIùpc#›u_à÷ˈ(­0v¡÷[kÊj__R“Ó/ì×Óú éü·_ÒÛ ñ­È•寳ý¬êAa{¦žþ3NÔ1¤ø—E×ÈãH€ZÔ‰è!‡±‰ž‚{¤ ö>-ÕbÛ#îÿ@¯J^Mwè¢j¸ ³ø,Ëïm!t¹b¬þˆþØhˆ†á· @ë:ŸÌÖ ëGCv = ŒnžáŸ´áƒß¤½u¬÷uŽ·ïé¥WDÙgªyUo¤#’貓+¢líô"à&˜†w ÷ç‡(‰²*Ø¿)]Auwö^úÖ{õñ\8¿ˆ¦¼­×;vŽ&´¿L´µ‡-ÛÖ°­wÆ;} ¼A놄ÌXìäšA/ K»¨µ+V×–vñ=3ŽXyu†4ˆ¸ó1ö€s"û fz±ÙÌCLjð-}ãÕ£Õ„C¤¢çpráºcÛÖ_`: Ü-Óïé~Ù`Ö®ê,ˆB\›ûÂ× ;oˆ'Ú!× ^[¯·‚aVï§Ôl4?ÄqÞ}ßää„=cJR,=ŸqñuOåA—–žþ ¥_ßè¡5yê1¥–_±8åveÔ˜*QÛIÿ©5N¬P5˹ÃïÎ„ÝÆ?^r¶Âjuè{ü‚›BsOÔÄl/®'n‡Ó¸úâyhú·Åúæ+Fu רÓÖæ[pôn9º¥<´ûNÌËãÚï¶eÞyô!iªGÒÏ´ë,·ÏÅ€ÊïÒó"šDÆEê~ɪ®vPzçÄUêTÖ‡€ÂÀï£ëÿ³µä zøv5¯±ïáÇò~!˜µƒÏèW‡bÖvqËAGÌŠÍN}giÓ2÷EýåCp¾F|E^¥A«î¯´¥z4“ÑÍô<à/õFÐUèâÉl;uìªåêîÊ7]º[«ÝЙŒ¹¾©iW.OcˆÝu îËEÃKq*zº÷ñ?¶â8?-¿â*¸&°#L©pönwí}ïÅÖu?—̡鯇FΗôT»Á~# ¯Åi§‰€É£söLá¢Çc4¬f鉧ùΤô Ï«¸~×xÁ—Y}Eor¾õ8h÷ë CWŸ¢“bÕæÇ´›>³ÂʇJš†çR,>¬v1ô0¨ºø0q‚Ûê=bЯ0Ûèpç˜-€ìkïàˆìa‰â2=Cï;¹ðdv3H:ÇˬZL¥|ÿäL_Ýo£Eeèõ÷ð%q4ñ:øÛQ/¾?R‹¬gÏX¨4`»t;ÀQ¥W´ïø<éO?ûa¡þ##î?Ń~®îÌ Z4ú„4ùü1ô÷iñuOäZËÝÔ¾ÿÑJ„ *<€?³rA %¿cú`ƒ õ7ÿ<=ÏÏÄþØhˆãÂ{ŒÕïü'‚Ï ¹žù=¦#îG·ˆë:ŸÉÛ&vXÿÁw^'öÃCü 6Á³çdþwtûL÷/ßøG%o|{LÝïÉ0{>Äȶ/·‹¬ê&Tõ¼ÓüKßðñ?¶Ûz.º¾cãD÷p{ý¢2ÔúÁTAB=L?ÇIÙ{¯ç°[y÷€5µG|¿©|è¡ï…*O3÷õy¨ÜÏ…öf-·à™Ë÷ñuO䥥Ö|ÿÄð^~Ïûa¡ýÑçØ7a&,MÛÀ1Zô&ŸIëŽ÷gÚQõzL¾óºÏ|ø¾ºAë¦éõÙóñæ¡÷œ˜&$ì?ÀþwAÔh‚ÄêWüËÑÑ}†>u‹ûú±[CØ™óÌÇâ™ð£âë:Ÿãúž'öÃCùƒ+Yná·£ yÿ+ªÞcî¿àÐDÛóß±âjšžÏÛíàYëg‚ë'w¹YîûæÍ úøƒÐ ê3ï~/òY¿X«®çl«öÁZ}nô·ÐX{Åí_2£äsá¬R©I E浯/¯˜‡ÜŽ®Ãî<Z& Ÿã ¬>wŸyÞ/õ;ùÎî\ý<ÜŸyuç퉒KlÏ}YÔÿÔpñ?¶P‹ê„qÒ¡æ´òêçAf„Ó݇Ë7¯Bnmä-/Ê—zÒ8Ë¢¥8ÓzƒeÇ DÜ|9EG|x¥íü<š>ó¶×ÝþB®×>ìfZ¢:Íó«~óµ—Ô¯û§½³>Aíÿ!­Âü~gŸCVÐ{o×·Ž;Ñ=$ô|M³ÒþÌÚÞ¾Üg÷8=:ûC3KÇg'ÕQä”ËôðÚ]úgñ8·µÑó¯ñ­aS]–X†Ïj‚»²…ÉöK>ßrƒô)giUá÷œ”¾ó'Ú'Ö:«~YÔúý z ö× ­V­ƒE¯*s}r¦Ì2W.Àÿ§´PÒ‡½¹ÍÔJ¤ë^ykÐtÛüSKùgÄþØh}J'Q¸giú¼†Ýç¡o—Œ^f¥õô?,½ „ukØ?[Ì0Ò19 Ovžøðç)ä1ÿfEÖÏQ‡ŽÓP³Éï®×…'z¶Þ1j0𫯔,{ëpè[è1êßFþ•µÇOZ–a³QÜtðó³Ð's—×?™Ü»ôÏâ)îª× ‰å‘ô| ÏÀŽæ'¥Ï"VξÚ~ü91—>O`<=ôYR¢–vùÓÃÒ/Vf6G«~º0r´?q™ûQ›¥{£à•õÇÔLòx÷ÁŠ¥Ô[ØúMÙÒþÌX÷üȽ«ó ®–3÷_F¼[IµMo½ÑùŽ’ Ã^;øã0£Õ½‹+ÀSK/c1–Þ;œžR¯ê¾ð×ðJ†ÁõgÁ©Ûö÷¦"¬8Q¾¦˜Ôîu‚æ—oc,ãòrOQ>ƒ.·L›gö„±êû-ŠzCèëûñuO¯iu|ÕWØÒ¯®­äâî¹ÏíÆœiÛªÿ¾\AEiƒµ¸ÊÛ^SRúú”ž™ŠkøxŸÛ äF ç¨Ê0fZÜík»ìRwÎ÷GÞ"Ô ÓâÉUÓ²BÒ^ÆfxG¥è›Tm]ö3ø›ÍuõÏ´åßÔ¤5CÛþ} ‹+ñíÒB[aÝKvé駇¨¾¬ïÉí_ˆ{wÀzN‹õáÝÅé‰Ùt÷ÄÏl=3/Ð+ê[óˆˆÓ;ûÀ.ÕZmuÏ3§@½†þÒß`òrKj;NæO½ËÃÿƒñ5J¡zS·^e‹]“…o_Á†–÷¹êG |9¶KP^À1«Ø²[y#/®  ã·Oh`ºBËØŽ“†;‘í3Úo.VQ]õ”¾W×>OEŽïý¢1ÿ‹çJ‹æ+ãxé¬bô{ÿ“D»ž¿Hé¬bm}WnàJ‰5šë쎅ÓòL ãÝS™8w2@Ò6^_ö øKc õ¼(† ^/VûNö¸à½¿ï—ÄÌcþ ´>.³©þ? ò}üO톇ò:ë’ù°u>ˆ¿¼Ç›ú›ªÏIÍ{?¤ÀõÑîA,ªyÑêD7RŽê¢ôrþ;L®o0[Þ5¡qÖ3B.¾uýÊ­j³·_h¬oŽÎOi”w±›â¦®³N‡nžš÷êŽú÷–»T¼ÿÍb6¡mµþfªWg'ê >²í‡ß2éuŒÒóåú—['¬¬@ oòOÜæµôóW]~yG¯™ÜÞþþÍH¥rl,U3H‡Ní<¬'>Ð"Á¹èGS‡Ò7,z–ÓÎåãûëgU¿ˆtº‡ßðÍÊû?ò'J5zK¾WãþÃ#ÕžÚÆ™äŸ‚'ª*û×âÒ Ê`>Ñ;äúm]£ºŽ7Ñ&š/Ï˼j›ÏT3AtñbK=ŒÍížAqrMþ#QõÕøˆÖVô~û©N¨ºê-eDCƒ¤-)ƒÏ?y“kØ×Õ¯F9E¦&µYç4‹%0 ŽyzÄT-ðtnOi«°=‰ìYª‚¸‹Xh—+õ…×ìØhÔ «_LËÏZŸ»èJñãÛæfdõ*--Ëö?Ðë:Ÿãúï'ßÄþØh#Ò—Ígž½Ã:ëWìGmô$,«¡{Õèb=e°ßx ?á³ï0¯WѧäżÁ`naéd_sÞ/Mº]K†¡âáŠÓfú¤@`0ßœ‰ê:ÿÙ;ç´"œÚ¸¶ÖX»Ç'}gqë{M_ g¡ƒMÈ…R^»g¢t…éPa¿/_ Ǿýà¶ÁòâvÝ¿—[Žy ¼ûÁ§AHÆÓƒø–·ÀÝÓŽúûÆe×ÁÎñ^M´j{âþÌé€ì ?s^ Ÿ: ö,K¯/½bžô142ùF.ηË-•µOוה`ëOQ?3ËG½¿˜Æù2s3Ý .ºƒ­w³Ž´y³Xúú¼®-ýžp”)ó©}°¨©ÔqoVt@ò—†¸¥¯fu†¯K×…Ùùq`èÑk§~%* i·ýê÷ñ×´uƒ"µë±´úÅ@ ›ÆHÇ•¹íÐô„Іøg[ìfÙ"«lx3…o´CÛ&áI¥ ›¼¼Á¡ÑǬ)/CËþ¢g°W¦¾ëô:ΧøÿÙýÏûa¡üºE½cé)^…~!nŒcu§™dJš ƒàZ׋¡ãiõQÊWv"ú {çÞΞõ3ò>ÇÐîÌŽ¤Âtñ@O=·‚Óe˜÷õ1’ñ‚׈¢ÁàãX,îf!B®ñ±¡íY¬jÜûmõ­¦i²Ì uðɤ|â ÄXieðqåJøä‹ãžc6£ô†ŽµýÈÞó_¨Ðႃ§‡LÕ9«!^h`íô:ΧøÿÇÜš^öÃCú<»¼Äàûø[UüêƒNÏ¡ÿ"»wþ+Âb\?âxÙíAô\~ï÷úEO´VފЯègSüØOhxÛ èòâY‡}¿¢±90ìrÿaÚbÅG² >Œƒj˜œ¤÷ÏoêÝgSü|_iŠ×ƒíàl4?£Yï‰`çú+[OîBÛßí1Áüùñ>ÓÒÛé:mþ®ë:Ÿ×"4ÍWJk1<ÒÞe>šÀ]>€\U5ĉ‡øQ~®P:èì Ãö¿? £ÂOM|àóÚÞ{88ðØ~Ñ[p}¼톇ôf¼ÏH¶ßôE Ó§7ëîñQÖ¿E§úzÁÏ ·EÏd÷ è-Ç—Ò¸q¯ééO¼_Ô‹¬ê(ו¡çÀgÖÕó¯ÐÊðËûÔgi‘û/‹å¢YÛÆý®ß8ñJV°úö)dµ©îRúT7z{yœô^¥Êâ²Óu¡ÛxŒØG²Y ?r~é5ŒxyZ`>šö¹Mh8ìäöˆP('gÄ¢(ëÏ¡÷¤ºÍøÖo%ìe÷ŒÿA{Š~¡Üš€[KL‡Ý'Ãû"MmÇ`Â÷öuG=Ã>ÇÀѵ¡Vž"‹éô|>¡kB"4Àw¬žÏt-9Q俽Ã#TY÷úN—ŸÖê|ëåâÜo£óãâIÿÑÚçB®Ùy\2òè—9t¬8Tôý¼—Ú{GÛÀþØh7[&?, -Y¿‹P)âeºš¦ž° Að¹/—¡z_ñ¨-•›~<±À Z§Ò®¾†ûê}ëÆè'V&"6š½ß¯ -²éu—†‰vl—â^Ò¬ª Ù×qW ÃDÍpèøR‚#Zïù¬ §Ò…¨A"ÀneÎ±Õøñ¸2ã2Þ}øP埠@‡P=:‡Gçþ€€^ ‡_Œ¶ú½Me M¼%5Vž:eŒxµ÷ïÓÃ6øô3ô:Χò´D©ÈŽÂ­ÄU:À—Ö=T}®¯l?–úÑû>Ñ;‚wt;²ó0‹í×Úu6Väx~t˜?|CejÎŽÌ4ô8ÚiqÛSÚj¶ƒÖ iôîjúÁ°ëìÜ:Aí’úâwˆõÄæhy`‡ÿ[1)½}‚Jh·ëŸÌ3¬â>ï›æÚ3Ÿä÷šA¸ûtºygËÆ×ÒïÓ?‰Ú/¸€«¦Ç«…j&,5I`ù'€Ù4Ý—§´Â‰Ûî;B?@ =Ͱù åÞ³~(Pz³¯ãìÚ }eÜt{M§Wl>÷ãËè|°ûx Ü£º¯bvo OšøöS=U;ùø“­Gu_¹ÓKûÜåBye÷–¶¯aùžQ¾ºúª¡õ}D*:kŠ•ü½–;N@“Ô?_ªšÆ õbÈ3ƒÜm#Ñmen:C¨t^ t^ìø¼ šD{”}ê8àæu˜«ØüåÖ­Og_flÀã³“Ú ´ö·ý°ÐþEEÜ:ù0ÕÞê^j4QE¯,Q5ÔîMÔtÝÚ!Ôµo5ø•à­æò³C¢lÇ~§v:võ)…¼¸?ìušõwXp z×hj£Ñ L0pÜrÔ!ß6ËÒtAã/ê[.F]N¤ÒbÖ³‰ëÔ{¯üš|Ògß?p’vOTœ~±!j¥v‡UÊz9 úÃ)™'Ó³«ëà§I—KN/n¤5l¨‰è °£¡¿/ÏúÒÔü›0 -Ï_X¸uÖm1zú¿ä©šjìéèøaúkØ~ÙÐ1ú9ìÿ“;€µ7týÁ¯#¨aæ2ùýÎ/©µs¼—¡*“#³+Ø-ÆH<ÒØÁ.„ŒÆºzb¤TSïœO2fÝÏÌG6êjùû@6Å\Fºêwà”ÐÄ8g³©å ^º+g¼7` ~¯â'Ô]œßCΠ§¥çÎ"ºËf £Á„§B#9«µÿ‘…ho¢lÄ$-‹/½ %-t7ЬÂÉêúMŸ¬~çGç2ë­»ÿ>‡YÔþNÚ½Ø-|iäâj‡c„äy¸Ï“ÊSï’Ó\bŽV 3E-)¬Ö74ðò—¨Ä%==@ý’›¥ŸeAç¬2ô>J_çÇb¦û'$V  ƒ ¡óðùºÿÈ@ô°îºö"ªÙl¤5Ãg¿Þj…tæ¬]íóCAyÅgÝ‹š÷ŸövÈ}̳¬‹"Ó^µ¬4ŽBÒ¯¥ÌƒwGŸýDcRï°ûKmè;PSß×âaÇŽc°ï‡´|ö¿Ä; žBþññ»½=nþÀV E„7 z?°,ï«í¬§4\v0{x¾}Jƒ ˆtîå:F9ÃkUØ¿ˆ iEÜ yޱÓYÌÂÈM«Å;‡OŒUmñ#¦+ÌýÔMp5é9:y0ÿ±I¡-–eWÅÃB²Öù4Ÿ3T¤íz>±(R|³‰Ùè\!ö½U[€¯N}GÒt{‚ßq]G럸ä û_iË÷ˆžp{´[¬%_ZëS×ìt=!lFû'$Äwy ½-­¢ªØԽ÷w_Ì5X âô®Ô«y4û3©åƒµó£ÕðQl¡É¿béÿß7h¿fžiÕ =)ès…ühûxÛ ä@R} Ã?nÞ7Lu(ÿØùYÕ{t¯ )UËw„‚ƒév¥'Ùòšûk+ωdQ² X~‡¡8r¤ÑàM Æ[ZŸˆ^¹Þ"LŸX;Ì ;;:>Qê±Ðß—ñõ#<0 q·Xæ\µë~"VcõçÕþ/¨ÙÌàz@#§„Ùèþ#ÕÏ®~”ÕcÐäÅ‹Ö ”À #¯Tè~à<u <¦ž(ŽÆ޽zø±Ð`£¶ýüXÕx7ìÁ®ír»¿C¬ê!-~ ÿ±o, ¡ÒYf‰É½D}î«äÉîÇÞ^Ý}¢Se§$Ÿ 3î±ÈÙåRt@:“ëë*öNöpŽDÙ:£P0@p}Ð¥áѲ³›Vß9[¸?pEО€{ñD&I†7¦4ù×ÃÈ[¹“ìÊK+Ôàï3šR·'0z·p€¦—^¸üÎ+«Ý_Út%/ÏOyuuØëO¡·þC[¡Ú”НU¸Ú¤È)›kOKñµaˆº€£È~{J)ðsp f‚…u^Y‰–ëÔÐvk>*|WU!ôÌÇgq9ÿÔ-‡;¾¿h$PÁàÒz Ö²=ñ¹®]<ŒxÖŸs³Óÿ!3Y®Z=ˆ¼MlRÕT¦×)k l9ãõ­yÎêW®?0ˆdG½GIòWîj-pVº/°ZÅV߬RL¬iñsàˆ Y§€JÁha«”"Íîí9óIíoûa¡ü)¥%·£M›¼TÜÛÈZ_•.õ¤q—D=Jq¦õËþ­ÕJ°ºÎ§ðbµ ½½ts®&JåØôöŠºP÷±÷9º‰TkÏ-z›F&¨l³®©Ž>†šiÒöŠ/DéàiI¤O/._ÓKèÝ`½ÿÓM4ÓM4ÓM¤™"yyrýI¦ši£ôFŒO/.¬h œØ]X‚É)%µªø&ˆ)f@ª7¸î´»ÏÐÓMUÓ×(®Ä-­ /Ë­ïž±†¥ï¨ÜñäÃs¶ ã)ÜýWÐÓM¦å0º/” †Ã­f—÷_ncoŒ4БgFí¦sêXc@7 Ç[öÒ akÖΠíÑ^3¨tlÑÄQZØj›| ®­$,^€¥îÿìS 뤳^:_íñi¥‚ÆÎl=üàò£[^©ï¾»5)jò»Ö®œ5Ò63KÝ`®®©ôÚú¸òa"½p7Œ¦:Ÿªþ&ši¦ši¦€ÄpÓ®6pì:›±i»ÏÁ¡°Ü­ùô8õ•«+ ¡”z{‰)£íàl4?ƒ-óo.þëµçY©}}Ë/h!ZöÀÖó 4Œx‚¨‚ 8tç¯Ú8¡¬t__ ¢XƒÑÓ˜àWBvE\½ôùæzÌ…ÿçßÈ£AzŽ*úþ5ûÌ…ÿçÞ9VÑM‡WN~Y,Z”òé]oh"††|¾‡¿>S6Ö:/¬r¬¡Án‘ÊÚÊÐßOžg¬²Ó¯Ðà¶8m¬¥C«§?,–-_ÑM‡WN~Y,ZŽ,Öh«Sè¦Ã«§0FÂSË·YbÕýÞí|·ö} Ž’ž]ºÁE7»_-à›ÊE£ÅÖu?ƒ%óêo>ïÓHæÝWø=òâ +L¨}ÆVÚòš—×Ô¤ôËèp[ñš)Ô•“©Ó™e×Ðâ—¬ê›Jlês,ºú4®`*šÝyé]îQ¬ÓèêéóÌj5ÓÏJ†Ht‚:xë:/C_žP²YWÒëÏnñÅ__¢›M¿÷òNâPétú)½ÚùoÑ7v׈#“è¦Ó©¢t]±ç·³iã¬è½ `: ÑD³Ä¢X.‚é ”Ò,ÓÄD¥/‡¯H ¤±Ùß§Ð Ñ,¥ðõ”ÕËìïòxŸÛ æAÒY}¯¬8#ä>ž° <‡4‡z4:¯YÐà<¨9W~†%—ë.[„¯,~âY%Q§?š4î¹Å_=NŒŽ½¨²uü^££5Ž¡äéüלZ¤׫‡ÕÎ7·I¬ð»Z’Ã\ì}ï=KWé3N´}ªyÒò,ÃTëÔ±Ú‹zg{/šªö¦Û¾õFΘLj×t+Æÿ!£½KÑVì+ÚíV´ÁVuU»7¶o·Z»aW]xo}ÔO£"êzö‹´z—Wª=^£ˆ@ò ý™f-5UíM·}ê1ËÉï{â*;-zÞVö-îùYÂa£æ5¸säÍ¢¨ßQ¶)ÓïôgNO¾b¡l Þ¶º½¾ëoIkA=±Rüš¶±Þ <›pyVýöñî…xßä4w¨·Z¬à¶º]ªÓ§V¨Ú5V½r¼ã¡owÊð!¿< ÑÑÓóôd¯Bö¬},ºn©XÁc:Y•ÏUªUÑ[ÝjßCe«[zPУɷ•oßo*Ò·Ê=réíxÌM¬(ßA¾´Pîæ±@ TÓ]2ë”*ñÕD¡ <íWœtéôV”¾Q+—O»ˆÛM(zã@ßP(åΦ5@tS¡`PénzÑFAU¦=sgm=S§‹¬ê;m5‘öm<Ò'pÑç'lùÊr‚ö°;+¾]nÚh4+ß–\cÕô6ÓPyµõ€«Síç}"YiPzjPc»+«6šQë›*žê_ÐÜÍEô©œô1Ðè=¿w)[l=((<„Õ9ÎÁ°wC_±å·ÐÔÑ~ßÍyÌ; ¦ªŸ>:é•1Éj4è¯R×Ð4é}‹ôl7M ºÔõɾÕ]ð´ éTßl-àt™»öbö±ôÒˆÚªvͱÇo 2eÝýš½)Õ*!ËЀ9ín5ª¾c… ú:b—Z¥ q N—Ø¿FÃpú«J_(•˧ÝįT=´õ¢ŽVõ0|ýVÇbôì™Ú*†Â¨yús… Ëwëtñ¬-U^šžåc\Ü0·f ªC®4¡÷"E×YñÒ ­O\›íUß‹C€îÓaMféóΘɾ´_PVôQŒ·{Ñ” (vRvÇNž#RÕ«òÖ³Úª·ÇK  wi°ÏQ¦ÿR™ó)Ó´`iëybE×YñAÒY}¯¬)̾QTã[mÍÐU«Éø_–žô—6į\ × èyQœ*ƒÅ‡Ieúˆe£ÁÔ­m¶Ž™u«0µdü.¸ÓÞ‘`ÚúÒ™MÚ­lèW_ûa¡þBë:ŸäGöÃCü…Öu?È톇ù ¬ê‘Û äf04£ºª…z‡ñ§«^BLËê îµí¯h¬&˜{~žR©_3Är«‚h”¡BXbÀlKaÅS¥ ËSÐs1cÈ"º­ÞˆA2©4-CÕTJ- Ü,ð:£Õ. bÊÜ/>{ôÓ3SÐvl}ý˜“´wcÜÌuš"úïíÌP+Ç»Uù¥yØ>XyÌT ¾ù½:iÌΨÎ6w;«ÞÈ`M—zžKö.¼å`p–bÂ<† 'uít§gNšô‹G[³Ì|ôÆ›$¹q¯Ý¿gCǼV퇩Ñç^òûÍû5§:þâìêë½V|óX |¸Õ¯mbqÔSʯç>ŠÒ»~“ïø"Uíγ©üšã’†\¢k^ñ*ë»àçó=…ùßÌiè(~ˆ”ÝyÚ³å­MGŠ;ôüqCƒzÿ¿lwå-ßΞÚ󉮚Ñ[tÕ  ¼šÁè·L5‡w±ÔªJ@[îl=5»³C¸(ë©V'ªdzÒŽnZÕjQ1É“M3AÒË× Æ1£ODÄ MÕŽÁìºç\iàeÛZo>Uſt¸éç¤Övøs¤V…t~äŽãÈGâ[38û·œ*‹V=|ü¼î¦ªÅ§}3ëƒ×¬°:ž—ÓË~ü6WM?XûÜtú† cš‘. ÚºXËjã¸=DÔ•Þ>±oÊôÅÙj:-æè6«õ]QD4spÓЄê£f‘!5¥V–•]ëÀJ ¶õ)J6Òüá²u)míZóÚb×ãôüÄ«¥ {þù‚è/´=µÿ­åïÙ¯zóÒiÖ¯\V}>Òœ~õÓÏ}®ôÂc‚éélc8•#A]ò¸°`ÅŠÏ!"(Ø®÷T.[%qvÇ-ûa§GA‰mí3ï½E…²Å´ ûhû¯Š¯Gû)ý°ÐþMĦ:…qϯ]å3åìÙï«çîzºùïÞ '“Wö%*»žò‹~’’fÀä3÷¯ihÜióËH ÎÞ[vâdÚ¼³ûc£ãÚÏÏç¶ NŸû(:~³®4”ùÆ‘»™´¢ï¿»o¼ÏöçYÔþ@a˜-íÒ „€)ÓÔŸh–Œ1¹úWòÀ¾’·¶Ÿ9oVQ¯|±ìԜөzÓ›4ËŒ±-­öAî–ÑJ¯T{ XÛb¯¬4ä g[m·[nîdJ Ùµ4L˜3IÒfWœ¯w9à™V½€=+O߆^ ØbûÚIJŸ”ß܉hí ¬ÞüÖþòœöþþGiJ®+ËçÝÝWxµî˜ÑMÛ`BÒÕÅÕúÑèGÒÇÌ}¯i¹Œ|žw¤KºÃ‡LŠõ~vOâÓ:` Nªùª¾ï…Ò èä½õxitÐ0¾\KEé~õb å×_JûD±±-¥ûÕý Roøù¤¢ï•õ×ç.ìO‘[á)ÔL7¯YT@=†ÀØF»·›®ÓŒiU¥`­+bg@Wä«ÕMvél³˜:iiKZ[Ö–õs(lßÎÈ÷g\ë§öSûa¡þBë:ŸäGÑråË—/ûM%²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëg e²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–ËŒþÅ–S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”Êe2™L¦S)”ÿ§ö#Cýˆ}Uôb4?؇Õ_A§ö#CÃ¥+¡^²¤¢Ø;…·åUÎ2¡‡Afé½k^PÀ´äºÇž†®¡Q ¤itÎÙëÄÄ»+½Å~‹SLož˜s¦ ´kåufùM/X\¥#:™¼wJ§C«ŠWüwÛÎ3C >IeokNµdê–‡=eá³çÇýlýˆÐðÈz¨« nÌ34jÒñf9”zÐ,êFÆô^/JÎÊFŸ³m]šqÇ BŠ` N´ÆÕ´èh»Wc,ëän‚‰c#í¥K.¡„ê»ÒÅaë}k§½²…u¸$›”åé0Ž¢«‚¸UuØæ‡`WÓeé~ð¼Ñ0 q¸™9eí=ZèÕáMßýÏúØú-™™™™–ÿc4?؇öÃCýˆl4?؇öÃCÆ¢ýñ ìØâ›á°–Ù£ZiשmÔÓEÛA{uë°Ç#Þ:ÖéÜ¿FêX’•Hôó=Ÿòƒ5ZZ×`óAç‘›»jì*¹INö æÔŽ­×°û—³Qõà< Ðó/5itª½c¹Bq¿^ buWvÒŽÕ—Cª8”ÍÙÔA¾/f¨]hFC*wVãíV´+ ÝÍ@u¤‰šÈŒ¶%ŸåÖšQÏN-á›7¬ÕZ™¦™P¾§^©¬Æ­µ×AвүIYF[´›á²+ôK G±méCKVÔ/DkµšÖÒ*²ˆ:¢¥íµÒí Þ@.‹åÃ)Çނྴð.ä4D,‡’³Ðt¸Ð-(5D,¿Mrà‚ÞÄ³ÏøÒƒP°;áö—³¡®2¾šÚðV¹«¸è¢Ó}25Nðl4Bô¯¸YÞʲZJÛ³{?sS©.¥–àuR±øtévƒDí k"UÚA!tÁ°Q}?Wš4„v¢—­M[z Bµ=3²>ÑÕÐÀô°©Þ‡Ža_CwÁgÐö´47 ƒT5N—K¥^ ·±,óþc&þѫֶº ‹Ø¥Þ´ºiÙÖ?Zñ©„ êÒÄ®‰›Óvæ2j u\8aÅ­d«€µ„{Sö4záVdúÃûa¡ãP‹(ÍÃþÈ0õ+>Þ›4=“!u–»tÝ–¶ƒFá/‘Êó—úŠðWºªý¿Êb­¼vT^Õ…SÔßwÞµÌE²Òõi³}V–UæïÞxê7[b¦ ‡VM^t³|‰‘®qmÜ!¯+ë9 ·t§s¨²èq›Úv0•]p»TQÖ;lÁ:‚iÍJŸŸ:Y“c‘:ÿ’º0zàõ›(Þ8·Mà‚Ïé]F˜=pzÄ«4ŠyºA¼ŸÒ±&5=>ñ ÀIc:½GêþÈö~YÙ/ªšþ™UUUUUUUUUUXf¨5µ—âl4Ñ% k@_zÿ%r[OÓg¢x­¤«ÉÒtpœ'Gi¶†›K1vtôþÉm?Mžˆ=æâ6Š :q †=§ ÑÆšm¡¦ÆÒÌ]=?£ÕzŸÕ}€ìAT4›¾·½ḭ̈º R¾œ§Fºóxo|AD˜òË^«êÀ3²×E·ý2ªªªªªªªªªª²ÍÐ/z+ÄþØh±톇…¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£iFÒ¥J6”m(ÚQ´£oûa¡âÉAK VZ\GÂP àá¦WÀAï´_Cx¦1’g½r+Ñ´Mùw¦¬áÔÜÌÄZÇuMqŒDh[oª¬ ¨AzÒYq´ UØ _ ÿ(D¤'W^Agô®£L¸=b ]¨tK97€-_ôº:. 4€-\êõ«û#Ùúugd¾ªkøUUUw¦j®úÆó²vNÉÙ;'d쓲vNÉÙ;!“ÄþØhx˜­x4Z™«‹wš¨T4ãm€h6‰è5Æ5Ö±àÔéòê~éÅ„tV­âº/\L6+6Å2­,]E¡tád¸ÁŠà²ÈKµ­!Ÿ¨=ULÐF®©f.ñrÔE@c¨-Û, î3š5çBçfÀJ© e¹º,`¢Üÿ’™$¤œã_cKŒÁ™}F¹CTSK8WÍS…,³‹,⡱Þî¬;kÒ—íRÇ* z…åvV çú-k£^"hà Ž÷uaÛ^”¸¸j–9P8SÔ/+°¢±?Еy—èiÙØåÃZ Ôf¹Túê6§'1- êëš]óYsgIˆ †q‡u×W˱X,ë‘ä^tÆ¢³¢Õ¯vѵ¨ÅÔÈ>Þ»ø=ÏíüÃCÄþØhšn#hæÝ6”á:8ÓM´4ØÚY‹³§§ônKiúlôAï7Q·H毥×WëEö ªÉÂtq¦›hi±´³gOOèòŽu¤W]\÷ÞB‰au@¥|9NuæðÞø‚ˆ51å–½WÕ€(<4ge®‹oøUUUw®nêºîÓºwNéÝ;§tîÓºwNéÝ;¡ƒÄþØhxY,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7ñ?¶ìCûa¡âÉAK VZ\GÂP àá¦WÀAï´_Cx¦1’g½r+Ñ´Mùw¦¬áÔÜÏŽº îó¸ÚP*쯔%“¦~}ÜE¯º7{õõưÒaþ•ôBÃÍkîùu¢jºvë-ŠÕÐêÖÆ®§®ðÒaþ—[e_¥í©®ä¬+Cáæô åê5ô¿³rù%_˜d~šÕÐ,z)ùðÿχþ|?óáÿŸüøˆÅì=Wyyyyyyyyyyyyyyxdñ?¶&+^ ¦jÁbÝæª 8À` ¢z;èfqu¬x5:|ºŸ„`z@p$‹Ð0ùf¾Ií¯rñrŒ}¶ÊøÞü#Lˆ=@)j«¹AbŠ €£,¬hJ¡¤,3š5çBçfÀJ© e¹º,`¢Üÿ’çœ2¦îCÈg•ÜMdª¥½g Q’Õ90¯R$^´‘gL&!ž~F7½u7‚» r³]ˆµß%†NüÿEîàúmWJÒun?÷áÿ¿ýøïÃÿ~ûðvŠ-æ¶´¬¬¬¬¬¬¬¬¬¬¬¬¬¬1âl4<,–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍå›Ë7–o,ÞY¼³yfòÍ囸ŸÛ ö!ý°Ðñ%E`‹Am £F­4E×Õ(]²Æ‘Ƈ±ZëM,κÕ̽š¿e=ü Ôú+V^MÕS5ÒçCó²½tƒÖ{Åm®šÂU%ZÑ2àçÂÀMTwÛÎ?উ›‹ÞåÅ4ÃHÓÍJ-‚[Ë>Š.qNjêãJ5Ñ5N¤jµÒ¯M¬½¬ÞÕ–¡V›êi¹¼ttj§s¤ ”Ym]ÑÖ©¾Ìj¦Êo=mJÞñþ@ª7t:µWF®§­k &éŸD,<ÔtíÖ(¬eÐêö5ÿ¸Ö%ôŽÕºž—£ÆøÖkl«âô½µ5ÜŽÑ4K<åòJ¿0Èý5« XôR?óáÿŸüøbs ¡ë{®ÒòòòòòòòòòòòòòòòòðÉâl42&¥Ý_{*ü¡jCÏu=εWÒ ×’n¡ní:Ž2‡ÛÃâ·L‡‰ý°Ðþ…BÌ_púC*ÕU]5UÓÆôŽA¥=“î¦Õt­'Vãÿ~ûðÿ߆g0»N—°o+++++++++++++++++ xŸÛ  —.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råøŸÛ ö!ý°Ðñ%E`‹Am £F­4E×Õ(]²Æ‘Ƈ±ZëM,κÕ̽š¿e=ü Ôú+Z²nª”×K¡µe7¥=o¤¹aab%´uJ5ɼv "Þšž²¸ÝÂVµ®šµÞ ÕH×}¿Éó^…}ÃòeÇœ\Åe9köß²g´³a®a½ ÐM lv ¯Lóà´©lwo€á$&д ¥ÑµdÀ¦Ž°MMÊ„´ ‚­LèXQ¶_BÞâÁ`5€ëMSÉš•)ƒ]h0.[BÇAÐÿ'ÈZ§Ýý…‰SW¤&\clhʾ…?fmKéÓ{|:Á«P,ÔGSÒª±‹ÛBSF6ãËú6 jgfž®›Ö¡‚VåŽYcQŒ,*«l•åu6Î¥ôé½¾`Õ¨j £©éUXÅí¡)£qåýÓpcQ%œÜq¡lZ¶ÊVåÜÅ ì vÚ,Í]u…fTº­/\¥Ø_Lí»u…é‘3ßH‘k Í0oYªëC¬6 q›L«ˆµQöðø­Þ-±ý!¡âl4?ÔÎGF¯É¸}7åEw½|0¨ìi+++++++++++++++++++ôÛ  —.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råøŸÛ ö!ý°ÐñKZ è@ºrÛ¥c.f_Âò E!¬ÀmYá fFñ×ÍÔ6ÏZ>ÑÐez•xVÒÈuƒÙWÍÿ–½øÿÀ˜ê_µË3ƼE žîž¿Ò½Æƒ.ô ÁnQÙ¥Kó̳]/jVög–ßb1 ðÕ¼*>yVÒ ð^OMU `Èã­´ÎyÐÒ± Ñu~vÞ©hÅœÎÒ£ä/ÝãëE1D]2mX¯šT«¤1cì³ÝËEï´hŠÎÙÉÞM‚ù¨Õ ‚³©¸Ó-…àÒ +i¤XU[¶n¾Þ~´. ¶|²ö>f„ï_cApFŽ©FüR½ft× ]n~˜u57 ‡Ú{^»{¼4+²{…Ó}o§zÑju’Ï4”éiµÐ Ì inŽj×è.kC<{Ú¾qœ.Æœ«ºQû.hïXà-žæ¤4X‹TÇ~Iá±~™òͽSYï¢Þ¥œ…Y4h¤ùý5ÄUšNSL‚ùÕª«¸F.ÀÚŸ­ônPM+%Ëf@/K¸PfÒŸ!£}ÅL°»)éjÝ…qEõäl)¢uó¿ ­C­ ãÝU8Moi€‰ÍÏú±Ðô [u‰O£¡èO$ÁÇàЕ¾†¬¦4Ÿ_ûë©5|~¤N…«Ï„áæ!³<t}UgÕ~¦§¡‡½UÜàÃÀ|¬lúò}qÝÙõeô™jÙvBN´<&-æl~¹5¯Ñ6|bå»K,jXµèVMù‰|ì^qF{Äî>J}A p£á«Ümãh#ZÎöû®¼F•jŽŸªQ¯ïPív­Õû¶Ÿ)a°„î’;ÄvOwѯ‡Ö*ç³ò´qè`uvüñö~zÌŒi²Õku£cNM0À¼óÛB¯X×èAo®q„lÙÉZ˜ˆEÜ0.˾E‹ÓC.c¨4yL§co1·j«œ#|e2mµÆ‰Ÿ’@Ÿ-Ý_UÈU^‹‚ö\">L_8È—T)tVrý½¿Õއ¥˜¬[}L!™W¼rþ]ÿ'ð¿ù Wé©è«ù_üŸÂÿä0¥¦§û]ÐüN‡æê~-Oö»¡øÇÝ;§tîÓº.^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_ŸÆÿ¼÷ƒþ› ‰‰‰‰‰‰DÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄI¸€:ë¦?>""""""#QŸýOÊò£=còG$oM>fÄæv>ß:•ø:5Þ7^üíþ„Ûñ¿Ý6þ‚?•ÓòŸUJ…—T6pRîWÅ6Gr‡ˆ+õEÍÖ×u—˜©º«ì [¸ž_Êÿk÷®áàWº<]}LÕ§UŽ çEí›ý¦Ùª„ÑÐø_[ÍI@Ô5ÎÀãïvVñ¨5¢ñc×Á«aPïÀ\óœ¦ëV×YyŽ[ª¬j®ƒºËÖMM0lêõxÏÇ“Xج³s_²|S!½A€)W˩浸$ @MÓZs«í½•nvø//*N(•Eò¶ò漡g¡rðs[ü<Ó¤¦­~Û|¾ðÀJù=ïj—iFj¦©H9Fô%F£rï“¡”ƒÞ!Nƒ€§•üÀ\ KZô/w*®Öc`Ó;ªtu†L+lÝ5§6ýÔ¯Àpßývó*$µ’é<âëK0Ô©[—A­¨1Õí¾!A…Ðè½ÌÒ9†ÒV.•ÕªÐùÓ 0Õ• ¾Kµ@-õ&”º¼âôàbòjX^œµÅBe²*ÍªÓ ¢ñÀ¡k¨Ó üéÊK4‹³nXÀ®œTTœ6{13'*Ý7®k}þ±$À2®ßòÝ¿Éöš&ûµ$Å~UÕíÍg›=B¶BÍlP5Áˆ™“•n›×5¾ÿXÒ`W@ïùnÞŒ\ó_Ùeå8-š½Ĥ2“JÔ妀/$½'fϾ‡ÀS*êë÷lÏCŒ¯ظö$®sPã¼\«L×®_Þ•›Ã-…wਠë:–4ÕÔ½ø{­>ØÏÐfçéñg×£íÜ44Õp¿tkš€Ú¯ûƒå„…6ýýp•±«j©iÒ€ö˘Àªáý8š¾÷)/«JoÏž¥ÊùW8(º=ñúè âßzú€ÑZUV½ªf†˜{Ù¯„}áNÀ½‚ú ¾èúÇÛñß©F«˜8<ß^ð¨r'±¹`Pݬ£‘Å—†ÌQ(z0-+qÔX>ë=A¬úk<1aE7ØŠ.(«øñu/æVÃbµ»¡ÎÊ3¶5m¡Ò”ß!´¹.qv!h ˜º”·í¦äkoë…ÈlbzMh€Õ­åïèläûBqA÷ÜÎG§}ê€cÁ¢- ¨Å›¶ÓHaé4e¢T ·—¿¡°z1;DrK°Ú‹¦ì¼„I"‰zò HëSæÌ|ÅÀ“ͫ꾿c$<«÷ÿ0Ûñ¿Ý6þ‚?•ÓñW2¸õ% Ò˜xî0,ʾZ6½ÿôV¡O0s•¾µÿ>+Æ?º¶…ÀÓM3)%$¤”’’RJII)%$¤”’’RMN?·â]¯û²ù—Ç«þðÞª·-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-FjüÇIo2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-æ[Ì·™o2Þe¼Ëy–ó-GómxE¯««å¡Ñø5CŸÉØyüj·ý"W¯‰h¸Š§ÔÍÖÞºâmŒl†TC-J¥[3kæSaÏù¡¼ÕùŽž¦,/«Óù¶/RhòâÇÆSØÿ55vÍ=_WV>޾šX±ÓGÃ1§—Îõ_ù¹N†ž×Oó]á½»KÖCùS4*«ØÏó^!q__ø‰¥Ô KŸ¶žÐ¤ÝÏ¡j$çé¿´¬¯ë_?Måz8½k«¨Ý@'Ê| ½ïˆ)Ë_j³ôcLi¬ôÝþêâíº«¶SÓì•ôg\k–[Áxó«ï=!cï7¾´–ÝÞsõmùròåÏö#è_TnSħ‰Ož%ñQ«Mb§£Vš=ôü%À4=ÈQϨåÑÓ9¤k²37µ:>Ã]îÛæ"B­ó§ÎѦ¿‚™‹´|¡úÁ`hÓËg¸¯0ÑÔ/_ybÔ =Ú¿«°.Ñ7¬}tù¦¹Ú<a8¦µç“g`t‚X aÿe¿‡é³L0ßÝS÷bí‘} h6Ò®ñiˆ„1TûÕöŽ˜[I0]dª0º7’ c`F:Ú^…9…_)Êd{Tî„;‘¼—aÝè:Yâl)jö­_±™àmà6sYÔkÜU]]¯œų̀( ÀÓΣ‘{ü.“4o½?³´%8>Øã¬`1ÖòôCe´…ÚÅNP24㸪ˆ½.®v¥_w™V‘ѳ‚ÇÙú?†‚ËÉïU拓ub–öË{5IE›#S½ pëôúâi4ÉÂJ}÷Ù§hAT¸¼”GÀXk)RhoŒîra¿Ùoû°.%z¿îÁY¾~×»çòý__åý‰ü¿±?—ö'òþÄþ_ØŸËûùb/ìOåý‰ü¿±?—ö'òþÄþ_ØŸËûùb/ìKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKG?‰ÐÞ¯ûÁÿx?Ø”©ã%¯¹‘÷Ž¯Þ³çxÔÃJ]5]XUyy€^C£Q}–)ïÛ MOuEO6⸠Њ[@íUIÂj¥eçú‚j²€×?˜®˜ûüú¾¸ºŽò_Ž&.³¬Þ¿h±f*‡j+zê œm3vòeu×wæ´žð†—|ÖbažØ(>&«Ú¯V¼¹þ šž™{ti>1Ô­ÀDºà›¼¾ ¢©°ò®­±„·…­, Z úqçóB¾¡´èi§z߬ñh[H¼å  ÿÑlÞWMTG„®í£{w%F”îpÿìtn¥,ä¦þ˜„=9Zè<™®\]–´ìÚžò‚'‹;¨À7@= æ³O¬éœVfÅ8šÖ.»Å;kñ¶]½µÇ46­»yà±/zºÉmhvZêë‹u¿Ö$MÝ—f÷ÁY-²ªYj-‹{d`B¯TÚê«Ç1W¿(«:练[êgd2™­-ˆòÝéä¯å–•‡ý9•Ó¥é|.×ÏÏ0¹ä?wèo´! Ͷ” .›¢žvƒk½o ì¦./QK‰¯¥EX‡#ˆaîˆ*ÑInŽB¨/δb"±ªé_/ˆuEQnn³g×L÷«JpÝe8ߨdÁ[`!wVØó|ât <¨Zò¢õÂù§û 5=–‚¹ Lwž¦>ز¶3úÂoõ ý¦µ¼_…´©òñ·p/I…ëj°YŸ ¡Ñ?sõŽ9Ño\+kG6x-CféQ×nåƒ6çh×kÝgÎ$ç%/õÌ®AZ"Û{·Ä¼\!MAÞ9S[ªB–Ù¡Š¸Â¼¼;z™žZ·®=‰Šk@Ô´¼éZ”kÆ)Ú¾´>Ìǵ¡Å‚g¬õŠÝý%ÌдûÍ8?<šž”¼Êúš|•Âfþ'Ê[ìMYMÞ\V Kk¶Ýþ†Ýàοƒa\¿ž'‘¿ŸXÎ ñw½ÞÛ]ëP»±x—Íýf$hMêZaÚõq’±F†ttŠÏ•w£Þ`*+•fî÷¦´.úÂÜŸ®*ÛïB˜Øû•ó–RZµïX@iC=¹>(bµÌ!Â*ŽÖ޲^øÆŸCî÷AoÓkØ£B‚Œ[Y¬åÝ5ç¾rp4¯‹E»UZµÆºÍ‘º;èí}é“ÙF¸½@w×¼ËBÔóYúÝuþ¨h¦h£ÕþÂMOž(Ý0tý"¥1_ãàÓ¯j"¨ZD«W›÷çÌܼ·ù‰¶‹×¹ðé[Wð%µóÎòÜtß¿>iÖ®>_–)ÕþZpñüð|ERÚcé§Åµæ Ì‚5ÙUí‚ù ²*¶ÿ«­œK8–q,âYij‰gÎ%œK8–q,âYij‰gÎ%œK8–q,âYij‰gÎ%œK8–q,ãÔšŸìãêщ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆSRjzi–‘«GgÃî|ÌKq˜"®ÛÊCLš ׊ç¯Â‚dŠÀu){Y¯Ä©Ëo˜ht´½¬ÔòoÇå¡"º×­þÑ49öçéUg3šð5†‡ZZÞ_ü«r½_WWñ™ƒ^à5ð>|ÿHjz“SÑÏ:ù6=îÖJllj§‹ð`†VîS _ÉeùoÔQ%tRêöèÔ©¸@MªŒóƒ]ø7Î4u)‰ïŒþ³•!9KÕ¶®\¯ ðP”s«­mùzÒÇeêvqzhÑÝ ËÍC¾29™:²jæ‹ÓsºJꚆݞjt&åÖ«•<¹xÛýX±–¯««ê:'Î&«I~§5=I©þÎ>·Ô¾¥õ/©}Kê_Rú—Ô¾¥õ/©}Kê_Rú—Ô¾¥õ/©}Kê_Rú—Ô¾¥õ/¯Rj³öj²mJãÕþÂMOÆ*AmÓÈþèê]ûä.û81eËaUO¥§¶çá(€íõp+ºZ)  XBSL£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÄÊdE”ƃêÿa&§ã0Ù>6Š .l&Úu¾=ÿÖÏå+ž%E¯üõ}|'„ðžÂxO á<'„ðžÂxO á<'„ðžÂxO á<'„ðž¤Ôÿ`?œ°“Sý€þqõ°…!_¾Új"ÕÛ‘Z—c½^õsT–ÖØ'w ÌÂÍÚä£Õ–SŒéq‡ÈלXjjõÓß÷KFÅ9ºUê%âTŽÍŒ¡\ªiÆtˆdÞ½à;)¯f^ö=ƒžoÚ¢a®×WÓnq³\h“°¿|i¥çˆ†¸õu+r´E(+‘øg,Uã8^5!νD¬ó¾«DÎw—ΟPÕ{s¿ÏŠË?œMOöùJ•êú»Ý)y£ñD^ƈµ…ê&[¬:;‚[[wpa­9ú9°€¤))ôäÑÅ:â LXƒ ¶E,½þ#ÖІ|›\볋C’Ì7[ù›ÃºÑN04PŒœ¹oo¼¢Ài…Zó‹ZÒתV|G›;.‹¬-í¥¬¡¨ås´+O¤Uè•Æ¢ªk6Jp Cd¼—ÖØ”ž//‘ñ†^Ýápqs[÷Ç;ùsª™ÍÚ¾«J¿Î&§÷ÂV—W‹â*l‡_D(WöôT-ŽSOà(°é}΃ì~Þ¯öj@¸ñ÷ñÓµ†mßÚsÃSÇâr¬• ~%§ô”æØh$x¹\éƒÝéOÌþÓñàˆ–¸¥B¿³`Åw¿ˆà)?9Ê7P¯Ïb±É(Ã÷úËŠißï5ßGÌÑUýŠ—þ#þÇ…4HˆÓêþ[ÃÕõòžSÊyO)å<§”òžSÊyO)å<§”òžSÊyO)å<§”òžSÊyz“SóØi#¥æ"§Xá¬ÇJŒ;¿0‹sŸûëGáumuC©dÓ¿ãÿ? =ßù£ÀCÁ‘Ôêre£ê­32ž.Çï¼_ÌF¬ÊÑüD£»¤àù£¶ Õ_‰nïˆÝj‹pió46ý¢#Oàlº;þ„¥qòÎØRÖlîM¢÷ªúøûíº‡ ^‘ZBMŒyöƒ²e()§×æ;ÔZ>¬ÖÐÕŠâþo?#NPiõ©rÌESøj0Ç£Ó jðMèŸyÊ?$6êÎLÊQl?'Ù?ì*ª¶÷ÿb-ÏDf£4"»£§‰ÈGÔ‘ÚÀèf¨ßf"‚Ɇ¬,4Ã÷` a£ÏLr–"j~:Qq\ñq £ÐÉ刲ÓW—ö˜(§×æe½—ê\EÜIWpª¿Oª´' {Ƽ…àb:)üA~ûE(CDî:î;ÿÛò5ô´8îé>§‰ehú†´}½At?F†+B˜­3¸EB½К2øš”æ˜ÅGL®VÁ$”Ô?™ô¬Ça÷——SÈ¥IøøÊCs´£Fzï«ùÇû 5?0(jÌ»ÌØœ$×÷™&Úy–Ì5dh솯ÒÊkGÕó:/D]’—#Õâl¯'íÎÛl{ÆGV&LJ²eœ2 â^Ñ%~„ 3+7D47¾gYðK:‡Ún“Oˆ¶WMaPhˆ»ÀêüÇŸój{Ài˜ Œ1Ïæ§Å í‰K‡†*iŒpq­ôÒb,úW2ÆäKÜ~f h¿š1²,$ h~þþ„‘khç)äý§Gáƒôþý³~â%§ÔŸù6Ëçi: K¥A°¾Íì»Dy"ÚOœNQâoÏÝ4O³i×òOžï?òZîó S:ê4kô!fÓ‰¨»v|Î\rfm’Ðýb,i…¯§dÈÐÁ!P[]_ÐòJM^6e•ðó”·±ÉßèE5OƒöŽ§Ãµò.h)w§ÄÑ{,G:“ÞáSÿ àì)CgyŒeVÖ#êhŒÚ‚³{2ü¸‡aÖµÏgþÍrÞ31år»Mƒ>¯0x޼Íá ·–^ k7_—ï òöÛ÷õwdmw,×↘{MŒW‚ •äý§oÑ ñ÷¨i—³3MQÙ5nyÇÄAŸç“5öŽI0Ï!ï1·dðú_ûÞ'óÀú¾`½˜eyËâtíË9$³¬I–üæ$ªˆc)SìKñÕ|Ì‚µ#y[©õ}á ¬/Ðež³ƒõbí’÷ 3eoÈGü˜c²Óëñ`ãvXA·óM#=È_o¹ßPÎ>¢B{çÖoóQҶزÁy¬×¨—¸d¶ðéÍâ®%5ibÞ3í1ò7ôÊSÞ/ÂTMOÈ"ÊÅ*ÞÍ«;L¶TúZ{aÎ~ˆßW»¥¢š „%4ÅíèΆ[P¢U“¢+Vú6zj_ºÛÕüš3ºY¿®´b"·òѰ?Am·ñšFvÅj`£dÁ’"·Õ<=1ÙVúdïè+·ÓIæFhÔÜ=4"·ñâ\’½¨øÝ¾ˆ¬ŒŠtKW·«*„S£Áo>‚ä0F¤è"–1"ëÐSFwE]_À- UÕôæ×‰©UÛêiÛÖ1—Qr?€Äx®ó²vÓÆxÍÒ£0Õþ ‹êÍe¨µq±qÚ4b+·ó4"µôQ,›ŒjŸÀõ F \ÌàÎVf¾¨ìžV(3Ñù@RÂZ¯ÕõÚéo^ìþ²ÌúXš÷d2JnÕ³uto¿QY¶¶Â…Ðñ^÷®±ÚOꉩùEPH6m:ßÿ€UdwoøÐ£dwoøB;"+§9hÁ6}_ì$Ôÿe,Þ-ú¾´s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£ŸRj³öj³©+dׂö]&^©Çž=æÀîNyÆÙÒ\(<°ø)çk‚«!ä-ús”ðm{kµÅ ɳ²—]4rµÄ¥kt-~ 5ÛX2†…¾9­jßôÝÆÚÄ×úBj²—+þÊVdõ}JµlRßqŸnÂ’Ú͉k¡y.¬¬]ÐáÒ*¨s†ž¯ÌÅ‚ó…Šð6ávÀ´*Û[°Í÷1Ú¼S@ ärº¸!¶Bpµg…YzXƉXblik·¶IR­ÒØÈqˆ`¼´•¨3¸±á[ñx½/´² p‚¼*ã¯é ©þÊiêéýoWû 5?ÙLÀúôN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:=I©þÎ?ØI©ù(hAxâe°ª§ÒÓÛsð”@vú¸Ý-ÐP,!)§ý†}|¯Ó_‰Êž7™YSúÄU?Õ“SòJb¨ ¤ ¶oÉ3ÉCå¯çÒn4Aó»ôƒVòþ‚×–šððÃQäS°ãïÙ“˜µ Pìö%ü×óK ü+ÃT½dù P‚ÎÀÕ÷Cçs󋈾Ô÷÷÷Ä-½ý5ý¼Æ‹nWbþ»:ŒfÔ?1¢Ø5üàó\é˜ï©³U,¬ ­ûP¹ö"VþZÑrš}¾Š7îL0Îð­k˜XTçæê|ž0ùÚ¯…9*ñÀÓõǘ±­ì+…úV¹F U7ù… Ù›kµÎ™™U¯)îŸñ,غ޿‰zÃKµê©8»®¶t½ÌÈ8/ê¬ï߇]ká¾Ç5ÝýZ‚íÅéÞkþøüÐYq(¿WÖÔ¨-ð¼ió(br·Ø4Ö‚º…ç:Z¨=åwÃ32È.‚ÿg¿êÉ©ý©Â¾ý%ÑNlþϬ¥òºr-3f ‡xBøZfÜÙ§æª_ÜâÈêípµåÍiuwP¶%nbÆùª[péŒþc¥¶—å³óó "œýtþo­•3‡.öë{³¯s R­üÆ_ÙPA/"{6ó+„Þ.´¹u,ª5Á¯»UÑw@[«üÿÜþe[42÷|–ë­lÊ ÐzP& à(ÓÚ(Êûµú¢g 6æÙx«t•ÌVvê¿ILŒ´½¿ ZêªÌ»ÔîÔ_…Ý…cX³¸µ‰Ÿ°5mgòŕޜt:µË“]<±Ûm—v¹ñ}FëCØ-ðÓ–ïoͦ&Ày@Ï&.·ÅâÇW6ÝÛÆ<öûõzL¼˜Ãæ©s¬ÏæÕ° åÏ]o£‹¶VÜ»Öüç·áÒ áJ®3es½Ý*ÚÞ´­€~Ÿ˜|é|!ŽïÙ®tŠÏ ÛœW¾oË@Øß›)o+XƱ]‹«Ëå~ƒ^Ûiù™WØËö~‘H4Ö÷o.6­4­E)í£ô p¥ò*FX×Ë}[˜¬ì=Õ~’¢ob÷_`,8µÕU—þ›™ÃÖ{ä§EpñU¶¦zÁÞºÖ¿˜4Ä\gÕþÂMOöQ˜…Ç«ý„šŸìãëÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'dìõ&§û8ÿa#eŒóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎyÏ9ç<çœóžsÎ/Å[O/WÔ.Ôj:…šcRݰ„àCÜØë×§9•hÖ…ˆìlsEœB y°uû„Ô‚Lè”CͶ×WµÊ#xzÚ»—5Õä3tû2O<ûMRSÙpx׸e«–Ö˜»­©ŒjS] ·Nƒ"Ö™,a¡¹¾ëB k!ÝCá}u‹l“d"l¨Né×3: G‘Ñ?¢¦Wr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]Êy¶SÌ®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»•Ü®åw+¹]ÊîWr»”þ1³!MW׿W׉¼šÌ£…7ŒfîüÞ|Λ÷žÍ]9gI»½5çCà”M0V¶·+\®Vv»:ñƬP'ëÿ‡ÄÂàÞÞ|À¤ªUmII\V+ŒE.tUïUU|QU¥bPUËm¾4‰×9oó-kå)wMiä¼Ãж¶·Wß~¡&§ù¤4ÊQoÕþÂMOò ÝþX}m---------------------------êMOGRRPn¹Ó›«:”–ù<þ"-Æ–¬Ô0.t±ªóüÒÓÔÕ¬ô(‹ïœ~ŸT;KÜ!ð¼õ¤1[¦¬ÑìÿÐÍÞŠ´"Ôò®øî¿™üLM_£4Ðû%ŸGñåØ¥Û¾jŽ÷ñï^˜´Œ”³éÇøÁþÂMOO¢Á]7Ô}.ÎÁÚ]†Y–€z5{[¶ 5!]]¬4²±ÁfñÖD h¥6\gr¯{݃CCY64^ÚbgÕdq`û¬wÅë;®ç ÑV×èV£| XW%Ü´¢”¼ïáÞÕ¥hTðN.óÎ8 ²°-ü/·ÁØÆUOaŸ‹ËÜh¿Yׯ§ÉÌ1u3îšáo^Ž&ZÀÎákË'wÆ=Â<|f£8—aœÞ\ãzƒœŒ6Ëó·ÉK:@|[þ¡›½?ÌÕô#4PQ̓¦ëFr6ë]@ØÚ´ íF~ôok3–·[+ÐâŰþq,3#KBä“>ÆIn*ì ÎoÇ¿1] ÔÅùÆp[ÙÆI±UŽ–lîû*Ø)c&p›îgöÝ«côö+åZ˜[ˆŽr0â÷ç@êP·¦»Æ]³q‘½µáÓÚTz—[YG“ãbk\«åÕ÷Þp€;ZgƇpMãB'øáâP] ½‡ ·6 ,4S6ó½ìÑvÛþ$71Üz¿ØI©è`uV;' ʰ¥=ƒ`òk˜ ®½ùŠ¥u[ÛUo-bÝ¢^]Ž"«:h޵µº¾]Ýâuã ;W¶µâóZLIëQ ¦¥­­Õ­-ߘÛk¾s–ªèušÏ;Í-4Þ9çÏpÅ:ZÖÖêùwæ45u[^òk0Òö‹áî)–ûüë-,çÝ.éç9ó –µµº¾]ùÿ ÐÍÞ€ÑdY®àîV vÆ#³îk5W¼*ì€|^zœ¨µ­­Êù]]âu£¥µqÄ£ÌcÁ´ µÔú<Êûk¥°y–ÉÎ ºkO9Ì0š–;'rNCg“|c;bv”·cAä8Ò,[†Žæ+ØÇˆ@׺É~}¦e²»wo[uÍ·æk˜Þµuÿšm=_ì$Ôÿ!ÐÍßåc‡«ý„šŸŠŽ€¡Æ­-ûàÕÚ×®hÓC½wPØ÷„@uGÊÕñ«§…ÓÊ{ƒìw–M‰wïnð‰Ó²ÒšÿÐÍߎ©o÷ßsZ íPQº‡ŠºÛ\iç╸¯ü>°µjµ<%ŸN33<@—ñ,œSêÔÕJØÏz&V̽+5YS%&³.×Ú`¸©2ï}¦=¯¼´µ¨ŽÔÔºû¿X}¦'Ovf\ ëâÑ™ŽI0\ÕÛî}.9AƒS¨÷¿yMêÏ…lUÕò¯æÑ¨´’Òµ3ïË"‰jþàß(¢dà~ jcw˜·"DÐî¨2œŸiŸs_?žÀÿhéÖð(Ýãõ…Å©™JáÁL­†FUÀ„Ìz­ht~óàŸ´@íý]=›ûéýþÂMOñfû™ÑüA–´EúŸDõÐÍß›Ô5}+ê?W;ŸhÃ[)xK¸.:Æ_Ò_œÚÞâ"ß'¼¥á„3f³èŸyå™0\—2.d:B‰e2껟¦‘Áy%¼ÝÇ´±èµIc¾~Ä4ÌBî®}YG5B+'‡’èÌ›€=l9DtO8%ÂY¿§gÓc‡ô‡aeĪzcÚûÌWú>£õ”¾f ÉQ±û|J)ôõ°å/ç§é —F§¼Rõ_¤­âé ˆPæ È‘(¹¿‰N‰eº¹˜–¯ë-nVþhÿa&§øŽ@ç_”ôPeša¥žòÉÛêTðûüŸÛ×C7~oÒÞ”¼3ø1¢æ”¯\(¯Ušzµ_žÉ›“ô˜žÌ—€ŠÖ¹ Gˆˆ­•õEzQƒ2À~²¶Cð!g/¬…þ=!p°r}Iïà¡—ÐçÇý‹”ôŸXÁtÐôZ"z·¸¦f8õôZ=³¼ªîùù‰“—×þ~ô]ÿ=ý iê}l´ ¾% }¶€±ò´ôúÏçóOöjˆçÖýÊUðWã'ìFµ©g‘Ùèû’îî¿zèfïÍùŠÿD ·‚.¿ÛÙ®¹KƧúg ¡§¿¦žÏ×óOöjˆçÜ}ú/É]Öû­Lxeõ™ó‘ôC!Ï©¡›¿1Xê‰aâ4ÿa&§øŸ•OóÈŸžeþù>”û~Ké(øÏÖ`p~Œ÷¹3³ë~º»ó>bâsù§û 5?¶ïnº€W ¯ÇÞ Æ ¶:»Eðäý.ÕÊúÏÍÙËÆûEZ‹·ÆÞ º‚ý#ã±cìþÕø½ãà*¦Ô™ó?Rb܇é~º»óuÿ×yû~iþÂMOì‰_Uàî($EÔN}5ì×'áiûGÙOÞq‡ÌÃí<(úcÔôð_ˆCM8äöõ诰ÎÉOœ¿+ª#õž-¶G÷ŠÑþÓi÷¯é+6áõH:Ðü‡íø³<ËêÌzGä™v‹žæ'®†nÿú¿Í?ØI©ùÉ BÉ£vEöúþVËû/²¿#^7Góàòú¦7Kêý¬]¨ú\=¡ðgö—Þ´}1¶©_*ýbnù(úW¨Êø„šª9À¯®Xó¶³êúÔ&ô|¡‰þ·úúܺûËCš,‹–…ZÖ/K÷ü} örçìE³'ÇóoËV2б+³‡Úx€ýçš?K<`¾1øz(~Ò¯×ß3–~cà˜u'Éë¡›¿ÇõùþiþÂMOÄëÇ1_aúÝRƵ|VxÕÅo´.žSÜc¼²lK¿{w„L–•‰g˜(œ'¡â®~F>Á}'¨—ÚyÒ}»òú„tÕûA“˜à¶ýSÙt}¦oœøoÓÃmô¢cÔ>¿ögÀ¯é=è|õÌó/«é‡}}râ‰òGÉêÐèú‘0÷§Å½>§í;ð~vúÅGTÏ“×ñ+]2áÃ_>… Z¯œ~°0Š|Õ—éãòÎ2M•‚oúÜ»wÇÐúåSúGðOÀÀ|“É´ëï°L”€hŒþ!¿Ápáß_] ÝøÈÕ­/Å×Ñšª»pZ €ûÙŠÖ³ÓCV€Ò·µÿ‡Ö­V§„³éÇn,vgGêw?Å>ËóOöj~#G¾"7ª·ëûpEZÞªú±ý ¹ïX±­—ܰù€d/êµ2º&;ÌfZ³¦6xkôϧ]sŸù0©øF7zÆs­¹® tµëp 8„Út.¡èZOTA´émȯîN ï‹•,§Dá5ôþZž(Œ~“ÄõóÖ*ª0ØSëó=Þ>OL#³ÝOÍO‚8ݾ¸þÞP2£ÓõWÓæ– -OŸæþŸ5üÁüéwv«ûJÁÇÜ\É# ê„÷KiAw€°Øäg»#ÆD Uh_Âê­ëîCã|ôðuõ¿Ò;hžÏí]ËôeM0t¯o齎‘1tïǪ>´ ŠÕå¦ýø. Ž}x >úK‹cö™ø_».<£àŸÂ¹å4úY:Ma[:ç#á4ŒFµG—í†÷0Ï€Ÿ(J>À¹?xMª£õM•Xäûéã×C7~7‹ª]uwE3t8Ð¥ZÞª÷¬cè[«Zëf°{aµ{aÜ0Q¥¾VϦ•Œyµ@8{ úàÿúÃóOöj~fÔk¤þqË`ª jÛ@ÌEªÅ|†p6±ŸÅ[öŽÍè1,c4So °k•äb뇗é Sƒ žn”ý‡ë8¦¯ñ¬®ÁEàñË(Ì3ïà8Kÿžw§³âˆ¸’žv¾Ÿüù¸»ýa£¢ÛÃl%¹G›¿©< ú'èúxÀùÌòÛ}3<¨|â ‹Íè“õb,ÒuwØe%Ä-­ µ\_Ì„-ºÍ[̡êò+ï*6£ßï* s<`@•›ÿB$Ð7hn:È0fŠûnþñì³að$óâøÙè{l¼)ú\F÷ÃÆ§Þ3ö4{Ucœ}™jf9JV^¡~wúÍðaX-ìrzgÅY4}}=ö~v½¾Ãózùž(ý=®!Ùú+ëܳ/ä¾ÍbßÀ{þ8†:NfRÍQïû )ƒZýsNb«Óål󿈲âšM÷Ce¿èGnèº\×Çô®j=Úû\z(5M“³í£,µšÐ¯3ø 3<}磃ÜqWãÿp›Ï&þº»ü°“Só ©Ÿ¯ê?x£z>KÿÔ¤´*ö(~np×3ò}cò®~CôbÐýãØbƸYsØ‚ºÈðm˜QMŠÙ˯ÛiÊÉú¡.¨"<&I•…W£Zé~ÐmH)0_îjþðŒã>L?Y€&;x@»ES.÷?8Šs¿._ºhx ?*h0ß+}kô™Æ€txûp\ý.zø* ƒ¸ÉÙºö„CyðÂUùGö^Ÿ*þvêÅ¿ Lé ˜Å<'ÛꕆõBX:µ{¸ú@S FG±GîúOp+ÜÇÖ^…¸CWÝT4ÏÝã ¼‡ÀÃíPAÍ~[Ññi¦¥{Æ_¤ÚIµ_ݞßtÿ°¹E¡¼à~ÿòk>EÃá|’]¹_« ƒrèÕð×ïŽyæüÁmWKxÔf «Ûßĸ4àˆ‚…Û`‹áêQó'Ÿoº×ÚpÀ»â¡ÙO­þ°´'6¡ôÃòˆðmqšŒ8‘Îæ¹~#kË/l}£t=߇þ_ÌѰ˜é4úïCVå‰õÚ4ëM„·« 6=ê;7pAÉŠâYP­ÇÕý ¾ÿÜMS!]ÚZ]o÷ˆñ/¹ãøÖh-Ç‘®°ÃPT^úN2+ûwï.Ñ£–ÚÏÑÔÈò_ ÂÍðþçàÐÍßãú¾ßš°“SóàáÜvHk½Í4mF‹O_HôYçwÖ\{EÓ÷iª;-GèŽXy'³[JLSD);¤ZEå«íRî±ÃàÏè !VʪÞËÅ}‡9€e¾^+\Ë×PÏ—/Öid*ò(·Ý7äw©K”j}Üx=æv2¨¥º<•ÜË4ÂûÖþsXJ°s@š¾@3Ðñ“êΫÆLp›V—*ª°ZyLì^•¨åv“«}á%‘ºUºPìiÿq<¬~3úNìû!!ju¯ˆÑŸ[?T8`k›Ï‡ý¨í:¼¯Ú¡øç‡üâh]@/*ðcP´ ƒÑ{O¹¯ê• ÁQ l!çR fÏä¦=®TÅ‚ qvßëºE#9W'Zz¡Dg.ö»þ÷Ìzê~úÃt ÏjèûJC^\ß½_¼p%4³OJ›sôHúñ>ƒô…IôÞ?C+QUÐÕ¯Øßâ1eê\oÖ|ºV‹„ 6)ºÚi¾@2Ñå¼ÿ*9x\?³£ À&€Ó?Îó †èB¯ùâ-š&<Ž=‰Œr¹°:vD³Á,P7m”Vß–Ï¥z!ú…žLþV!.ÉŸÖ 6Ty S¥ÁãÕ³+"á?GyNkö´–‹÷~Õ3\Üzý5Ʋó WGWÜãdz˜Å^êè Yæ5Ð/š×ưjF¹rŠ ¡ ‰RÂß{´Ù¡ž3ƼÃÌ7{zø¸Š5€ùËírËÓ-ï£ä€jùÍ{ø43wøÿðyüÓý„šŸš€¦¡SM@Ÿ08i5ä[úÏ©D:û4÷.Ò/—'×У»Ç´EöK‚õ<î.ùãÕ@¦ŸŠâЍ«Ê ,°}{{üÁöÞÒÿi@ó÷~"D°Ôz‡|¢…ØèÛùß® E^Ä]_‹|Îé_ O’ÿ•y¦aP°ìßß÷Œ ·ìM·Pøl`ŠÞå¥~¬J:‘%×w务}”æ>ý|)¿ºtxû~OésÈ~•~P½±>HÖ^Kåmüt¥Ï$/Šü/wô Vê´3wøÿÓM˜°“Sú?;8xÄüçõþ‹Ø/ßö”?$ôùäKëù积Áý¡µÈ}GéøE¼OßÓú½ Ýýp ,šz3æ=ôŒEv< < *Œ–ºˆ]­~**Ÿ”ÕŸ’ «?­¼û†w7(—TAf½¿‚Ý=TÌP[è S§¦vð¼7äwïé—™øÌ?ØI©ý¶Ý¯ÅÔÑ,ÿ»ýŸQDPéøŸÝñTú/æs_¬[ú¶ü«ùÿ͵×ëÃAz¼þvµúÿ¯ô÷f޾7ƒä¶Që¡›¿4ï!nà~›˜Ô²ýßä*ø×k¿ÁVZ£ nº÷Ò-s­àUé ½6õå#['óŽÞ££s_n®­ÁŸQˆayß×%ÐSÁP/8oæ6¼ö5·í(f’?TE¸%5<ù+½ftJÕnЮêxýp0Ÿdi†ðçÐ¥ -Àý8ƹ9# ”ýžah_†>¡p¢Nù0ìú€V„u\Y{küþC€¢÷øÐ7Z ÙkóžV±à´ñ÷ }Wð ”VáûÖŠ]8sé@ bÚßQ\z-˜‡H2èWÑ©µhÜ´š¾îúP%Zÿæ|Xuò„þ|šŽV_Ÿ Ê€—§s8rêÑ¥º°–1·s_Ñ+Þ š«Þ Gà ?™©üÐ nC~9Ƹ]½Nˆïï¡ÁunS8ênç5¸*oêêóùKê)¯uÞWsÜ¿Tºå6yß«¢·Iÿ‰à±z ÷»õSÓ?>€üÃý„šŸ±?¡ÂÓÇ^¦Tª›è:üFmCÒ¼¢ô7kZü°UeÖ×§º}Qoé«£V^úÝFoa^4~×ëw–ùv"–À”ºtéûúd §þCÓÀ>`m”n™Fgj–ê Ýà›nª‹T¡Åöjz#ÖH*xˆ•©øHÀÆ'J¯±Šñ*µ ©ëDSÎ .ÙÐ÷×ã–Pcð1j1SKì]Ïçþ¢uDY"›z %µ°jÇ mdyô0V±0ú…à†ùƒ© µÓš@(mG^Oyš¾¼ ÔRŽ +Zpÿígªðä¯5ÉýJü1õ D(Uðï£ÁJâàäò¾é©ÖqWAì0ƒùâ#$ÈŸª1ÿèh‘Ó”ýÅøY®m{ú"Q@¯ƒ, ÚM‡ñþáúhÈ^ù÷•ö€»È÷BýXMl<àûÃ'ý¾RYÑ‘Pªºø;6/ÔxMPò×@”[Ò8Ö³È@d)†¯kÇsjîz/“•4xl5«gÄ&£ø:Uÿ˜â½tŒoshE:·’±Ç1lÕ )¸Œ®ïáÞnx§+¿µÞª¿OŽXôqbøƒÓO‰z&û†ß­Î:ý<Ü|+úΠ‡°—Ó@F^о´ÍÛuåÑô©Ö=ÑÃî–VÝñ¾Ø‰CZŸ7ßëøQ;Û,ðŠ|GÊÀOHQ{¨®Õù"‰ƒ²ìýsu¡#/bãbînºz GºTÌ䵨jxÜ뻎‘Yä!žþ-ÿì¼ý3_éò(>!ÔeýêÆíL¨Ô ìä´|CiAÊ/ê¹ òcê«â}ù‡û 5?0LšçQÒ_®[SNˆhi£áÄâîËhE÷Ì»UêÉj[5H'°Ëàˆ^«(6# -=2ÿÈ_Àˆ«à_™§¸º~äLõvWЈ"òéí¹ÈïàÞoÞÞhJ4vb½bàˆ·Ñ?ìÕãïæ!Eß/Ú8Þÿ騳xÚ~‚ :,>óæÚããˆã—§ ûÎÁ¯–ÇÇ =bQ…™žw>baUÀ§k¥¿c£ùÿ ÛèG’-E:Ûâ ]4ês ª¯‡ý–S]M~OLÛSNþÄÜ3qã£ÿf?%@ðkûEiË“¨kAëöŸ†+F™àCå…c„ä—(‡ o³¹`‰`¦¿9‰ƒ7Ô¬°}̾¬y¨é,:¬|^°JáïM¾P, ƒ¡yUf†Zê4(„`eо¾IÐiýo«^ð?E}¡‰ž©M‡f¬rT£óꢥÛi{O˜€XÊò›_wée6·ëš‡Þ#8¢Õì­=¶`PBþBÊ>Fü„z[«Õ7èàÛæu^º ÷TB¹ö%¯ ³Ìù‡éÿ°ÈB:ÈR9 b®ê625«Å×?IHN€‡ìf°ãÚõL×ÜGàø5¼yvûQúú½¹õÒŸ,y!Lý¦Ÿ¬mÑûŸÐ› `6ÕWùj°zäX,ê•‹MÓóMThîãAì¨v2Ü2埩}GïŸU^q£ÔM¬ UÛñ™‚—¡Ö­^tO½$Xdºýjh¦ðbek:Ò7Å¥|³¤¯×Ïû,Ð\ á.ÛÛé†SyÒ75˜sV#l1f›óš š½’“Ízh[ñŸp|ÕO­©ãÂoûN-Ý*åð* 5 þ%ýpÍþRì|| {ý‡÷z1ÖEÔCµ#Gd÷žáƒÝÄ/,Æç5¢`lµb¶O1Nºåår¾ê± 7{YÔ7_O‘§š  ¸ÍWˆhƒ!`ÐŽü™²·$rÓ“äUñ»+tÛ÷!ãæ¹=¡|µ¸ÃÀZ§[à#Ýo.šï°S “œ…ŽÊΕx÷~€üÃý„šŸ˜%cø &7ïÏ>´$Юÿ‘ð± oïÓ!WôÏ>#„µü*Ú±ûžóAPÀpzµÑ\Š>ñ#òü³±=¾ŒZ„©hw|ä~Œ_„ñ´f0þ5´ bù[Ïx,™jã£õþWáô‘;w•yëÌ ¤~¯ $¯ûù#Z:Õ÷ônÔzï˜Ê¶r.æçë†>1øE{E&êiÿbËsÆ= +H(Ùs†›-ÞâªÝ}WWVú.`:úƒzH­6ÛÔΩÒ+|ñãÔH´¬¯©Ú Àp~ Ýùß>T?¤(‰,"YJµ\®?v JueHļVú3à ½X<ëðjÐ(PL‹õ.>íô€ù„¥Š'ILÊZ«•:«Œíà#J^*û/ÏáÍb›Ñ[1°Wj´å~ß½¿GJ2aw @À`Š—_€/àV.¸kï'Ò½\Ž’U²Û•¾h4(:N2%xÈ?$ ßɦº¶d¼~†íÍŽÝÅì´v5œ¿5É“9 ÃÕ·O8>¤v´#À t«îJñ‰õ‰ñxߊMlY»+å^hFðñ‡W–¸f›€> —²@Òìw§O†ýlºš•!ð•õÝJ†nîYøÊ—!m ÐiCù¡H; (8pZqëe×®l¼%A²¤t.Ÿ@M^ùдœxÖábÇaöt~§yÒ 2Yt4NfþÓøÇöŸÆ?´ÖÅPåutŸÂ?´Q¦µ¬ž›çYD ¡¤þý§ñí Xµ«ººÒÿN ücûOãÚþÓøGöŸÆ?´þ1ý§ñí?ŒiücûOãÚþÑØ ˆŽGSI^`€Ài?Œiü#ûOãÚþÓøÇöŽ€*Diúä@ÀPÖ"ä ‘~‘ò@ H±OÒþÒtÀ4oÇ9ŸÂ?´:U¤Zûáƒ÷I5@§ãO3øÇöŸÆ?´þý¥•¸ rüJ‘OgßÍ¡˜æƒ¿/oæ,„]I£NMœOãÚþÓøÇöBà)×â9%õ‡_§ñí?ŒiücûB’µ¥4N1XTP¬VŒ `ú5ûà N¥:üD e¦Ÿ¦"ˆtþÓøGö–fÜ87s-š†Ï>ÿó‚þÓøÇö€ío~ó[xñüiÔd%J#«;6•xÿ­ÅqƒÔWg8Û¡7RhÓ“iü#ûOãÚþÓøÇöŸÆ?´þ1ý§ðí?ŒiücûA®–ìAEìËŽ=§ñí›^<%R…ÔiӘŎ·æì$Ôü…ƒ¬º+Cº5Ö,ke÷#ì>`™ ú­FL®‰Žó–¯ª†X¡Dɯ^a”°2­µëðÓžµëùL2Ó_ãö—àÜ9šß_®Ÿfú«ÿ~Ùe4üPjÃ"›@ó@hiÏà°†½E“õ—µyˆZfê·¾<þ6gÛHŽð2­µêCN–ˆ F“eØ×¯å1×ðhóíèÓ™e.Ç럂ÀvõjMxy”ѱü°ŠÔO‡¢‚Óð^8]{ñæ‚8·NvŠÔ~ ‡fŠ8£K=t3wä,ïEcèvÑl0ƒÛ «Ûá‚-ò¶}4¬cͪÃØW×à3u´Øy–S°ÿß¶bг_Á­ÖÓ‡™· ¯~<äùŠ2Ÿƒ—žÌÁxûk‚~ —c^§¥ï¨õPËA2í7¡¤Úý¹ñ“æŠmø,¡çNü|?g¢¢4½ôî+Qø6˜ M›;‰X”;:wÅ)¾ZûDU:ú¨e€ ™vŠÄK5ˆ>ª²Ú9ãx¡¬D³^"*}T2ËZ¹58—š–ÐÏü~U&³zÞ ¤ÏþqþÂMOÎ+¼¦¾#)doß?¶ò‹ÖººúUºø f룷ß6.·Óð[ ¨ÿ>“X4_vmú_´AsW/'Š·=´Å\­‡‚em{蟀À¶ø)MzŠƒµ³æïµ—íÌɶ–¶i9¶ñ­fºãMyMéÞŠ|¿lfbÏ–½Õ‹Ï¼Ì†W„ÔW6ѾÒ5D€Ø'‹¶µ0·ø0svÛ¿eÛVQ†ò«ÊÕãP  Ö¯[˜Ô-¸+›Î8J¢x¯ÀÅw^ Ú/Ýú­urÅ®Rz«¬oV»6`·ÚÕ÷Ç̀ƛé(Л¤ñvÖ¦ÿÉÈý±ÿ µ¹´¡¡çO\Ê • ´;5;.d±wcâ—ßsø#E{æžú×¼M_€]ÕÛ¶¢£Zña쵯…¢óÍMÇ[~1KÝÙàç×7aÝ»öQ]µfo){hãZªõ]¹|; ªm±Žc¸Ý„ö»y.ÍsŽÀ'­@žyùÊûÄ ]¦q­::Ü-Ê¿ÁZµzŒ[¸ëoÆ){»<\ú¤5/] _F§Èf±`›Ô•²¶ôcG#{¬¾÷imMv&´Ë ej§ÙÜZ÷ßð$6C¡+â¬ïH†ÙRþ‹¯ÐÅM­¸uZÝ:£cW‰‚ë<ã߯|]š»óÉK¢½ß»GÁ(êkÍèýï®àmlë\®ï+Œ¸ J‹ª}¨_º=â÷üÅÑ›ý¢¡N‹<Ñ&¾Õ‚À)í{yÉjtr…W[~1O~‹üÑ·¾¯ÓéC›}žÛï¶³±êÂÁ}ÝsX¶¬µ/ÚÒ}êëðTØ[<槺/´\«ï/wotš/†ôg Ö­G°àÌlk5¦¯éK––½jåGï¨|Ýß–ô@:×n3÷–$#; hyF‡W²ÀY^¿+ŸÁðú ”Á³SEx.ûUãBÑGVNÖŸp3Êé°«› õÖâòy¥£0±¬Öš¿¥.ZZü †ÐèJø«;Ò §­ÏZ¨Û¬ øÀ»6šñ"·›ï—wÝÏ®°ip¾ØÐßL€0оšxJ½¦¥‰ÑMŠË›O£ vkÇ­\ èýõ¯›»òÞˆ”è—‚Ê[6«+÷¸…‰bL‚ØìhsF+J—À¶€/(û¶ú›U(Ââ“Ýh_ͺ†™H°]'-‹2Ù³ tÀÜnãxpä•O95(ÃD‚»5ãÔ®òšøtŒi‚ç{ÒŠ-Þ«K­BÕ‡õU÷û,@‰J9Àˆ¡á¸nÓ"ÕÍ•ûúÛ ¨ÿ>“ 8vо(+ÍVƒ~ú/×SÎ"­neãtðZ]ðÓ(.ÏÍ?ØI©þC¡›¿ËöjèfïòÃý„šŸä:»ü°ÿa&§æ KX)Ók•¶_!÷#Sä{~ö<Ü¢]Bú»×ß©W*¾5ðyÓž&ÈM/P³Q+@jËUHªŸ#9Àƒ×GO%¾A6SDàX-¢^=…ßÇG-©/¯Þ½ òÓ~P¯jÓ{¼\Ì›.õ~Úx€“ÿŽ{ïÚT7­a›ÛÛMåÉï¸è]ûéξ)O}:•QÔ¯¸Uk¿ÓB(mÿ™‚0}‰ã“ëÎ5þmé û¡~ÚËÉí…(}ÒÐÒµ«Ïzs›1°hc…þkyq“ {ÉöÞžt–%°¿ ûÁÒ¿T×Ùý£ Y£àrô´þ‘ÅkzøÆÚÒ¥WÙuïÊÍ`6'Wÿ~’»ì_盄oÝÿnÐÍߘí©¡ÌEn¯ÒVöÙìûcÿ"+Êiµ»bó2hp~ðâ¶ÒîÏ}.ï©¥Œ]¾8÷Íoo±á;{g>;"*wÓã?]:Îä vè,!X«.¦“ .”Q5É‘9¦îŦٮ+Tp²ØÍéU]5 *´ÙCa(m‚E­&è1½œ´SvY‡ È­6î«D!}ϪåÕÖjýPvj˜¾ï<×uM‚-]rk}qs =ýÒ„ ·úÇ¥­ PÊéàýó1Piyºó1§òæ‚Î_7l_oˆZ˺[Û÷ÆÖ³÷Çó:Ãõ&Ú­½VZ‰š;léÉ{qfIfZÎ*{߯Õ,z×d¾Úô«Þ‘¶ä/†ÃÓ&²À–Öš4ôrÜ*8[*üB6ÿÇÒ7—?û*Ný1#KÅi÷c‰µÒÿ÷Ûôˆm³fŸÛ'³ÔÖ¾OÓø¯RQ«±¼æ…,§ ªœâšˆc<ß(²õª»K˜n +•²³Š2 «Dâ*żY¸¥šÍy&[Rg’µ¡ËJ¤èÂ8gêªnºpþÞ°“Só1é;—šÙ¯ïÿ“[:Õû=÷€ºÜ¯¶úíƒh söζVˆäM'¼Êh®ªmwPJä½ç½_ýå‚€Ð>ÎëkrÛàXnb œX ¥àÏ«S­4?GéRŠB £ùz×(þ\WUíÚ9ˆé®o¾³É?[ë¬AGòõñ{ËWñ§rÖ·ª>æŸylûýpý¦*þ|ú8;‰—¥ÇÚþX‚T—ùÍóN³ïÏžå¾·ïØŠÎ‰õ?i{¿n«ŠÒ$#¿í_b-¿}üëý¿X#W´·=ý+ìERÿ·hfïÌA)Ú )‹7«]`Ñ^ÿ§éÛ§ïÿ‘µbió-ªóõ×ùÑÁÙãéƒéúpN*Øû0S@QZŠ3‚MK¯q|¡ïzÔ@÷´ôV²«ÄPj‘Ò‡ (B(ª¬B-{Š±Âˆ¥^5`lžÀ¥îÏåÌBëÜ_(ûÖžŒm™áGgÿJí±P×5@{Õ÷›?–T¼pÖa®íU·\ýpúlìuö¿Ý™2Íß¿óìq- â]G–ê:š0!ƒ‚(µbö—^Å´hZ…¬È:«Ø¨|§8ág=æ­o-,iª¼Þ­¬Ö‰ö@£:ã]cOJQ¹*†¿0hNKýà‹t¯m ¨hNKý戛KØñ]e¹ãé§óö„VëcŒR6%hŽJÒZÙʼ„TÝEµ·GP®#^h×{Í«zÚ·lÄb:]ƒâöƒÍ /]s–¦QXM³‹úZcL·ý¸ÿa&§ù†nÿ"Ùø)•*T©L±e—ü„@¢ùBßåjþÄц\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\%~V¯ì$Ôÿe¶bŸ]_ØI©þÊ[ŸÁ«û 5=ƇÚ_±žãzúÁh¯†øÕ£2Ü•OÅéõ—JÕÑÃWŸm]…¼@ž¨º×Þ6κ@­fEfÎJ¼rìáÌ;'F÷Ñ[õ¬§mcÝ®xÀ¥ÕÕšÛ$VRס‡õ‘ o;Ó¿û\.=Æ›ã:^¹«¦&€ÔëË¡?ì¯ì$ÔôÉtv G‚m¥‰ÛkéÏ]A8,¶œ )U ß5xºC¼t°§%ÑŒ\º%)QmÁ²j<Ì5¨6°š†6ê ³@e‹íïG)dzŽ©F¡ ¦ÉT]·¢¬ŠÏ ¥=ï\SŒnˆœ­o»éCE«­éeZòÄj©¯NP%®É««|ïØ£{ÍOaúÿ®”J8”LJ8”Gû 5?Ù+—._ö2j»ÄÔÿw‰©ê¦üÆÀ‹ÝØ\äWœçEfòF¹rì5‹bÆͶ6¼c5ÊMxÌ 'Œ+UJ¹H‰¢:'ùC¼-g@-|ÆæÌß yO $hCÓpì{¡™ªÔ6ô´r‰³ª å.Œ(ƒh¾ÐG±ÓNãѸ_ ¾oªh¬ÄD©D]‘¤|#Fú3.e¤Æ…OžZÞbô k¥¢3¸Ò“ßn “æÝ]Bãyc³C£y¤ž :°ï ëXZÓt¦†J“[KÅ­®hÍn¶èMÌó[‰í17ÊÊíÁ¸´ƒ&V3Q Ò^e‰p6m@û‹- /X€0¡mÖ°÷5hÕÆ1ËQ»Ak²óuÕ”©Fäƒ=ÖMÒ®› ±¤Ð@ƒò:P%Ç'I‡Éùw.„tª·­>±kf„éh¥VrYW­ÖÉMËÒkë›8¸ËK‹&´d]›Î%!½~Jk#ÿ‰’!8@N…‹~1÷ªVEÝ-T_¹2g1PÀrs`;߯¹ÄjÁÚÑ>‹m¾@¬’µÊò+5‚»Ì&õí÷8¸§Ï½-“⋬‹Å °Eƒ½–^(æ³&'ç/h>AúÁÍÖsWg˶…ëXc*²¶°²üw.E¢ÛPÓwM˜^+1ôNÀÛ&j¬2„fâö¯nèÛr8—¬M·¯£¯öñ5=l­¤+ÂVåç"˜dùJоUo-æÉõü¾‹×~ Zšƒ“SOÂ5Oœf¥0h-ÿ-·uþPЭ°uj¿4Qæ"êí~;¦Z|c!5”Ðh‡ šå  x*«»snvŽ£B6d yM&D 5¡^ŠÝ1|ÖÙº ÕÚ ;<©Õ&ƒa~­ä´nô½åFNu£µ–8q¦K‰CÂ|5÷¦3†êËòßæ¬Ø¼ÞA×›¨¶ …+ËX¼sQÝ2ð >JÏ=@‚µü²´÷ªÌ°§JÓ´l è𪴙³@ÛSm¶(™ŒSLÐ%ð‚Í{̺VÊ+K”֖ʦ¨¹•9·ÎǃM3æ-¶rz@S Yyä‡[C½ƒZ Y]‘µÂ¯Ïœüþ_ýZëߘÞí\lÚ¿pê§àÀm6_ý·Í!É‚[K»»^CSm«ã*ìæãS’¥´\™æ‘£°0”_AµêŽbšç7Ìk}+[ÌTÙy§Æ¼î¶¼XÛ[_7ÛJß[4e¡:k½çlyŒžÕÓ‡éÜÀå(즴hÅ5³qµÂ¯Ïœüþv»¬Â?¤Ø6>pú+]ø„ B-¥Ø{© Û´À4+YÉ[£J6Ë\À5ºÍ)cwŽË†É€PÜîh®s{M=Vÿ·‰©þïSÓ²vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'dìŸÛ„Ôõ¹¶šÐµñÓçÚ_ ¦šXxq‡©s\ OÃèš)V,à—±®n«zš~VˆŠDÏù) Ö—ØÕö…×^7œ™â"4ÿJh5¥ö5}§*xþs´¹ÃéT aoíWöÌj" I±±Ó¿Ã¡º l²ÿ¦M»%óMnS×x áiÀ³5UžjZ¢¢È]JÕÆÓrçÕÓíu‹ŽÊÝñîPõnÐa(¬ Ñzy38[K.šïëú8Ä¿‚´VìÁmU^j‘µ@ݥ䦮¨à¨BÇv¢nÈ>è—¤ Am-Ò„ÐB°#eÊæ¦¾ôöçü•`Ýgu„m^ß;evGw¡†è¹Í EÆmºú<of‘½ÆãÍ]ÕcFúwU¼ÁŽÀÔ eî»*ˆº¨Sú%ƒuÖ0»•ºÍ´8g ³.2;×§» q‹Ðý#gÖ³ïŽjî«7Óº­æ v c/uØ(qTEÕBŸÑb&÷âýê> äk#äÔýá¤ÿ` º8Ó!¥S’²‡dTmcaÝ«:èt&4,?YI¾¼¹ªÌ"6_Oå¸?¦þ[—ûpšž¶ ÛZSí F9™çq»]¶ÞJsÙ‡¯@‘pí¶.¾-ùbêöÖ”¿ˆš…Jm[.ëÅæ¹—ÒŠBxM+Üä–kM½J®ª·F²Ü^vßβí—+oÖP[M-Zùÿ%0Ó\ýuùÞjh¹“|·ßæ*µ¿{»óyó»×^u~X.[ïóý†šçë¯Îñº+ÎðÔ˜¸—ÝßfoÍæ 5w®¼êü°$\·ßçú;Á°Ó­ñï`Um\WDjZÊ!0ѳkúžj¥Ê¼èëÇjÚïßóƒ=EVßMMÐ/uý00mYk‹oûpšŸîñ5=;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙ;'d쓲vNÉÙý¸MOQ›EÖPÏ¥½ŒÈ¹dfF–GlǨ¶·›1ÜW]ô‰ò)4Š´Õ}5£Ù£ÜTnöôæ±mÛ¯ ¿I¬*GÙ¨QZåhúÿ”+&I(UÃmøÓÎ"#Oô¦ƒZ_cWÚeL’SÈ0ôÄAIý)C”5–nÄhS66:wøt7A­–_ä“P]Õnœ¼O)å<§”òžSÊyO)å<§”ò‰MnSÖÍñ¤…hãkªÅb3_™2ÅU´]óñ-ÐÎ6sŸŸBOAò´ü–éÄõV²ðVuʳ]M+^¨õJK­(ºº•BBófu ST6^ Ë6mW‘ôzÍAÔ[ô#Ém/‰KoZ–KÍ3(’QŒjPÝ_-iþL±”-]ð3i§nŒ$Û¦|ƒ³[Æëèð‘¼ÓHÞãqˆæ®ê±£};ªÞ`Ç`ê2÷]‚‡D]T)ýÁºÎë"èιQÑ›@òteû–½ øshøfÛæï›ŒG5wUéÝVó;P1—ºì8ª"ê¡OèjÜÓ^eyñÁáwrj«cˆ” >œ—G±Û4Ìt醺§g-™` º8Ó!¥S’²‡dTmcaÝ«:èt&4,?YI¾¼¹ªÌ"6_Oå¸?#èßÎjnSüѺ+ɬàO;Ç+u»÷2>o0«½uçWå"å¾ÿ?јi®~ºüÅÖõ}Õ×ŵ啣Æ}̳»×^u~X.[ïóýSë_?yFGFÕ²ˆL4lÚþ§š©r¯::ñÄÚ¶»÷Æ|àÏGU·ÓSt ÝE~@)4UÞëÁÌðžÂxO á<'„ðžÂxO¶ßöá5=:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñý¸MO÷xšž£6‹¬¡ž Kz3rÈ*Ì,ŽØ%Qmn+6c¸®»éäRiiªúkG³G¿]°6x´Ï¸ÂŠÐ+G×ü lºª<ÍÃË ðº_é#‚¤þ”/z¢óí¡«´ºÒøsìc ç®Ç—CöΑÁRJ„wŠv§%ggL˰r¿cWÁΚrE³‘Ôvû‰ÒS™Kµx´ûá²Ø&åÇþ™údé‘ÿ¦Gþ™úd>j6Ír›ž”þÜ&§­›ãH ÑÆ×UŠÄf¿2eŠ«h»çâZ ¡œlç?>„žƒåiù-Ò7†Ê­V•öê\4a«Ïø­ê³S=ߤ}ÿy¼P-†Š³U5•­"âx m±ˆhQo #bRÛÖ¥ƒƒ’óLÊd”c”7WËZ“<œ#=Æ;xÚ€æ.ªÃj7Êìhµ4›9ÉõZX–ž,i˜jÓ[Òö8šÚti€ß}`º/érhøþO¢ˆ ЫÔÇ¥µ®“hšÀôà}æÚ´ÆVô½Ž&„¶`7ßX.‹ÆDº\š>?¡ kF¼Äqo7N[€8YŠuŒ²`·ƒ^æC~UQ°d6UbMš£[¬ÂK­éKøiYybis?‚Õ[^†äã/ɃLÀåôþ[ƒñýïùíOíÂj~NØZ|Y‡¸ÿNªmõGÑ{×áªØ‡b£ÿ ü6?ðØÿÃcÿ ü6˜!X¾Ýן϶ÿ· ©éÑ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tN‰Ñ:'Dè¢tNíÂj»ÄÔõ±TФ·Pée­ë-h++Ô ©Éö® Zœ(u§Da—_P~ ¶4¸µ¢ó¸UØ8½õƒÐúSÍËÖ›øÖ/H5)²‹qÑŸtÛã˜`WK&xµªƒ§‘>òçfôtÅû¶W-kÞŸ;E@†DË¡åÛ˜ˆ•X=9ÃÆÃ¥4QÄ@À0´ÐðÊ.2YY+[6­øÿ ¹ÁV襺¶tŽ“ú`ë­/€>Æ9Ú!9 Â¸‹q{øËˆˆ©5þHÕ8¾ë­k&{!↩ÉYÆÙÓ0uÍFFŸiKµx´ûá²Ø&åÇþ™úd鑘 ®Ójà9þˆ§öá5=VTlÐ%»4nÁ¼Hص8=‹y§=f!L8­ª«Z+Áèº3¥º´kŒ­ÉÊ(ä‘dXâÀ"^\ðÀÒ! ,ÖàU ƒCF)h,22¡t£@8•P‡:ʺÐ^¸«€=tFî×’û”2àR%«,Å®huMå3êêÿG. Ë¢­ÀÀ{¼! ^Æè¢ÔmUL­l¼µ¦¼ÄeÂ6éÈÕ9ä,‚éã"dQ¥[fÁÍŸ×/ëwÝÄgÀ?~~áù§ù`²Mù)œr9VÕkÎ[:[ŒpâÎ10Õ¦2·¥ìq4%´èÓ¾úÁt^2%ÒäÑñýÑD]±Ï`èfÇc¤4fï/êsÚ`«LeoKØâhKiѦ}õ‚è¼dK¥É£ãú ÈkúW´ r^Z„qo7N[€8YŠu™EG‘!–?q„—…[Ò—ðÒ²òÄ Òæª¶¼! ÈÆ_“™€Ëéü·ôÉ©ý¸MOèCaɺî«íë¬@V…ùÏúETkoª>‹Þ¿ VÀ ;ølá±ÿ†Æ2ªë•ãú m¿íÂjzZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ[ûpšŸîñ5=lU4)-Æ”:YkAzËZ ÊõêrA½…먧 iÆ‘G%×Ô¤h-/-h¼îv/}fEÖjVO¾+㛈͑¯}+Íã̇~9Ö ’øoñý"J·K¡Û4 mQ}4/¦v]TŸP H§ 5ïu^îœÀpxwã`©/†ÿÑÐN)eîUž,È4§hBé¶W BþP÷„tX±ë#®”ˆÞäP¼~-G°-ÆZ@ÓEé߈ \œž¶AΤ/yüŸ¹Úè,ës®uι×:ç\ës®uι×:ç\ës® Sûpšž«*6hˆÝš7`Þ $lZœÅƼӞ³¦ VÕUŒ­àô]ÒÝZ5ÆVäårÀ -–4ÔrÓ\Ôu@SVT-ULm¦/YÑ)^q{ÝWpJ@ÅwQ×k¾ó=lBî£WÍf¢ªZÿ“âí¼•(JÓKæ¶ÓŸ€ÀÌÉŸÅÏÓX©ó`åv9ÿŽ¥Ø ¨hÛ ÷¤°Îu%–çžÿ£)ÑEíméÆìhoXé5)¡{0«Î”—¾|€Wض*|Ø9]Žã©vj6ÃF=é,3Ie¹ç¿è\¬I +ÍʧWKÂa+D«ù”³† /\‘zéBª2ÙÁk{Ü!nµ¼ˆ÷Z´"UÞÖâd2Ÿ(¯­{:Ä€5£íYø½\ùJ`ÒßOå¸=?˜åþ“SûpšŸêc Ôº÷ôSþþ€Ði´þO؉ͫnš³¾wÎùß;ç|ïó¾wÎùß;ç|ïó¾wÎø·ŸíÂjzZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ[ûpšŸîñ5=n‰ÅÝU®J 9u£sÌ ŠïAÑ)EV0È–v(8Ϙ3É)ø·ï…¤•ÀK0/”Õ:[®«ü´Q¹ÿÕðzˆ­‘¯-Ö<º@pxwã`©/†ÿÒ‰¡¥î®¨ËB-t&Fï^Ws{sÁáߎu‚¤¾üGWc@w+Ù{k¼Bè¶W Cî€kíp…l‹²:éHèŒP¼~-G°-ÆZ@ÓEé߈ \œž¨§\ës®uι×:ç\ës®uι×:ç\ës®uÁJnSÔã¡ M©ÈÞ¥dÈ‘¥"†FÁ1N6•QQÕ”F¥åw<úv%ì>ÂÃ{DÓü¸Vá2Òš®òy0dUãYö3ž2ÔTù°r»ÿÇRìÔ4m†Œ{ÒXg:’ËsÏÒSб0K‚•Ø«³A­2ëL\èÕ芟6WcŸøê]€š†°ÑzK çRYnyïúÍûLÅèàn8•¸4¨ º‚×pâ¹ì85t§€nƒçvòÝïp…ºÖò#ÝjЉW{[‰Ê|@¢¼ZµìëÖµgâõså)ƒK}4?¦ÔþÜ&§ú˜Âu.½Å}ÿ¿„ \ïó¾wÎùß;ç|ïó¾wÎùß;ç|ïó¾wÎø·ŸíÂjzQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(æQÌ£™G2ŽeÊ9”s(çûpšŸîñ5?Ýâj¯XÔ*oi©®<÷¿÷!5?×Zú‹P²-«qƒ¾½tþÞ&§ú÷4t·ZÝo^¹ ©þïKgûªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª¥Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²Ùl¶[-–Ëe²ÿû—ÿÄ-!1AQaÁðñq‘¡Ñ 0Pá@p±`€ÿÚ?ÿxû¨‹:®ªéðAËÊš\ldPÃ}"0Á JYÁWpë¤U´Seω¬‘Ø„PD5*ó_îaP6‘jöÑ&‚vYaêÂváû°ùM]šo¿™¹à>ÒÙ* \@m£ pÑØ"ðÒ„Æ·âï¦nxƒ1~ÆÔ‰œæ~æUV…l£Æf «p]†&@Î)S(Õ͔֯¶ÝGª¾m¹`¨IµilÙ÷ÒË6Ť¶( »HPÖ-wMXk+u¤N‡h²¯ ã–)çP¤ÐÔìæÉþ§¶àL­F†˜öÞÇ͹LU„¨b RB^U#ÁÉiˆ=ÇÁ Ñž€ÔKÇe´@ÏÛa†»ºÙx‚úÆ5)"õ.U`ò¡)Á/Š˜sU‹  V' `M7"x€ &…¨1Xº¢†ù3•ŒŽE^%÷s*íƒhÙpô›•Ç’&,lq »…Ã=„vÇ k ¶TÃ@jÜ Ï`‚- ˆj[Š4½€¸ß¤ Žl+]ñ£Zá½è%……ïM‡v‹€M‚¨øÀD€Èå-w&.ðÞìÛ@Ùw¶UÇEÆ †œ¾«2‘a§™—vp´aŒÁ½EZr¬ˆiÐ/€Ë)-SE¢ªXйvŒ*@»yÑS€(îŠÌrsÔ˜&FE?ÕŸá]ù²xt¢Ê @L¥gè5ÙoçuHʿӔ\Ð_‡ÄxVC£ûa›TD!póml˜ZÕJl¡8Å%UJ2`V±øã4ÕM«©ª¥¤ebU"×)ÆâØt•HøtÍÏ÷ç·ñ¢@¼4c„¿6\`ØkŸ}3sÀÚ@jÐáJ£JN1ìšÞ×Nwp¶.,ÌWi‡ª¼Œb0£Ú-„ÚºÛ5q«þ†ÁòC£:€- u-« ‡b®Å¯¦ÃhÂ:-Ï¢^ƒâ GvV‰¥úÏ8¬RâÊPUàR«z•pH¨’Œ+"@D¡>X0»·d½Té>‚ oQ}aT+-ܼˆ^lu ª§¶ôÄ¢C•uŽph²è*Ëyu-l°ÉŠ Ðgeu œÕ—td²Z¸Ý¢Ä}/µ€ Q]Òˆâ{˘^ÄÍ+X¤Ãå r>08 ímKØ ‰Mzuáy7Ì7–`ÁÉ‚–,á’…µz!¡VPp²É@ÒÈa¢SëP‰qR´ºÎØÜé2(ʪ\B¼{´ø£~Pî³B®˜U,ezâôÁ‹Áåf´+ÉqAJÐuG¤"i§º‘´[H0Ï4`]¦$¬ó—ùÚ)ˆ¥”(âšÐÆÌ€q$Wµ«Ÿ$]˜-)‹7‚À’Ò[HZ„|;|Am”ÂâòÐ]kÛÝÒ> ¼¿ÕŸáUù„²Y½"‹¨@L¥e©qÙo2§ULÊÓ‘8Ò_‡ÄxBb'@aƒ‹°öêÀ¡-¬«X²ÑRAV–4¥?kžAœ"(œeÿšír¾là`9š´º·_™¹ áƒP£‡ &åÑÌU´Celj¬1Ø]¤AUt*³s¦nµþ#ò¾#ó¬%›ÉfòY¼–o%›ç\Üüºfçû_â?+â?9^ƒât)Ч@rÊt( -'8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN ¡'8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œÇU©ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN pS‚œà§8)ÁN Ü9_Ïáÿ»pA¨¡¶£j3òØadU¨«m[eç?ýÙkEób#l(«¤ƒ@d·e–š(ßãðÿÓneUÁß/ûX¿íbÿµ‹þÖ/ûX¿íaP2©Ï ýÿµ‹þÖ/ûX¿íbÿµ‹þÖ/ûX¿íbÿµ‹þÖ/ûX¿íbÿµ‹þÖ/ûX¿íbÿµ‹þÖ/ûX¿íbÿµ‹þÖ/ûX¿íbÿµ‹þÖ/ûX¿íbÿµ‹þÖ/ûX¿íbÿµ‹þÖ/ûX¿íbÿµ‹þÖ/ûX¿íbÿµ‹þÖ/ûX¿íbÿµ‹þÖ/ûX¿íbÿµ‹þÖ/ûX3(оéZšj7aäª1VŸ·ÿÿÿÿÿÿÂËaµ-å]ñƒ·à5…?WÃüÙä¦"ÝtWé&È mÒÙ­Œ³^Ö™JÚ¥U¯òö. Á£_ô#Òïüßü¤t»áû¿^ïê?ÆÒGu‹ÒúÔÔ´ã Ñ… À§Æc^[@]"w9 \TW‰zÏ< 6Fl…ƒ·íh \k¦kdAqq DXÓ6(@Xi•jÁl‚ÎVË“Ð#["+ÄÜ£ú»¿Š5Å# p¨!—Á_ -Ðv-“K«Á DÔŒ@`¦*€jØ0Å–lì[§ ƒÅÌ—jšK54c&à× åNlºµ.. ,;2´Å Û £Z-5¦­êšwîVÁ7íw ÃÏÅ4‚°­þ Sñn!M¥²Öº%_i¹Í‚ì» …p@Ê•]€º.¢™ä%dFl…\D*ôHj J¥Ü<ÃE“&Y¢6#¤ak¨‘@JÌÈ[U’ g+P_‹c@Åœ¶A¡¨K]ˆÉ?þ£Pѱ-ªFÈu$ç$x Š¥„g÷¼+vÑdÐ\ BÔ;@«(‰® Tfd€Ý°S —Få l{b\éšB¢$"R´´–.Ð¥^”Ù+VǸtìÁ–Pã% ³ÉHÌ#£[š0­Úš1 ¦Zdº£hÅŸÑJú/õÚId¥%çÀ_ÍÄUTÿéÞ—|hfÑn±+7Q (à`ìMdÇbo”"eXµ¢Ïè­}úí$²RŠóà/æâ ª€*ü>Y—Ì”­ï7/TÑŠ»K%²4Å\¼ ,ÈZ4mYü‰€jX=·@휱+a‰S\}$Ñ´EœSL½ŽÊ†¡¤)¢!°àk9F¯DA¡MöM¢•¦Šâ× 8@AÔÍ ãüûÞ(µBmâëü¸½¦’Äd-,äÕþ(R”…d¨ ZD%Í,T0¶YcUn#a]¥x•] ÅY¡r(oQa¤´Äja&@âb®2±«±8,€±ŒÒð¤Ò À"ÚRˆ´Œ~Åi· Ä+hÛÔ Z90Š)n.øøž8\H¡€è I¦d6ðþ¢Ã©ˆªUº±AâÚÉM&„`•Al Œ\+x©ö@’„5 ‡ùPE¢Miƒ“yZšïØV¨~d *¢)GTމÀèQØ’ÄÊxüÏÔrdÉ“&O‡øzCŠVUŽâ(¨šÙ nQöf½„øóy¾ ™|y¨y wAf³€_•âÃl=<˜¾*VBРª,Í­æW]. JÃx¶bŒo€mAÿàe0m-Xj¬`”…r ˆ˜|'lGßd C‹g„YÖ=”·U[Vó>kÆ”ó%ù¶ ÁÃb›|4°Tû ÐeàµVÛ„T;ÇD€Þ-ÝÍÕ4+5‘]¦R‚¢ê½œ40M@ †öÃé5¦ @úŒøìë›ÓªîüV E˜%‘l]b眣 µaX×IEɬˆÙT°_iPÜ~(1ÆV)¥ºˆhØl3B P §EdH¿ M0.SRóˆhò#ÉBŒ¢ÔÀÊd{Ây+1jš‹sQ`¼"]µ£øš7éø(ÆM3P˘f§P ‹¶û&éH8D„\•­lzÁku`ÿ¦z]ðÔ Ð¤UPtK¼–…0ªµ®ã‰ß¥Æ€wlw웥 á vV5±èK­Õ€Tø Q®r²øB8H­‹ T5F}SH€©cE§ª…÷†¦ÒÆÛjåu (r@Ùihf3OÀ Ò‡$KKC0¤eÔ!ŒÉŒšÐQuû×à±H)LGÞ S€Õ h¬[üõÄ­D£M8j0©â™áµÉ‹Š./® ¾Nq{qPXÛ² [Ü@-Ñö/Xņ@uFcB2·xªÈetO H7©mÚÀ&§ËR[f(]©0¤9­+sÀk ±<ÜáÝABÖD:]ññ¡Ûë@ h5[VMœªÜAi­²(hu@毩ãÁî ·E@1i ׎†1d·#ƒŠá'äcF4c)"t»¶Æ±ød›ÝE03o„CÜR˜°–Bò‘xLK-%èÀG[0`0gç+Dh5EUusT™Ðis}â­–ÓA¾¨ÂX‚îB¨Ä°U'†°?€Zâ™D³}Ø@N»' /0Ù¤Q«8D9vÒóf¾#2FØÐÍ_Wo ”°BT3kPàiĆ‘ªTTÁ/@û­qïBZåbhRÔ<Ðè(I©¥nzúÿì—æøå#¥ß÷ÿ3ò*Á@2Íie⑈,„ ,Ö4V)ñø¤±²"°ÖÙ·Cú€¥Y4Wø)bOA}~ƒ÷ÞwûëqB£uDŽﯹß_s¾¾ç}}Îúûõ÷‹.ZÜøNúûõ÷;ëîw×ÜéNs¥9Δç:SœéNs¥9Δç:SœéNs¥9Δç:SœéNs¥9Δç:SœéNs¥9ÎÇöí;Úv?´ìiØþÓ±ý§cûNÇöí;Úv?´ìiØþÓ±ý§cûNÇöí;Úv?´ìiØþÓ±ý§cûNÇöí;Úv?´ìiy«(P*øñ”&CXJ;áš±ý¸ãŽ8ãŽ8ãŽ8¤„¶j6€eÉ…;ÐÆ3Š?&dß]X´¢àí ËÂx £>?ýج„,ÖÖ-Œ1Kfµ¤Ö¶gÇáÿ¼>ûÃáø»Š›q;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«.3€Èß™ÿ Ù'd’vIÙ'd’vIÙ'd’¬$Dã;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µgjÎÕ«;Vv¬íYÚ³µeÆ`°ÛAd[{€ … è,IÐiQ‰“‡‡ÃñꛈsÔ!%Bé ,Ù3íª¨Ú£aPÐL’0ChˆøTÙŒªÐ̘S_ÃMë%£Èχ³¤Ô«­×·òº´^™hÛQ5 ÂȧSçð©Þ‚‘€«Tšj2ÌÔ\_—ÏÅà•8Í'¿å\Ú‰dSLæŸ:cD¦DF’Ì:xÑŽ¢¹)kÓ÷ñl%F£{C޵*Z©AÅ™ÔÉÏ-3@–6aG$ pˆÍ /mç£ÕQó&æÉ­Z€©[t‡*ˆ˜±eqœ%«”¨ ZÊ«ÃiÙEíiWFMSÿiò’ùŸðýkŠ  9 ÞàUÞÚ¬Ëwêö}Œ0\›—xþ å?lµ´æÈ¢ŒµÙpb,mÉdbׇÃñꛉ†áH´)Ø+·TZr¼…@^ݪWÚnƒ žðFÛ)ÐA¼aб@°ªêoBª7m¶–À©§: `6b½s­F›ÓbÖ¨ÉFï+У„´[#¡K¶Ñ £ /±)+¸JÙUy×1£7dJîCHm¢£V5ûj O%Ë“}ƒ2¿ò9¹¶µF+E¯.º€)VWmÓ ï+Ìéu6Rå¾oWhB†ÀŠ¥ÜÍÄÎØ“[ U 0l9jÖ×zó(!é"¡¶.ïTÉŒøS.SÐm³Và£\¶`‹·i/×Úô§]¾‘S¤ª£ º·}1BX6Üîr@au¹@AË5¦4ÄAcJÛGÍ&QWšS$f+&²|kpÄp‚÷Æ3¡©B¶Å‰¸m•Ñùp­l%Sf4Ì¡ô8•^¶ Œ-”±Ž°é{\­²³f4Ì¥W\¹Jޏ0ãxÑ,Šš‹Â}!Á“P”«]—¸Æ0BÓ7Ø­g-Ý/aEDu’üU£\ÅEê«@…!À³²òÛÓ'  åpÖ:÷)•µÑRÛ}¡«D¡^È·+V®aÂKõÖîîñz¿q­Ú ¶È¿6¬ð·Kå3ăhådrÞT•Cæ†Â‹aQ´ì&±ÂL† [Ê9z•X­{­~qdŒ£ª äÛl8pŒ˜ÃO™§*¡Èë‹™"÷±4€ZãƒÌöŸ)/™ÿ­ `º1œ0¬ojd€+ÓW`ÌuCÚµs|(/f Y]@Â5c¬\%T܆uŒµ¢ƒalJLë ä…•£{6fó—.Êt¢„`f2ínE‡iêó@œ‰€J½k†‘€2V¢·ÍŽó¦b§ùîZRÙº&ï6QUNz¥á^”ý¶Dº+û“T\¶‰§•ô³òµãðüz¦â7õ©6 "pežŽ*¨jw|ÎÚÌæös`>S° ÕKŸáRÉðê\—\%˜°€ª w´¤Óø¼<€Ï¬´à©¢–º½Ø1ç¨í¥4ºz@£à¡b±PÀÀ kX½Ñ1H4@-»£d xÜ)D~ˆ›6¸UÚÄe€MX®u=y ª%-ææŽ­ˆa^LcˆÌiL¼`Jº€ÒVsóÁª·qÞÀáÀœ” xÇP0K´7¨Ö(=fFÂÝî À‹ÁÐ+³Y¤tYŸh¯x¦#m3c)ÐV‡ ¦@4ò‘ÛP°AM"éO·#‘Ò°°"]‰©:­à&4Ù6{UVBí }ØJÄ„# ÝÁ¤Îç[jô6Ñí2vÈ6íÞSZR+W+ê {J¼Ñ E!\dVt5Ý  hŠÃåº@+òÇd¡Z‘3W„ÈœÖÌÓbâPSF´ðÖ³"ò)q'Ý®<Ǥi<µU¼³9CßI4XXtɳ©‘¦íŠ”(Ô—Xc~yÿÚ|¤¾gü<^"»ãXÊÝZÙ¶@Ñ[}ÀpÓUç"÷0ÅÖ&”Æ’¥J4™У°/icpòÛ­îj¶A6ç5õ ׬;"®'"æ‹¶â1Œ ¤ÊÐ)1Fq4ÜxF3~Óà §g57¨ 6ê¤*î?ÙýÙg±2F”X5FÑ´½Ë’4Áªv ˆx|?÷`Ñð Ò%›‘å8{A§@w%øŸý–Ye–Ye–Ye–YdpáÇ8páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8sÿ4páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8páÇ8pá†Aµ—»ŸÈ¯´ ƒn[ª"ƒ.±EPF<~ûÃáÿråË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹råË—.\¹rÿgÃþé†2*µ ¥jvÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöÈöȤ9;,Ð-#^ß“ÎÞÄÉDŽD¤íáœL„Èä O‡Ãñ»OY~HcCŒ"äÒa(†Ð.é»(Ì€T¨ËkzM˨paÅ!@R£ýêGªòAÖedñ42–fÁmÌCÝ£SxÇù Ú3sýˆóùÙXÎ I0¯µkSd5\ŽUŠ'‡Ãñ+uÞöí­–uhKÛ€5—¼Æ rrÄä­Pé ¥™¥‹ÂˆVÖ¢¨#8Þ†ÀëUî0 ÌPS½cÀD©bõU£GùtÍÏö&¿È~áUuÙU¸sœT¦3Á› ™ŒçãðüuÄüKŠb^Ûš5Jˆ¥ºœñAb&(.1‚ÀTŠr¶U±[™Rõ|È7êÏÂ[„ëZD÷‹D.ü"ÕWùtÍÏ (l…ë©k1{Õ¢²måТBA…š”²ÔT¶­0¡o]§µ%ñ"1_ÂH±d{K±˜Ý2BÒF‰t]ÅxÖê¸p(ݘ •i@ÒÁBËr:>¾!ˆº¼\'Ft'”•ÂÆ@Õ¾ c…ÂVúbh,”#3ÚjF¬Áã¡cÛHiMË|Þ\µ×\×Ee¸‰L 0 ²Ñf2Fð—€ÌB.ÉT5Ó<еËK¢·ÃΕ+" ac$ïʈðudÙ/……Ä„H¶¨›¦k,l´–8n×Áµ*È‚SrUqyBšâvÍVáV¥gh€IbX›Ó›qªðiJ]Z»*ª¼Šªµ(" ~9¡Eh.‹«£IKh’.Žª«Å\5@ÑvÛ¢P±¥l¨½¥ÇñXp÷y}O9_&Ý,à \Á¨!hÈ ¬ \nlQh,kg ‰¤(Ô`BwRClœT؈¦<`à7 Óø5þ |?à~4雞 c=.Nß`Æ+‰P¢›º!Æ1ëá¸X^æb¤q.…¡”QvªcÁt¼]áêµ4J}mb+)íHP†·¢Éâ â°‹Sb1ì^Bˆ90ÓdgªÀúä¦S"Ìm”?8¹ã[q*@D À)VïZÓWË¥MDTªP«JW8-›Ü¥^;‚‚(p¸¶õeÛ—eÖ¯LSêÛãšlà Q’¥´a,ÁHX¶ŸMAPÀX©Sž¼Õõu J­Ë5ûYP®ÐÈÜŠð'è°âS“D0~B߈›Ñr½¬B8Så¢ÀRÆ6 H4?Ó¸ ÷mHVˆ§h6sáðfjùgtÝV5Ÿõf»k/ÙÁ1CfYM“q,“Ø­º¬«-²A,QYUf•ÝuD£•†i P͉%à 4À€°KÎ(†MV¦Ò6ÚPY©ÌÁÔÊR AΟ†¿Ô‡üÆ3sý‰¯òœã1³Á lgRs™N3[´Æt#ãþˆE0lSžM»ŒJÁÁ3bæ2qVÝX ©äe_ …€æ,¡¼²wh²+;2JðX 8K½ÐK&"[¨ëœYÐúKfËàDãb(%I©/«q ;7 _)j^mAúÿ޼E4˜K{ÕtçÀIª½RÄM‡D‚ƒ]4-— ]6TMfFÒU²7¹7{Œ;RQ„}Œu%S|µ›?Æ3sý‰¯ò šŸ­˜—Ôä €‡çF¢ùl¼GÃñvZƯö‚¼+eæO.½#HÉ¥5Ú‰·Pmí ™Û‘ì~ •K5Æ XA\þõ©'9{ÙJ°Í­å)¶À«DÕ!£BtcP à—z«0‹¡UÉÀD$T)³(¼Æñ¥:#v€¹Y(ÎKV0‘a-¼%<Ž uw$bSþ씈ãK¤ÖʯHY š@kc1÷ȶ ÓD0b0"Ì!UµP<¿Æ3sÃÞ[è`¬Õå[.ñs„%g¢¬¶êW›g…ôd[æ ]ÓéµbCHQ®ÑÉ ›žÅ¹°Cq/ðú‚#ÆÝ¶·*}] kçj¼ÝÞb!vˆõ%C@¾"è%¥2XÌGI°%Šdz"ž¥A hêQcÞ$–»BúA@ ~µÑ 3BdA‚Ô7´”1£"Áê’î*ÎK˜·tXBäÓdè^°qcQìÔ€Ðm¾Ý£ÞÛÅïT÷—»\峋޿6¼c:]´……¹^4NñU,i¶«©©åÈ‹FTÝ]”âf‡–wϰόØK?ÙIlY§š®ã;2˜¨­ŽToýE¯òœã5³Á+m'B3™Î3”Òu'ãþð?tÍÏÄÓÀ —„8IDªé»fÐÇ\ÕÑu£ ÍZ˜0®Ÿ˜ ý‚#!ts*C÷©6Ö‚ïEß-Ù&± V§[Ö h Ð 0i>C SA¥Jº±÷¹ LdP¦CbÔ]ñ‚@©áB(Ý{¤ ÐzQ»óК6ظV.pF[ +ä%-j‚é5éw-]·¬¬'5U È¢ÇZ/Hh® bÅ ¢é @ÿQký@øÀÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&OÆ3sý‰¯õáø¡b “WÆ;î;î;î;î;î;î;î;î;î;î;î;î;î;î;î;î;î;î;î;î;î;î;î;î;î;î±2ºãâøÓ¦nx¥¤Ž÷ÛyaP] Ë6ž8ÐÛI€/>“ "HÊ•ø¶&£E ˆ‰bA‰5XµÈ‚"4ŒvJ4„;æ-;¶EÕ$çŒÔgu «!ª4ë(üCP¥i¦š¬0³ñø…E/i/×m/ëkå®ÓÕuC9ã3Çv. †¡r4/ú›_ädTa!Zé` È­@…+]¦ x¾TÜ~x_øÚºÅ7±Z¬ÕŸâuMÏÆ3sÁ¸ä‚ƒU4 Ò´Ò!*pÊØ%–v“]ã¢Z¬¸0²L*¨iqŸ¹Ú5¥‘J…LÏ<){´«Ò,DÔOÃs¬‹”,ZB·Vi.켤Ö*¡¬A4’&ÑE[aÚÁíSu_EAxÉUá͈d¤]@ƒõƒ”6;‰“E©F­á4«€•€ ] ¥2¢{ÚþƒªµV¨·YuYÕœ.Áa¨"h£î˜C¨µoýK¯ò8ì*~ì·JU„<¸ =pè±Ôñ|?©¸†µm%‰£UTš"‹]£°\30ú è¥;imnú%ÒJ ƒ:ñ™›:D) …Ði-«ÅªÑT¨ ±oTÿM…+‹lÿ ŸAaF 4á0Æ9  Y¬ Ž©¹ñøÓ¦nx.ù8@joí#s@º†½ˆKkCÈ¢h]ÑEÒÚî·­})§@ý(EG0b‚Ú‹Ð…qKx¥‰¿t çÞ‘–k(›Ý -^-JÚR¬ScëV^" «‹a´ˆTŽ"Ú‹}h [Û0NÁ†$_×—{!àÒÑ‘moÛ"fDhj)´}ц£´Zèt6Jšæ¹Q·`Y‚·%@&— áÿSkü€á­mØELÒ#:@ P¸ñø~=Sq↠P½¹ˆV³¬€‚è<¿Çꛟ:fçû_êÃñ .  Rv™v™v™v™v™v™v™v™v™v™v™v™v™v™v™v™v™v™v™v™v™v™v™v™v™v™ Rg¡ãñ§LÜÿbký@øÀüiÓ7?Øšÿ rÿ€MË ¦®é¥…Ü•T,$ ‚žø:fçç^ç„y`-]¡CW˜ën•1fÕP3H¤«z©S­dŠ*À¸:£šØºÑ%¢Æjµ|pZÁu²ÿÓÒË,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²Ë,²ÿ,²Ë,²Ë,²Ë,²Ë,²Ë,¶ I K½xD®¯­a~ R›ŒWYc¨öÄœ¢Ø¢§—6¤kÆøÀüiÓ7?4ò°ê‰#£BÍŠm—¯Ë¶/S¬uÞx Æqލ‰ž-|:¾÷úÓ£â~ÿ ltïœ \±WAV9^QQƒ uøü?à|ùóçÏŸ>|ùóçÏŸ>|ùóçÏŸ>|ùóçãN™¹û:¾÷úÓ£â~ÿP>ð?tÍÏÙÕ÷¿Öð×úðüp”B G­h¨\3nŠ]<¦. „²Ñ(µ…¥¶/Çáø™NOª!¡nƒKÒKV'.4ç/13øˆ­FôS[W+dÚ%©§7‰H*lka-8èÀ6 ¨m2&É’¹‹‚°hÈ5¡fQ- UÏšò6J ijW¤nlíF­<à¥îá”VR2ƒIˆ2‹®< 5E^‘°Ýd”J .¬Å£¡Ü©¨ `5¹‘ÿƒá½Õ;6âà€ªŠŽ˜ƒð »¡C™èc÷|iÓ7?gWÞþ< WdMŒ¸IÚ¯û­ùÛ’Ây"㪟ŠÞÞž³8¦«]æ)œ+P{¸|ùóçÏŸ>|ùóçÏŸ>|ùóçÏŸ:fçì{„ÓQ‰-Ž®àrï5 i±4Ilç{h.Ž1¢r‡aÒQšÕÝ.µ€ÛÚ¯ŽV q;DvŸ€9k·Î;í\o”ùàW#ã‰håÛ޺פÝ|#Éjñ ›¯2ªÿœL–««·eÊ6ñ­WŠÚùËÔzq×›!°2¡zÄ|£Z”!E)ÝTwʯMµá.È+ O¤$T[sY^Zn”õµñö˜xYÁ|4o€êÛ¸¯ö‡Ä (]ÁÓÆ¦˜N­>:œÑ0ö'sÁñ³¯—Üc¿ÊE|ÑRöY .R¼M ¤±óµøj§Õôô5_²Â@%š®uqÄ3Á<‡ÿ?íá(bâŽwg£0t!Î- ØC~grmö`•Ö›ÊÔrï¼@Ÿ§l£àŸ k¸©Ž¥lVÊßrþ_7šV†p2Íö¨†íR/iOœE~ K8ðí°«oÜôekàbe¢Ö¢{]GäáE~ˆ#]î‚Åù]n0vi´\Ì WdΫ$ðE^=æ—(mWL¹E×hÃÞX0[R~Se}/g–‹SÉn‚6> P³¸¸ ±Èž9lôXÎì”ùÔ8a¯RÂá4=>#Õ0ºw8 ¾„P³ñ¶T÷š%0-êx1µ+^±CY±¿Úî5‹!|yÊTú]{Û4„úm–?O ‚ò»†«åx¸e´§%سYn›ß;ƒŠÐqf•%r¦­j¹Ï³#.óÞÄ óéê~Eª(m®À.Ÿ©qO \àv­Û¶ØÄ¯ír«,ÑíÃk©É{_¡\‚ü:>'á¯õáÿñ§LÜý‹¨µQj­O¶ì<´+±L6ñ³Fm°™zä¸M}ÙÐߌ«*ziÝì>bŽ$E£@t'ÃÔÝ,¹î³kö•ñˆA@Rm¶×3èðÁúDLÆí¹Ðkl¸Òí}UÍΊi½§Îk`0­ó™»Pò]µS½¦Ú V l0. Nh«ÈW–`ë%kä8 ]æÐÖ«ŸLC·ˆ0][ׯ.ï“,ÅÁèCt®6o6ùÓµ@ eW‡ƒ[*!¤ñ[Ü&5æméP±«\© }×›ÇGÙeñ¹,·l†1qB»SÃåÂ:/Ú/0‹­øÅýÀÖÖõ5‹dáóÄ«g­ã6w08íÉm2øÑ£Ë}Ç8ó[Kò*ãŠ.ŽÏ(æ½öá‘ ·eÔÌ%ž­ ÜHªßè57™©U®œa5q¸bÿl¾Ý-©°&ñ§¹'ò` #|TÛͼ^—E™°v½›vî™>U5‡’þ+¯‰ípErÿhÍ®WÓÁò¤vA_÷z1 €O9ضªˆ’‰êzaÙ)ÇdÀk…0:° Úã;ïHtî&;Wu£<%dÝmPhpÝuŒLméåxŒúw‘nm-§«åÀtvƒxïÆžw¾há }&[ùîƒN®à1u_?0¶ß›² ì)*Ü9eSÓ|÷›rý«ÊY¬dÉ:S 4õV>ý¡ë6£ÿxd=cêÝŠ/êÜL‚§8*ÊÝŠ¥ƒÄéÚ*s¥cx!Û!_Gz<ó=shÿº©Ž< Yµ€Ô³7ë³k|{‚W ƺÖ´è[Ó›}¡@ù‹K`¦€ø‘ºòtß¿ÕËÀùÒ!7LæÝ‡[8UšR“@¸ ï–ÁÄi<£2Ý£[ª¿aÒÔŽÀêâÙˆó/°Kr¹†jÊiøký@ø~9–Ê¡ ¾Ã.…AúìúÙBTÅÙlxáÁ%Ö¨VË3ê3[[¡E)€¥¢ÊÒ¶¼7±Çù_tÍÏÐN¥]t@\jé«z©S­dŠ*À¸:£šØºÑ%¢ÆT‰ $͹z³æ®]^ºëý{Á ¹0­ŒÖm•À˜óÚaƒol”à[ º>x ž‘= qápRVÄÓÕÇO8PÒö¢•³hó)¯üΑËWõóþ½ã–¯ëçý{Ä{„à—I±1ïç3¬.®Êºfd.¶îù§ =à׳zééíÛÖÐKÖ­0cêa'âtÍžñËWõóþ½ã–¯ëçý{Ã\YÅ6pwÆàöEËÎuêæÐ÷wNv!°÷«š«w^ñËWõóþ½ã–¯ëçý{ÇuŒÝEdØÓ1Â9¥ç=6Å/1~y½p÷…Õp‡Üx{ÄÜÛsª×i¦Mû2Ǩ¨TvŸ€>jœûn]¯< ÆËóŽZ¿¯Ÿõïµ_?ëÞ"›vÛ{œ «p½zyÇUº«Ægqåïµ_?ëÞû´h3„}=âWÚ‰œæ²4Æcyvì|žñ½JiÇ·×O ±«ô³…t^ýK•ÓVÁ¶&գ߄rÕý|ÿ¯xå«úùÿ^ñËWõóþ½ã–¯ëçý{Ç-_×Ïú÷Ž]^ºëý{Ë•œä·lÛh8kqšFÏxý‰¶âÎoCƒJÖÛ Z; ‡ ÊFt¶-±êv·-²·o@?¸å«úùÿ^ñËWõóþ½æC¬_‡‹;lkjï«f›¬)¼a|k1,ªí?á²üÕËWõóþ½ã–¯ëçý{ÄÆWzµô2lÓ|¤€^/«ÓÞ6@ºìÝï6ÓAܱ7ðŽZ¿¯Ÿõï2G+gœ¶/‰½u™™¥Mt¦mDÞH¸zðã7€<"iœM´kH4<&~±Kmkb´­=áµöZ§µkvØ•SÈÓ>qËWõóþ½å[4"gú÷Ž+–¶Ìçyåï*ädjUÕc4ßµ_?ëÞ ¢´h3„wãÞ6&5bÛu»Ku¢*òÀ´é¢¸âZU¹—‘VC•Ú¾L§MgÏú÷€&²LŽæ‹>®<<âàoת`ã €p#$êZÛ¶]@²«‰¥¼|íËWõóþ½ã–¯ëçý{ÇŽkàu¾Ö èo„Ô`±S@e´f €kõïµ_?ëÞ#qJÍk¶¯¼`uVR—¯/y¬ÄÑnÐð÷á3LêƒóHZÞ¼!v ”ï™â[Â5ÂØËNa£M?ì‹8ëB,©¸û;tá èŸøËEÿJrÕý|ÿ¯y‘¼(fr¬·MwÇ=[û¾¾ñbÑ“:)Kƛ㖯ëçý{Ç-_×Ïú÷ŽZ¿¯Ÿõï•UUªÔ‹¼eß)Y^möù6mÛÂ7OeŸëËÒ ¨¼‰ì»>´Q]šãxÕ0„®èô—¦"–;(ònÅbœµ_?ëÞj~À&º§¼IV­µŒm±²QmfÝ][=àNu*jcSѾ(q9îrucF½\ ï’]x¶ÝÇ-_×Ïú÷ŽZ¿¯Ÿõïµ_?ëÞPç©ÄØÑÛ:žú³Šû·„]÷Çh-»e4ªe¯¿ zÎéMYÀ¹izËy‹‹xï[4gÌ5aW/Ìé­³+·$ Ó¶}w5»Slµ£äGØY~[eõ4~]üc–¯ëçý{ÂDkAGÓÞ:/·½µ‚Ƕآ…èÝ¥`»aê&Á\꥾»åä³Å¯>ê}¯|gö÷^|×:û°Û/Òª»¦ [zÖµ³è´Ævfó••åbeîÙ¼ˆµEÂá°wVýc–¯ëçý{Ç-_×Ïú÷ˆ¯ ²ZêÕî÷‹ô3Y×Z<½ã–¯ëçý{ǂۿÈ÷Žj_ïáåï-tÍÆwž^ñÛqiÅ·^ñ…ÛwF»ËÞ9jþ¾×¼ziÄÙ»]³þc KØ`ÁÃZ‚tãXˆùó‰Ì‚=8#4á>¦A{^ð]F•‘ËWõóþ½à¢t ê>žñ»ÍªÛ²èöÛ7º5ɹQÐi¾-¦œƒÎÖk¿mC.¥±¿ iZ_šlòË­®õr¼c–¯ëçý{Ç-_×Ïú÷šŸ+w¸6›ïP T1o88Ž—éG÷a]Þñn©1€eü"WWְοG¿Ž¿ÈÚ™µÀŒ_ˆ½ì ‘”Qo‹áø–õÄú!i|,±ÙfÔ‘DKe—¶ÑqHC‚@«3‚‡m Î c„ ‰éþWÆ3sô_h÷îb/ÕA÷žñœcªbg‹_¥½á[• j¶$$¸"Í$P6»ÜÿáY¼ê60€?^¨$1F PÂó‹Ý_¿áŒÑVªØŸÖŒB()P††×{—üt¯býÉ7ÝaùˆÈ7ާ¤)¯GËü@Ld h‘–󶯚ðó›<¥u8‰„uŽ€éYj›ÿª¥í$Ó…N^AÇQ+½B@Ú{ˆ:ŽÃ_ä ]~’µ !RБ¶Pí%ñplx`4<>ð?tÍÏÙÔ·¿ÖGá¯ò Ì Pîs‘J € õsn¤$ªˆoÇáÿ&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™?tÍÏÙÔ·¿ÖGá¯õáÿñ§LÜýK{ýiÔp~ÿP>‰*` ±¾¤Ò ›xÛ*£Ž­a«Ù£EBÔà’ëaÓ&ž«†šBQ:íõ5h†à7v*Ý'Ñkˆ¢ìç9ÈLC ‚1Q£‹,Z˜cX«êæítD´;£XÏ›Ì6Ým©GcZ·b“M-kGüO:fçìê[ßëN£ƒð×ùÿ¡M‚{#«z¦…̆|È(ØCÇáøœÆÞ6¢ù!°Ó¤ !Í-˜¥Jª›³ðe… ·ªÈŠ©€ZN°Ï4×DÞè}bÉ®…˜Yo@U‘ Hhq(d…X4@/u&Rå©wÃö ™f¤›Ü š»ÑsOµÑ[UVÃu‹¤ePwxÒñ·DçQƒWAe‹?c*_+Ñ¥”º`3 }"x2ãe 5«t¸A0ÌnAL.Rš2´Ðz Ÿ_ä Ž™jùn€+n JkÎ)(€—dGÇáøŸ¿X˜-ê¡zLÍ"‘ša¼XæÞjnƒM†Ä¹3ð""¦œ…?ËøÓ¦n†þE)Ak;TÒð½–lˆ‡q‰Ÿ!AzËw—9a9ì.ÿk{1ì fõ«GÔ]ˆšê@¹F°«ÚiË–s`$Vìkö„µ wM½dRƒjôʚʳÂÓa|†­ÆW¢šTuÀh¦µ«~Àµú&®ªªÚlq)äq˜6ìVõì¨%°Dè^ÖHÍ–Vu²P(`À¯;â3Òyjбn¬M,h¡"[ ­ur¨hÍsÃTWö-cèΤQœ…£½£öÐöŠ çh¬”Öªþ®o†êE·•,× xEvÆÀ…(–üSö#Í… µnæ?óS‰¨Ô52@†“@ Nì ¼[ºXÍݽªX k?úñ¯ *èhAÍŠAA7Ø`6%5 ÒV¸ºH«ªc Çíìᶉ@Š„V‚–ɰ ¨E)§KÁèk¼*pZà¡1ens“W²¿eçXF³(¤º½ÐvMP$Ò½û%n×huËÇP–Ó±Á}ÁÀ© ·Gì¿or¢f][Â;Ú­Ó(iÖƒ.[ËTXËÕ?_Q— Ã9_ì¡í AÎÑX(êG” 7Œø…ׯS2…ªªÑš9XÛ¬ Z¸RÌ~Zÿ 0Dà eÂË6UÌõp®\²³‹J4U߇üÆ3sý‰¯ò—5m4Ø®]i¼e5m6ØŽ )¸<~ð?tÍÏö&¿Ô‡ãÓܧOr=Êt÷)ÓܧOr=Êt÷)ÓܧOr=Êt÷)ÓܧOr=Êt÷)ÓܧOr=Êt÷)ÓܧOr=Êt÷)ÓܧOr=Êt÷/:fçû_êÃþ© g""!ƒTÏú§N:téÓ§N:téÓ§N:téÓ§N:téÓ§N:téÓ§N:téÓ§N:téÓ§N:téÓ§N:téÓ§N:téÓ§N:téÓ§N:téÓ§J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*Tþr¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J•*T©R¥J• g­(0A½+ÿ#_ݨJê©D,ªŠ ³Q…Ý)j"‰âø~7£)hööÅKÕƒª³S·ê¦Î’f¨)DÖEIk à dx}@ˆï „K‚ŠÎa›³k¢(ÜVÁRÝá@080Œé`¥áᔊ —UnӬ̫J5m¦hS&3raFðÕc¥sþ‰1è°3På/è;«æÖâ!X£G➟ฌ"ò”±Ý`Ÿú$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D„@MB Ö4Ëêƒkÿ¡Ñ"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H‘"D‰$H­i B¢&‰ù ![Ñ! «Õ,ç%¨P.ãðühèX@l¸¡Ò˜"õ*›P¢›¼hqKX0:ÛÌÜ_XdMÚ ì²ï–=©ÆŠ:´Û@Mã°¢dhƒi¨BîÁ•aÚ½-‡³À‰©4°ÜC&>³ 2ÛnÛeúpTJ6ÛkvͰŽ:)Ú,;`^àn( QAS‡T©E,˜G³]«@ÔFðlÜ&£jïš/ÿC‹b“ÆšÿÖXü‹>‹ÿ¢Ý aÃù:ZŒ’ÃM¼DPR:.Ó\øÚ·Ãáÿñ§LÜÿÐô]ÿú<¨ø‡8páÇ8páÇ8páÇøÓ¦nxà *¹ëÁF y°ÃeŽuvd-bîC©  ZÜL=Œº «ׄ¼~ÓÕÒkQM¡püƒ“¢Š LÚO7 |€à¢)’š\þ;¢ïñÁO §  ÑU¡{I¤éÇÈn5[lü°ÿPZ­К!ìH›PÈd4üÜÀ067ªüx WvT~b«?øí¨ø:fç‡WÜŒF¡PBÁÍSŒJãïuqAžsa5[a Pµ-º°B@¦ŽB¥qhp]¿˜-rÍ©PT*F¢åÊš ЦV[°¿?®Ö(ÒÌ’ØA‚·^¸®mŸÐˆáÇéX†PpV‹j“#ê®ô²õƒ‚,õ8‰ªN†±‚9o¨8V*î6¹U䀡Bã,2ßy-„2QFõ¸lYíe\ÑÊg0Îtzã¯.4iUy Ö†ÎòźAp‰ÑJ[eïu_ügEßø`¢c;‰3¾î+¡B¢D?ÛnŠ ÔíÊ̦©MBÊšCF›¤_0!-õ¶%J>ÕØ¥Y&ði©¦]˜@¥@ö7(ýXà€xàU»¥f:ë<¹¤,1Xi1´ ,ä²m°¥€L0àÁ4€ƒà© غA¶°M½v#H0FÖ)GM +`­â7šýiqÛ)ÊuƒÞ®F®ZÀ#«eqhÚj¨6ïYÚ¯ìl4´ä4Ñ9ö¢Ž40lMm‡œˆAP![V˜…ÑzíÿÆkü€Bã†DûP½ ‚2'Ê…lX‹áÿñ§LÜð Léu©G#©5)Óºà£hvÄ{(! $mH¤ÈCè p¥°„¢ÔQyÊ«V«#¡t¥.] ¬¢7wÏ¡\"Ô`Ä\ýnÊ« Yu…†õjPj…ÝDÌ:‹8¯Cf…C“ÖN®ÒåšqAE QI ¡‹ ´â™­°£(@jƒ*C²# KN'³F­%V‚µ¯ i[Nb꣤U¤VŒ”Áˆ;8WAš÷¹Œ2K‹ `sÐ=”5bìÿã:.ÿNb RADpŒó¬›¸%Ù* tŠ6S3ÿe5v%Ø6V’ß§Â^¾8•2ôÁ„ZŒ‹ÙWÕŠ0S;æfx¹µ˜{ 4§oˆ9Á"GT0·Ê]ÏQQØ»GÛŠŸÍõªœ'ZÂd€JTÚsÛ¶– X;#Pµóf¯d)dgµ@Áv”É»œLιÀ‰H+¾7@*¥‹…š¬M)8œ®ˆQº+fVðÕ_Çÿ¯ò¯õÈÖÆiÝ>þ¦ÇÄü?à~4雟ú‹¿ÿGƒ¯ò ŒíR¶¬" \pHŸ*—¥e/‡üÆ3sòIµ;t2™¸^B³–©MQV¢¬û° ÊZ ±¨ÌŒ¬Z3Þpz¢ÔÀÄp4Õˤ¦6/EÞ?Ll^‹¼<~˜Ø½xxý1±z.ðñúcbô]áãôÆÅè»ÃÇé‹Ñw‡Ó¢ï¦6/EÞ?Ll^‹¼<~˜Ø½xxý1±z.ðñúcbô]áãôÆÅè»ÃÇé‹Ñw‡Ó¢ï¦6/EÞ?Ll^‹¼<~˜Ø½xxý1±z.ðñúcbô]áãôÆÅè»ÃÇé‹Ñw‡Ó¢ï¦6/EÞ?Ll^‹¼<~˜Ø½xxý1±z.ðñúcbô]áãôÆÅè»ÃÇé‹Ñw‡Ó¢ï¦6/EÞ?Ll^‹¼<~˜Ø½xxý1±z.ðñúcbô]áãôÆÅè»ÃÇé‹Ñw‡Ó¢ï¦6/EÞ?Ll^‹¼<~˜Ø½xxý1±z.ðñúcbô]áãôÆÅè»ÃÇé‹Ñw‡Ó¢ï¦6/EÞ?Ll^‹¼<~˜Ø½xxý1±z.ðñúcbô]áãôÆÅè»ÃÇé‹Ñw‡Ó¢ï¦6/EÞ?Ll^‹¼<~˜Ø½xxý1±z.ðñúcbô]áãôÆÅè»ÃÇé‹Ñw‡Ó¢ï¦6/EÞ?Ll^‹¼<~˜Ø½xxý1±z.ðñúcbô]áãôÆÅè»ÃÇé‹Ñw‡Ó¢ï¦6/EÞ?Ll^‹¼<~˜Ø½xxý1±z.ðñúcbô]áãôÆÅè»ÃÇé‹Ñw‡Ó¢ï¦6/EÞ?Ll^‹¼<~˜Ø½xxý1M}Ó“áÑwþŒŸœÑE]míE&fºe1FˆilTkÍn)5bÑ^áZ,QÝMèU„[;@‰Í‚+ 4© Z,!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡ÙƒbYá¯õáÿñ§LÜü•ëèùøA×a2Õ¬Œ†±IhÛkœoìqKº@CæP@N‹Ð§˜Ò¦< û‚E) [YA… Z 2åÿËt]ÿ£d³Ž†/AHQÍ”h¿ñ  ˆkè¶1ic‹2­ÁEAü¶V ¦ ˜­‡J¬kÃ( ƹ Š{›ÿÀQI‰r 7{›ÿnŽÒÅZèÄ×úðÿøÓ¦näZ㠔ʮšÁàt]ÿàà‹.¤k _c±|ÔÏ$Ž\À² ‚ baÄ8‹[U­bï#TŸ° ¥Jp8v@Ø~œˆçò°´.­­ ªâ_´ÿ‰¨ˆÌ­3Ô]2ª€ªs%ð $D`IU ÕXV@@D°D)6@leE½÷€Ó²”ìYšuf½¢&y?ÀW°öHi4i›­¿‚GsÕE¸ -PYnHq%âÄ0‰´ý“ÌÁKÈTL.µ‡¹ eZ7ºf‹á±eŽŽLˆ˜Gü-¨ø:fçþD"dP¶çü‹¿÷àÙ{­ËЫÕ+Fz6ÙG_ž+ÎY2pï0ßBö°I×Gù’=a#%¨®Vµ»¢¯RW½:+凨å[Ü`ÚÂGU_²C€Ñ°sÃÒÌèÑ>˜üDº¬-§ýއš Jc)*ñ§É4ü /M³ƒm»y ÞAGL/sœ›ø3J2j%šó•Ýêé^¾:/Þ3*peM‡àÅ`)…ð:ëáJ ¶»%†Ò挴ÖF§C™V•áÛ–Ó:ªfÒFÅšŠX4.5Jݨ‚lGÂè!°n¢ÆøÙµ~;Û\fWc©hœ²åŒÝ·yí®©u`n”±ˆ[Âõ•žøPÅØŸ¹Ý…E#¯Ã˜»-¯4UMÑ5¢+U+X <‹eK•eÖŠë 1rà¼FÏä§DÑÿȾQ•,zû#ñÂÇPÉØ<ã¶,p©v碵n’‹­ð@’ªª±!N)jƒfŒŽ#Jõ¥@êÔPwÙš´œWÓY¥Y SrµcVÑðAL€,·„ŠÊªì¬R8zj™á+u_Õ• Ca€x£I!ªÒ8°Þ&Jtö+5oè×úðÿøÓ¦näWžÆïŸð:.ÿÝ‚µg§@èYrN_+m‘gŒÑ—¸H{^—¼è²›¢[qQ¹¦ª(Î7·Cé°Ñ²•h[µi€8ÅÚuGéØ/†R Û„,ôŠD'`ï³É†ˆØž7ck/P u½i1o)]ÈQKÍ$‹i›£g%†ª•W$£iôÈ Èð×…J®Á‚l‘‹°4M¦*à–Õ¸TMö´‡ Vž†‘2©âTŒ/d1Š”¶ßÒUë/†Ñ°ÉÝ–9¾%ºYy4•€Æ×[ÏS-ê²Ò±¦ÉbyU˜kÑ(¦7Äa.j9áL:´”>÷ャÇÄ ‹ Џ…‚¸Ú!Y±â5î<ç° ú|ê€íxl3cFÛáàoƒ¨(¾aéӴ–Tâêñlvü¤Î æ°o4m‰Q«%¦Ìêãâ©]ïÕmú1#ù ±¥©C¶*‚ã L0Š0*ÅL4­¸»^OšÐR6ÚªörîÄ>lL)h7(îØSø »5Ü>Dõœ0%èÁ€Ææ8]«z„•P  U`ÒE“[˜¬ÊñnKÍ ” CB×gˆD>n8ʼ:.Õ>§‚›­²þk¼`ÞG¯È!ü{ÔžQ^Æ7“Õ­Ë­ì]ðq8¥’(€Ø·³Ž-ic=Ѻë*ÂÙ‚1g–#mš@E,”ºœH¦Ø’ !ç|¢1,€–¤ä¦LfÖ·¾åç«ÙL^ƒ.h¡ÁKMiQ³…1l˜XÔúM6'˜Ã—ÛUÖܱZ2kt“­èQÂÓZiúþÆ-8ü|e fλÕXÊωpቶµºdr*‘üµþ |?à~4雟ù‰‘hwNÏØH9|G”R~ï¤}'§Eßû°APKÆ,ˆï8x\ý²2Bœ:-¸ÛŸÅìiëH^ûGí.PŠîwAr––ʲ7@Z30»ÌÙtXªf­ßV¡rÐM¡}%yMˆ˜ Í•fSk—%]ªl‹e:d|6zËèêÃ7`+S (+4ª%Ãbm5cTÍ:" «v[,ùø =®†‚ µ]ÅmÏ“Oê¿+†ÚDŽ-Øõœ šyiï †ÔÈ¥ê­C jR^:$Ì2ÐgOXù%Žâ_䄺´¶1pñ 6©¬ã«‹ .Šø¤)È—_¿,å¸ä‘#vÖ£šãº¥Eá­Zrö9¶—eª…¨œâêìÕÓí25½UÛ>+Ø ¥Ò[ó,®Ø5†da¶Ì…¥Ñébf@/±@’³·RÀ#)@/€ 6ÛÕ%'À35£e¡ak[àÆ'}1 Ø‹ÙQé‰W!ó(¾¾>¸‹t» -½ÚÎHgù qðéÀÆR-Áú‰[披hÇ•ôšÍ²r \oH—zŠºEî6ðŽU«uÒk{‡Xå=)Wý”˜¸áyÄ2›ÝŒ(M{Lt³UŽÔlµh(FoÔ¢ÛÈ]¢£êÖÚßUƘ4JH#³.aM¥¢ ¹/"§.p^h-[Sªí BÀ‚Ýk+7zˆ:E˜¾eÓËNnÛ@ÆS5°@ß.Ë' #µü·8m¹û´”ƈ´ ¦]mºˆñ“,Ö~p•{Ç_êÃþãN™¹ÿ‘ù¹ÁÿQ.Ï2‚Ü|Œ±]¢HP±§L3-Õé/Sš @BJà}qãÑwþì•Ù¯›þž üë7,àjõw¿‚5ÊáJr:iƒq@¦ µ\ø— ðYi^Ü ñ3kE*Ù¡ê¡ãºá² #Z„Ú€ÒˆIpbȶKÐwDaLÖ£/*Jpˆ= *ŒÙ·-³b͉zÞôõXfÞ9'D,XÜ¢ÉÁFykãd£.ÁAìxð5i¹§žMÌÀ ’uæÇ¯¡ÄÅfËwHC2Y£hmhôgˆ62ÄÜ㔊6Ú» Úb[¡õ8Š6)ù£çÔ”ÒdY£Fâ^‰÷cWe`Ð.Í©DáE]¶: Ÿ„¡ì¼òïUr¬A,cfxže¢PZi‡x6¾ðœëY¸½¢Z[y]ÓcÄtv \ (,5øapz³ÉDÈ‚dŽ“T e©t¹ÙâWAAh…U#SIyLApjüo†!g‰HP ‡0²5Ö.‚ݪô7êX£–nÑÛaxX~ Æ9–”ÎÃÔ†/Àœyåµo¨rYO‰ò²ôhÐ^ú]Ñâ—ñÚÒ’6óò¶ jÑÆéV§¯?Ñ94F¹ ÛÇÄBj ÜU:§ƒB|¡wÇÇ_êÃþãN™¹ÿ‘Ý‘!´G?© º ³¥bÇ:ê»à"/mâëuÜÝ|çÇ¢ïý¸!¤hV6$Ú™mx }¿Â ½.Gìò”U©tW¤;†¯0m3ÐQôˆ­ªÐ:#‹VÝçð×ü"<„Tƒt¹ Û\!¥¢ÙÜ4z¶øëý@øÀüiÓ7?ò&ûUm”ùŽú,¦ö´Ë°5<èaàšj8fVéWÆÌ÷ñ6±/ŽEßûpK2á¹-„4;ß"òF¨Ë´Tâ]ùxëý@øÀüiÓ7?ðCy”µ{,® ~âdÎ]º¿‚+éqý'‘IÉZ4 ÆÓ…™Îd¹ÜAF¾&ñ´û¨[Ç¢ïý¸*§ªÜGQÀh‡þH™xØØ¾ž:ÿP>ð?tÍÏãDÁ¦õ‡KÛ[³¾­«Q [Bˆtm¥Ú%Ÿ¿Xë«ZÆh4(Ò¿[뵫•v¹ùýà\+6¶on†xFJªº»afÁHšq…áÚ³÷WýTl“ J•r¶ÉÏäìryNiŸiÆÒÉ…ä·{k”Íô¸¼z.ÿÛƒ°×7™ ¶“%ÿä÷%KÒ“þ-Yå¢ï¦fØ€½—=îU‘T­*¦<Øw±À ´'ÖˆWèËbô]áãôÆÅè»ÃÇé hÆ)qMšÞØŠ ¦¾éÉðè»ÿF P£fܱK±­‘R6‘`¬kÍn)5bÑ^áZ,QÝMèU„[;@‰Í‚+ 4© Z,!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃì… ÕU‡‡Ù ª«²+UVd(Vª¬<>ÈP­UXx}¡Zª°ðû!BµUaáöB…jªÃÃìÕ `Ú>ð6%žÿP>ð?tÍÏÉ  5{s „›" î4²µºqU†(|Ê ÑzóTÇ?p@(¥!Kk(0¡Á+AF\³pä6Áç“ÓÃáëo°ãE3:î`ÈÛ|L()gEã{°€Q“kM¾Y—€•á9;Èø¤@šºÖ¸èË)Ü cÕvwÓ:¨`Îù—6߃'µÌf v‰üKØG†X7Ñ-{Ù8'†ˆÕ­§‚“%ØZísÅ+•¦hâ6ô—e“Ò¡6s|-€ߌSÃ{|¹Žöš*«ÀA剼˜Ýv÷^ºì–ÒŸžÛÞ ¦™³R“0è^3}ÃÀì,VÔ¯MvÅ‚„ÕU™3„ñðßjk‘»õ‡¼CáFš¬”}ã{©) clE;0\@q´ß¸Gà|ÑLº@ú\eiÈXÌÛ25|>òå^­Xò4r㋈ mFŽ:ÃH¨¿ kßï ^hÕ,Zœ¤6qTÞŸ÷Ã5ƒpA¦„É’–§§b$^X-£–Œµà U ÕcFìfÅÌðt\ RjWWÒToû|f{²˜mÈÕÙçq•]®Â‰óh½Ã3_ÛÃÁ>ܦì6úÞ5 «xaÛ´ e@×hŒqúM1÷¯¼{Õjhjá¾a‘Tp*nJñ¼câb6¡­7úá,™ª·wW ÛŸ‹¿ô`‹éŽëvÉžÓ~qn²è¦€c€MÒÆîLpÁêÆ ¹nçÒná6Ç2=EË<ª´ºOÏh諲ÅAMç7À­”–ªf­¢àtTA@ÊDÝ©äÊ›jShh ã`‹#aˆ/2…ÌÝAKèfeÛ&òÖûGó[• M :›.¬kkä²åB›Gâkº?Æíhot<* `D,}§š±wví{fÕá‹§½•öSgCÑš%ö·å,wwžmcaX•©H­)."Ç+›´µ/vd4oáL¯ÎŸðgÚRBÏa'˜‡Ò&[ jµØÁ{*ëT»ý–R‰p±Å£áU…&ò¡aÙZ^W³É NHú±`'¹Å¨}@Ù¬Lp—¿Hk AÐÛºÍó•OÔ!g´ŒS†+c·="%ÀÑW@”†35PòY0•e¬qÙ¿5/ΊýeÐ+Õèú%’/(Òßâø”ìBŸÒc(¤jøŽÈ#ÕTËJÞ®/8‚¬®Ä¡å)$aË#•lfÒr³`£Ìz¤»/(: Vè긃Î:¼´wb|érÁÈʲÿì%@N#«ai¯ ìÙ¨…¹)ñ¥ö€1#fË]¡)“M7JBÖŸ"Fýæ Ý1’.¹hžÈIMÄØõ³*¡LW„ J‹SJ4­‘îFÝT`Ð6[FÍ.AêÀ$±$Éî+4Ù÷€£E–ÇþZÖV&õ¦6çÊkþ”ÖÆ§Ò ‡Ö;Bk[Æq «á!Œq`õó‰£mµñh}`9±hšÓ?(™_¨=rÕnF!¦nHlËwƒ–vÑCÞ Öû~þƒSð¥ÁAk°Éã¯õáÿñ§LÜýŽ:ÝÌô<¿å˱Bè ˜ÒVxCÍîRŠzµE•?Ö‘œ-G\ÝÂ+ ¢[­U9:ßœ w]Þùx' Zÿ¹Ö`Ê›ó…6››aP t«®V8„*­¿ÔÄèñv;‚ï3 ›¬nÞrÛ•izµ8œMO(\tV°^/†Ë§î7*]VG¸4 sq¬®È¸©óºU›_K xû¢ÖÕP…ªYÚ®†Âê,ž¡ÊÇ cØ^”hÕ§®šh˰ãç‚Kt6J”À× ‰šÞOK¥Í[š„EôTº[6·yÉ=%M»Éß áx¸mÒ/ šÖèKù@Ò¹rJuÿ–˜Q©MÓÄ(ñ# e&›K­Ä¬d4û4p tÝ> Ëà €&×piS† (BöÓöG§Wæ÷äÅ…ÀÊ…°ضµ7¦*ö“0èÑK§Ú¼™è+ˆ-©Æì¶ß*q…Ðm!ôõƬùk\ ž”‹d€˜cX )c@ÕïF0VP“r¿#eè6A“ß/x‹MeÔ#„´!P€Üvq¼¶–[1á,­©6€ùèò“S¡Ã Ó*K´Òƒ´fº>†ðî©à˜|øJÏÿ(Z™ ,¼kLu&¯†¯Ô¯D~TÕè+3Ä´IbÁ-pí2Õ¦$¥_’Sâ¼,.ÆÕmkÖ5å*aje/Ú‰Gåàq¦2J½½_xe…@P¿+-¶ѱ,‰ÝcaÀ=tÒk6­È²Ù’Þë×4C o¶OâïÿÐàÆéžÿP>ð?tÍÏð*­µ·Çv0²þH®¶ ¼@~|dÔŠ°xÑíûÉ1 Û8Ï.Úÿó‰¢SëAßÒ·wŸ±q뮇?Ô£/Öàü\ÚÚ ù¿Á·”k8_µÞzÃÿÉUw©CÙxUlðh °7Næ(*‚êÕÑè?€¶êÖ¿!™¶AÓþ?ª°hÙújJäµf0þFý4c´ ­ïE+0Ï¥?2Z®ÀdMAÓö´÷ÁP SNŽï 3CDïœO?-φù% ã--WÃ_êÃþãN™¹þ¥!}…-À–ó‚½8á ct¢TÖÐ}^žs¦¨nƒGÏàÔ›vðÁ¯tDÔðV¥ìc³TißhøOߦ5 €®   ”Oªo?Ý7joÝñò‚ð«µ1mÁˆ›&íV—ŒÒÇŸEßû°Cå³,Vwm1Äð_“…[CWzk³]9ÝUzõ†X¨[ëAz:x¤f5ðp~ž-–Vσqunu¶Ñ:Ço‡ !tôà¢å§åÞËkk›c a~h€šZƱv5ƒ×l9cΛ$®ªBßqÃnê\oèÛx–xÍ‚í4wm1®Mäx®Òò~‘¨e7™Ÿc/ ÑU™×S&ñrZ»ÎÓb¥ýÿE8gݶü Zà½fªJ,©B;ÂÓÊ#‹!¹/¿àU~ŽÅÛ®´áK§ ”‚Ñ%Õ¡·.„jžßA”Á[ö5+¬Ò!g„ú¾]0-heÊKÓá¬N¶lñfz¸‡àe7kt{{x× V€W) °,M:6ĪjÚz+Ö6—ÃeÂ,9Ä»¾{íø,(ºìuoMŽ5ûÁþr]÷5Fp]^Ïïã˜L^5 ­¾-`PM­é.cµ(in*½åðx; ¾E™[ÉŸë9æ<¢ˆ[tWüë਄jì±ñe¯õáÿñ§LÜý̃0 CR}µPû$eÞ4«(5¼SájµÌ¥kN”Ûf¶×‹Ãã Xh3Šaض!gÂÖ¤Ð*+}¾ ÙfOÔ–„X-Upubà ÀWÀUdÆm,oâ4„_DZv_0ÅØ1UÕe²îñ^‰­UÆŒÊ<B¨Y/9¾¤°6+Ë?*<×ÂÔZÐÚþ—M ­}‰¤€M5\–4DÙ 6ε#¹ O…Û¡†FiÚE'~[EWäÓÁÄÚŠ%]„*3í,tþꦶ©Üø"†©@Û ‘ Ê-†Dÿ¶x‚c(PªÆw'ºm>ÌëáQ¾—4?Eßûp\ ®Â4ýµè}<•0€hŽÙaÚ4 O–O?Ám¬é¸DMÞh–ìczx ÒËpïÝHº"—ºFÞT@„±Š?±¬a§3½£´jÃZp÷«?²¬çKrq†TLÓ`Áö2Ô øÂ'5š•æÄÒk;ÎߺTj|и†°y‰ùNx.2GeèxŽ&ÉrîRZmã^K,X¬ºŠsŽI ZûJ”¶À¡à°Ýqé Ëv#ØÈØ`EŽ9=!¢Ä Ô_\‡·‹¸¦é×G_(aMµ«kÝ¢CÐÀ/·œBº)6"lGâ`]0½)¶°7¾¡ráÊ¥ì.TøYÛbr¦œ2AîÖEPŸÁnL<ÆøÐš˜vØ×Ä1”ý±Ž÷³8ÅÌ*¦˜,œolß,ÅtuVOG§‹G«}(ö> 'åÁG´K‘^Þ /ÃϤoÙ¹~Y€½_TúŽuzFêÜû”²vLv'=QØlJêŠuÓXõÛÆq_À]ú²AÁò•>ýøK‹}ºõâýDlYZ ¨8è?wZ izkâl‚Ù¢½À*‡Z–4:‰»iÞ%…Øam›Poß…­¾y*‘}vºTÇ`‡™_“V6µºm”Zø–žqèSF'ÜCºÊ—xò âD8QZÿP>ð?tÍÏÙb¾þ\€.ëy»-»OtQ·”äUäìZÑÚ\%•ÏmÄ´õ†_ÚK+h%Äh èê1£|Ây´ ˱4Û}ºT¹w®­ª¶lN FÝZZy‚Ç”6³ªƒLÜR¯œÉ#BµÃ…î!^$Ta7¸§„ZÞh\”×·1ÏY¤Ud.͌ו¦»­¯8µË±‡…i0faO²6[w<˜ì ®-¢ø¾5½MåÞ¬P‹Ññ_QqŒàm„(ÕÃFj·ÈÓ¨²÷9É+Z”°uMM™M`Úi‹'9ÕÚ1ýhÆ'T dcO&ÌA„Š+tVZçÉ6 ÖAVøÂ+6SƒÄ²ÛD–®ð`Dñ ?‚¸ œ2ťʖJËjœèùLm¡…9+층à}4™j’¢ÒÌK2ÒÓV>Ó‚UœMGy‹ƒµ[ .¹m—%{Ùa 9§FšpÏù–Õµ\•‰o¥úfÍLS»2c‚’mpcfìHjË“•š²îCf’Ê&¡‹ZÅ+fšã,vJol/&Ú—D+R7ýB –dˆÛQ]aå‡ Q›nð Z&*±QòX[í[=ð5-"iûà<ãm„TòªlÖæF¥k»BË˜Šº×]êœ.g¬»¢ppÔ´—Â_&áÊ÷k)s+ÚCÿs±¤ÕK–•ƒ©½ª/¤|Ñó.ìeK¶õŽDè T(Ú®".â(ªø¹zÊ™ðZ…­vQ›e»n-߬Ú2Mì5„•ðUÑ¥N”ËÁP5¶%«n6AA”ÈdN”kzDVñ/…Ù2·p‚4Šê4« *±QC[”j^Ò­¾­Ò¥T†Z(X †Ûé*ì1¢Û” ¹ ²npžn‚Ã${— n_ %Ò2€Ö­á·®ÙB*QGüJÙDEßœgþZç9›ˆê¯œ1\(œ"rÆ¢g¹ƒ•–cùÅì½tË‘­Û ÁµÙê=âÃZ3b5±¿d]‘Ã4«"[¿;ââÓz°N"†ô[©’8ÒÓ-;Ÿ‡Eßûphv„·%ò$´q.ÛÊ8Ú±©2æŽ;á@ö½c¼j>¢ŸT±Þó‰mY¬˜áJx‹¢øPÕùûM÷AîÃ1è¿ ô‚M†åŠİŒÞú´W)§…û¬«Cíu¶U*)EúŠúTcGã¹óG!»;b–]F’%ö%W¦ÆaèsâUhpoó÷@2‘«ÀÜlš¦„ÒúÑë¦òC ò«sd¹O<®žð\f©ÞôË ½£b²¯814©‹y‹«Ö%hXüfp÷1tðnCe¸2òkx{ ÈßÅ(Æ[< dC7îêÍ `¾O刅IÝ£]7Ý­Þ/z'ü–QÔ×§MÆ´®˜­iBpò˜T ô9>;+óh½ôÀ6°ºì–Ñ*íöa¾°¤Öކÿ†÷ù@É¿¨$Ó†à(”Œê¡!°ï! èRmÂYÿcÈðYu“˿鹎òUÏá¡f›t–ãÊléË4”úÍà°7b‰…flWæ>µ `}VÐØ’Ö×å|‡¸z׸êjT¤8^|èvÌÿ +óÿ¬Å1·r}¼094n©(q 8ƒvÚ­Æú¶rƒï".±ˆ« ߦÙVåi«·ê*ÆÉY–3©í_âJ¬@f«×Òaè\Ô;5hZ?&mêÛ^`\D¾Q)-£ \àȽ ö›ñ,±Îƒ(î ,áäx¡’œ=c X––â´€Ùêø2×úðÿøÓ¦n~Ì…8±±§hçð­at²ªïËškŚŢ€.aQ}[b^Âe!læçož a.\ж puÑ%:}P~&X+k(-Vjàmf\MÙsšw46²ø8‰bC\¼Š®Ì®]üo*}«iùèçt vÝÁÍPÞ+µrø\ì?bDöf'.õÚ3{3‘D\¨p<ŒA핹M=mÌC$ìÖ½0Àê[2_¬N@¨>³Œƒ‘ÿÙw ¥”Ý –åCƒüÿˆ@c¦n›2O?£\ïðA>¬¤i°‚taØ Ž„Þ[è+ ”±6Úž!üh Ô`Magz€Aà"Ë‚h}ï7g)®LÛ“£w’u ~‘èì5Œ¾)"죥71®Ž¡®î";÷„)ÁO´[ k•V>XÛD.äëš'Fµä“CÇNJ]l¼µ¹Ÿ ¼ Ýó{DkŸˆYDCt¦æŸf9@×z”ry¦ùI4W¯4xà‡P 7j(¡»è¥xá^iNÈ*|N ,Ùtûxü7¨ƒÿa„,Îý>¨-’V—È¡ê,-£mðÂnžq½ßÒ|mJû< “Q.ÇÊ#¯+XHõwÌûB…èPmÙ¬;â €hÆì… ìV„1E©O9!>”·fçêc¶‰s·[ªñ Àë†@ aù‰U4ä)ÅÕ"*Ð €Á9@@ Ut –&ßÖé«/èm¬ÍÙ¶ì^ðž‹p|Yký@øÀüiÓ7?EEZгìPBÀ/)h*Æ£00±hÌXyÁê‹SÀÓTK.’™D6Q¤ž“¥õN—Õ:_Té}S¥õN—Õ:_Té}S¥õN—Õ:_Té}S¥õN—Õ:_Té}S¥õN—Õ:_Té}S¥õN—Õ:_Té}S¥õAúìl aäWKê/ªt¾©Òú§Kê/ªt¾©Òú§Kê‹ÜêÙ:_Té}S¥õN—Õ:_Té}S¥õN—Õ:_Té}S¥õN—Õ:_Té}S¥õ@¼ô² È“¥õN—Õ:_Té}S¥õN—Õ:_Té}S¥õN—Õ:_Té}S¥õN—Õ:_Té}S¥õN—Õ:_Té}S¥õN—Õ:_Té}S¥õN—Õ:_Té}S¥õN—Õ7Nï"¯ÏËâïý+DÞ¤¬±5bèךÜR:jÅ¢½Â´X£º›Ð«¶v›V@iRM¨@7®(8sXññ̳É+õ[Þ,­2ÔÕÄ‚PO0ÌäRÞ[ËtÃøgŽ9«3GðÏs ÌË1.†‚B’ zÉ( Àñq̳0Ü̳m#†h_Ä{@¢‘©‡4`³o¹Y~&1v‰oLiG72zæ´w5«3GÃASu;ˆZ›|­ÄW¤-×`)F ª®ˆV½÷U…FÊbÊE­‰Žéš™³*á‡Çrè÷WŒT”-¹Ðk1z°,úG†e¶R4†Wœ19fa™YëÌêÀ¶ª«”IÛ «$ ÉBì‰[(ذ2º6Æ:„±2àJl¤%+H`  Þ ²Xs Ñ*+7½Ce¤(®—«,³5féÕ¶ ‹·ch8É· Ño‚hj2æx)G9³T2\ Ш'¯0üD²)¥!ÐQS`ì¤G‡×¶P2nÕoñqÇË3 ̾8ç•"ó!mÅ-Æí9[/¯ª´i¸§ƒ–!¹Ð˜È­¢ ^¶½ûŒÚ3UäˆDu<-¨ø:fçè\ãcŠ]Ò2‚t^…<Æ•1àOÜ )HRÚÊ (pJÐQ—/‹îh1‹Upµ‹Ð%bU•Ú5 dß ü * W* ¬ªøÙÌiks[?Ƀçj¦‹#¶²‚ µ¶BôÉì®*Ó•°2Î!ënheÄÓLþ/½X8=)³•¾Ë¥ÄÒØ&׳…ÕhSŒ‹zM¿‚´”ÜZ oXcYPZ©D½0À-ÀJXe¨ÎšMe>UJpÙ‡ð§rB¼—.Ë\a‰G–5µ,Ká0’¶ X «¤ˆÅ Þ›§6V¿†n"µØËFZÒk'd QJ°áÜʯœÆ–±‡5²k)ô‚¨ªS†Ì?ƒ x€…ª…£`ÅIµ’êÄߪ'^…-Z×–/Hü°):~ìC ”µ°¸éÉWTJ«wMBý ð.0rÆ3 ¥M?…;’ä¹vXrã J<±­©b_ å¶ÌMú¥:Ò|SOð 2UÑÞMGwC©*“RĸmUEí£¦3 ¥M?…ަ°%—XŽk 1ûa– ¤ª×¬]‡]Ìæ…ÄjX–~› %¥IMjo”ØT·Ð0’Êw†jkÕQ ŽŠRļ˜ããÑwþœòN{—ˆ­¡ˆP¡†¾‹c‘f8³*ÜQToÀ+e`Àº`¹ŠØtªÆ·ãPŽ˜À)mD,ºÒÈS HØ6ˆ‰± ÛT÷d,8 ;£PôÂF¥‰y1ãQƒ‰€°¤nË7À«@3 ,ňŽä`*AqKP[k1˜ß(4©“|j/R X TP½-"“”–¢›ÝL?çb¦¶TѶ ™P†é¤G7á^á ’ÂƒÔ$KÓ ¤Ì¬åËTS›¬DĪ ‚ÙBí´i¤|T ´¬YkÌ×¢SV!t, aJ ú äµuL”aEÔ$AÒÇwà¬?ÊÜÖCrJ¬~t7AŠ­²ãã"ð[´*ö’ÜúU£M"4‰øXž˜€4–•%5©¾U¬Â.ða<¢¼ˆ¥¥±Àì` ,M¾á¦U˜³jÖÀs“|¢fêöÐa8ŸÊ~•kR–i¾‘°:#áF8E´«@ÚÃs5è†ol ïRJšÅ¥­®<šÑb;FW”© 7ʈî|ª¬µ{4½el›2 €f*N2­` šo H1+ÑÒ¼sAŒZ«€ ¬;"Ó¥ú.a»3­Ð°.&ǵ¤ºÕ¬Òõü&ª˜,1-B­ìß †Bº´-ãIJàd&jS&Mä)Éã¯õáÿñ§LÜý×=øö ª)[nª2I”î˜YN*.Æ´ašª˜``õáu$QÍ$ÖÎEÁø£VÙ¡ÕUY½ ̈ÉÄÒÉTÖóZð?tÍÏýEßÿ£Á×úðÿøÓ¦nèz.ÿý¿Ô‡üÆ3sÿCÑwÿèðuþ |?à~4雟²Ã7¸ êeÇpCëÙ©JnÃJŒ0wf5|¡6£ÖKr®ézî²1šÈRš-¢²SwØ)²‰fFX9Á(3J+hÑZÔtÉKŒ”œ_` Z3¸$6«#Ó2Ö)ÊÊÄ6;O ¶T à6TÑFÅ¡ íÖ¯„b™ØÒÑ©RíSrØáG´ÊÞ²ã1qx¢Â! 4 ÅÆ=•j>Á£W‹×lÅðÒµ£m@´îC•_lJA&Í4Ø™æE@gNØh¸­ *Å3 ºgK3oUé-5^Q2 J`Ð ‹·3#^@X@dC&ˆß†•ÅEÝOA>¸+î[‰Ööް€ÏÆ2ì;™Uã†èl8Ñz,+­=ÃF²Ö-;HÔìë3,np¸Üqyᬸ8}­HÞ©G./:ßþűCTlΙƮ`ªm@-tZª]ÌC™%e†•a­s‚ÓnU¥a°n­ÚÅ m`Å7 A–‚öŽ+WD;Ñ5r³üwEßûpMÌ ±5N–6¥ÛÎkl¸;FÇlÏVÌU´¥OHS`0%›½¶sæ©Uc ‘£z17ÚËymMäjg"„"ð]|%€–´ŠÈh„º¦”²Ö(¢R¶‡UBª;¬Ö­Íª†¶Ú—•³ó&UúEÒ,TKrh°r5 ë­–jm§,Z… ½ãr¨`h‹…EÜ‚1g*gð{¨ÛP"Ó¬%f(…Ó)bÂÙ…)fHæˆJîrPRûÝ~Ðr±J7—wÃÎ4"nbÚ‚† ø‚Å]‘uQÞEÙˆè88½ DnIDí`ÐSn1ºe>J´åÆùka-¡°£*×dHÕ˜}ÝÖŠÓ„0Gk*–rµm·.rËì® ZŒ(Ú3)qƒyâ.œÓc´cÁlW' aNƒ`”J‘š1Fë·lb#ìçðŸ:Ç Y¡¾DQ€ ZÆÛòÓ¤ÃU Uj²ý«`ÖÄ›üÜBÐu çWW ¦ÁƺºÀE,ƒ,…i¯¹(ÐÛ&‡\­í”©ÖM•ÛC¶ü%#H8‚ž êV%!bBÊ 5ÇS ’VI5:[š1jía…`z™¨hrÚ\×?©;EµÌ ~D!ýX´6deïØJ0Bب¢¡,hW LvJÅM>C­   UÞøjmðîØ –5mU°ÃJÍ€ - ·°¨*Í»ªÓV%o­Zí»½êå7Ë8˜ È0¨*Í»ªÓVðR©¶ÄLˆÒ&J€£T)!®*ÍQ¸‰ Œ$¬…ÅðÐÁD¶­Ýt«UFËm;„ RŠ€b mÛ¯E…Vc”ˆYû ÎÚÈ_KMH %…Yºê È·E¼­ÂëüråË—.|?àGµ:fçþ‡¢ïƒ_ú$N2‰÷œ,á=ç ï8XÈÞ gð6æø¡–”l0˜ÿЬX±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹Dh4kãÚ嘞×ïuôbÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X±bÅ‹,X­€ï"ѱUÕ\¯ê[þRá½¶èXÐôhÑ£F4hÑ£F4hÑ£F4hÑ£F4hÑ£F4hÑ£F4hÑ£F4hÑ£F4hÑ£F4hÑ£F4hÑ£F4hÑ£F$H‘£F4hÑ£F4hÑ£F4hÑ£F4hÑ£Fó”hÑ£F4hÑ£F4hÑ£F4hÑ£F4hÑ£F4hÑ£F4hÑ£F4hÑ¢™±lµ$du ÔL#äþ¯ ?€T›jtÍÏö#ºîüƒ‰eyM85“YrÖk¢`Á)z%‹Pñ>)à>4雟ìMŸ ¢ÖTUU¶óPÀ€<~4雞 èZÕ¡•Ђ4 õV³V‹²3{(dT¦À«Q#vÑ…  Õ¥dšÛò ÕÖ­QÕUŒÅGòl‚Ûpƒ¨e*QÀ¥2•0Ä h«7s¸Û Ê霴¤Þ˜!’l@j&mOÈóe¥FíuVʵ…·ó9-¡9.†éÓagÄ*Ì ­µþI|‚îRúü—Ð?ä¾±ÿ%ß öŽÅ®Õ*à~4雟ìMˆ•Ý+ºWÁ_ÀüiÓ7?Øšÿ‹Æ3sý‰¯ø°|iÓ7òœ !UT0i«ØËË"%t:a?‰"¸‹k]V.y¥OµZš+iYÔgëôV†åjᨈ¡d¹m¬g“± ZZÕ´AD u0qA6¡’¨fŠ€ÀýÞàÐÖî.êËÞO8ññ•^µ)•üT' ØkM;A¦öÛáR9mµd´¶‹<'Wˆg(Ä©•KxÎL ›š_t³0Éj8Ã¦Ì j$MÞ"R (UNV],E©oÍUB²YX€”À&x¥Tï\b0Ø:_)µ°•’œ³ÇqÆ¢%,@ ²§ ` ²ßý6œ'IècJѼÄPÔ· mš›4–û£8ŠÂˆBð …$(» ð‘èYÁ(Ó@[`$±óJLS?°ީašÍD5Ct &j/Öô…r¥F…0»wU.ýÐuB“JŽÇ…Â’]…øHô,à”i -°Xù¥¦)Οàß„cÎ>ZXÛ¼yª—ÚCDhæ:” ÆRâŒpDDÄ]BÚo‰Ò4(]Ì)Q2ëkÁ/XŒ2ûþ,ýe.Lî‚åbâ­-üŠÃúf玿âÁñ§LÜÿÚ3»³]ÞiË8ÚEš÷æòjôˆ…®ÐRÒ”b’ª[´S [RÛ«±kPC»@ÀQE*¿Ã(öBŠšfibÖ¢¶ËÇ,á×1BêS„ÝÚeW˜$òe(&–íÈÔ¶êìZÇîÐ0QJ¯ðÂQ¥­”Ù²Ìk¤~Ñ/‚JZ«yƒ@ M  Aº"I’–ÑaÒ/ZP«ìš <}¼ÄX¥¾aPïH990ÂèºÐýîîïöÜ%µw·L~興ˆˆˆˆá“*º*üuÿ:fçƒ÷jBGs™ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎcX–&óÃ_ñ`øÓ¦n±5ÿ:fçŠV:°x¯6â9*yBxÀÎÈ:£J¨ ´ƒ/|ÕÃTo)Bõ1AÔ(Uš{¸BÌÑ`ãÅ=Up²š-Ðå§\BJ©*e­¾Aú„ (5@¢ºµÐ`4kX(n:7MhÐ4i­¢#âݸͶ:Ae]ÁÌ’m.©´Ì^­‹¶&ðËÝD[`˜šºj·§a‚¢#þ-ÑèŠ)È KÑÔT–LQÓ¤hh Y¢W‘ªbâÀr:$Ö7à_]³ÅüX2®"H#Atì?5Ë—.\¹/N]D]½»±ûÐ @ @\š-:ÿ‹Æ3sÅ5Oâj1¬m‹ar'ÈÀš¥& âvvªõÀ7x]ITÙ65.ûÁЪѴT‰A·S+ÐÞrUÒ˜VåÅý“…<í¯Tkì5y°Ö…=ÈKpHÉ&*— MBS–xî!ÔD¥1¨–Tá¬6[ÿ¦#ž¶?v«B ²é*§ÁæùBPÝlÞ–Í LeP Îr¥hi¢­¿ü¥¼[Ue6 .ÓÌ4Â1Á¡ Ý—Þ (®‹QÕîË(ÂX^Ÿ‘©ÒUÖ¦÷mŽ»Ë°ãd#œåJÐÓE[~ùKx¶(ªÊl3@]¦˜hÿ‚T•)† Ä %Š­Œ‚¤šˆLÜ„ SàkSÏ?JFn£nªØ¨[ia€ULÓh¬¨¶Þ#Tvâ‡yÃMkK\Ë]4v¨¿ò+雞:ÿ‹Æ3sô‡ìÀ9BŠ–¥&kËÿV–S¤E,l³OòK›/üjhUÖjDÂ;`QF²û¢HXSZ'âC–q¥•Zµµü×.\¹rà ¥;pATvoÏï@ @µ9uPV|uÿ:fçƒ÷jBGs™ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎtÇ9ÓçLs1ÎcX–&óÃ_ñ`øÓ¦n±5ÿ:fç‹ûhÕÀ¢A{Ehî5ôèV%õepÕ—–£2ïAmЦ÷Õáa4qôCZ;€aLcRâEÓeRÚ¸êL¶Ô Áٜ— BZ¶·ŒvòN…Ò\励¢½V+˜]¤v,1ͶªÍbYéžê•&&ctí\)£ZÚ²²·CìÒå¢ÀçÞ‘Æ1:‘X* Óo#™[!n)}QÜ0üKH³\ìq‰0p¾›6Sïgþ¤Ê#š €i«¦‰£X(5ÿs$›Kªm3«bíç‡wPp¾£.΃ÅÚ `šˆÿ‰x/üõÖ)°…ƒWDc¢(§ %/GQP÷ÆjPµjhØ1Á¥ªˆ”äÂk5øÅA,ñ «ˆ’Ð]{Áråß`E¤Ú*«oøH @ @ pzh´xëþ,tÍϬrƒH§J˜‰,ûs€„»€phÃ+Œ‡`)_ SxrU¹¶ÖºÂîÚX#œhË eáÝE­ Ð‹®M(«#Cåœ ŽhY#hª‰¨v¤WŒB슥ߪ¡ðŒ)4ԬǼÂtc¹ÕB¢P «z¢¶JÐëÃ]8(ìlLÖÀP PÅ€ÁÕFˆÛ‘bÚa¦Í4Œõò0ô(œ×9b¯µHR/`^À¨åËÎËg™Uw¿ú»ÍÂ̆êÍfh1ŠŠŒ@ A@ÒEç7ç9R´4ÑV߃þRÞ-Š*²›ŒÐiƒæ?á‹(®‹QÕîË(V(!3[B),eí:ê_Ó63œg0Žs•+CMmø?å-âØ¢«)°Ív˜>a£þÐ7R´ÚÉp¸ŠWAdD±U±@t“72P(ap‚AF b l¥†U3M¢²¢ÛxQÛŠç 95­-s-tÑÚ¢ÿÈ­3sÇ_ñ`øÓ¦n‚á¨3“h·WÇÅ,Mû¥]¼ZáМ è)(4Ùfù¥ƒM–iþ54 *ë5â²û¢HXSZ'âC–q¥•Zµµü.]õZMªîö„ @ @S—UgÇ_ñ`øÓ¦nx1TÚ=ú2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&þe2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™2dÉ“&L™1‰`,¢>£“Ã_ñ`øÓ¦n±5ÿ:fç‹ûhÕÀ¢A{Ehî5ôèV%õepÕ—–£2ïAmЦ÷Õáa4qôCZ;€bˆýRâEÓl¥µr¥àµÕ°М|¾ÍÄDj°X,Âí7À‘vŠl¨åkXø¦,¬Úàsÿ§@mÔeG/›/˜ðžE ˆ¸gY«~ÑEïç4CÃB…Ý6#§,áÄA„ ·Öizÿ‰CvøàZa¦Å «áA ¬r(]d°%Ó@X»j¶ÃÃB…Ý6#§,áÄA„ ·Öizÿ†ë*×@Åóv. »E¨j­L÷Òúav ",>ú}êRô¦‘¡£^À(@«»ØþÄηÒÙ†rcÇo'8­ «½ð`3žX-V€'_ë®uþ¹×úç_ë®uþ¹×úç_ë®uþ¹×úç_ë®uþ¹×úç_ë®uþ¸—XJ«P¾:ÿ‹Æ3sÆë ÒiÒ¦"K>Üà!.à0ÊÄ£'aØFÊWÂÔÞ•nmµ®°Óú‘gk¨R…2 be×p¥€†H} ih›YÅ]â$C¤á`º¨³âÎAyH.ò €CÿN›ë Uc*¸ bذ•jÎuÑÅXšS!Ö«€vË1zó5X–ñhŒU„+l,Ù7@°íá“›ì·j&mÕ™ô-*EÈ¢9;¯n²­JÖ²Ì^ƒ|ÍV%„4雞.@  …šÀ¡™ —h,¶løgl§HUw°×T_…/ª³,PÕU[Ñÿ®;ÂÐÔmXô„Åà€Ì…³f“ ©S¶Y‹Ðp/™ªÄ°‡‹Db¨”![`Ùfɺ‡h8ÿ$Ÿ“ œTÀàÔ*u¢î»nµ‡l³ à_3U‰aˆÅQ(B¶Á²Í“t Ðqþ ©­v\ Gå®jÀ±MKE9BÀjÈ- ²äH»K5(ÁEÏrIA\aÀ,ùEA¯¡,Ô²/HHZahY$€)kº]ñðé›ßãtÍÏŃãN™¹þ¦Ó7ao0]§Ñüo M«nÙ×ûç_ï¾uþù×ûç_ï¾uþù×ûç_ï¾uþù×ûç_ï¾uþù×ûç_ï¾uþù×ûáE@t:ÿ‹Æ3sÀØQ¢â]ÿÐøñãÇ ' + results['hits']['hits'].map { |r| r['_id'] }.join(', ') client.index index: 'my-messages', type: 'doc', id: 123, body: { message: "Foo Bar Baz" } client.indices.refresh index: 'my-messages' results = client.search index: 'my-alerts', body: { query: { percolate: { field: 'query', index: 'my-messages', type: 'doc', id: 123 } } } puts "Which alerts match the document [my-messages/doc/123]?".ansi(:bold), '> ' + results['hits']['hits'].map { |r| r['_id'] }.join(', ') elastic-elasticsearch-ruby-c38be0c/examples/rabbitmq/000077500000000000000000000000001462737751600230575ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/examples/rabbitmq/Gemfile000066400000000000000000000015431462737751600243550ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. source 'https://rubygems.org' gem 'elasticsearch' gem 'bunny' gem 'multi_json' gem 'oj' elastic-elasticsearch-ruby-c38be0c/examples/rabbitmq/consumer-publisher.rb000066400000000000000000000035321462737751600272350ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # Example of listening to a RabbitMQ queue and indexing the payload # # Usage: # # $ bundle install # $ bundle exec ruby consume-publish.rb # require 'multi_json' require 'oj' require 'elasticsearch' require 'bunny' connection = Bunny.new connection.start channel = connection.create_channel queue = channel.queue 'examples.elasticsearch', auto_delete: true exchange = channel.default_exchange elasticsearch = Elasticsearch::Client.new log:true elasticsearch.indices.delete index: 'rabbit' rescue nil queue.subscribe do |delivery_info, metadata, payload| hash = MultiJson.load(payload) elasticsearch.index index: 'rabbit', type: 'event', id: hash.delete(:id), body: hash end (1..10).each do |i| exchange.publish MultiJson.dump({id: i, title: "Test #{i}"}), routing_key: queue.name end sleep 1.0 puts "Enter some words to index (use Ctrl+C to exit):" [:INT, :TERM].each do |signal| trap(signal) { puts "\nExiting..."; exit } end while input = gets exchange.publish MultiJson.dump({title: input.chomp}), routing_key: queue.name unless input =~ /^\s*$/ end connection.close elastic-elasticsearch-ruby-c38be0c/profile/000077500000000000000000000000001462737751600211005ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/profile/benchmarking.rb000066400000000000000000000050061462737751600240560ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'benchmark' require 'yaml' require 'erb' require 'json' require_relative 'benchmarking/measurable' require_relative 'benchmarking/simple' require_relative 'benchmarking/complex' require_relative 'benchmarking/results' module Elasticsearch # Module with all functionality for running client benchmark tests. # # @since 7.0.0 module Benchmarking extend self # The default number of test repetitions. # # @return [ Integer ] The number of test repetitions. # # @since 7.0.0 DEFAULT_TEST_REPETITIONS = 10.freeze # The number of default warmup repetitions of the test to do before # recording times. # # @return [ Integer ] The default number of warmup repetitions. # # @since 7.0.0 DEFAULT_WARMUP_REPETITIONS = 1.freeze # The default definition of a test run. # # @return [ Hash ] The default test run definition. # # @since 7.0.0 DEFAULT_RUN = { 'description' => 'Default run', 'repetitions' => { 'measured' => DEFAULT_TEST_REPETITIONS, 'warmup' => DEFAULT_WARMUP_REPETITIONS }, 'name' => 'default', 'metrics' => ['mean'] }.freeze # Parse a file of run definitions and yield each run. # # @params [ String ] file The YAML file containing the matrix of test run definitions. # # @yieldparam [ Hash ] A test run definition. # # @since 7.0.0 def each_run(file) if file file = File.new(file) matrix = YAML.load(ERB.new(file.read).result) file.close matrix.each_with_index do |run, i| DEFAULT_RUN.merge(run) yield(run, i) end else yield(DEFAULT_RUN) end end end end elastic-elasticsearch-ruby-c38be0c/profile/benchmarking/000077500000000000000000000000001462737751600235305ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/profile/benchmarking/benchmarking_tasks.rake000066400000000000000000000157321462737751600302410ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require_relative "../benchmarking" namespace :benchmark do namespace :simple do desc "Run the \'ping\' benchmark test" task :ping do require 'elasticsearch' Elasticsearch::Benchmarking.each_run(ENV['matrix']) do |run| task = Elasticsearch::Benchmarking::Simple.new(run) puts "#{'*' * 5} PING #{'*' * 5} \n" puts "#{task.run(:ping)}" end end desc "Run the \'create index\' benchmark test" task :create_index do require 'elasticsearch' Elasticsearch::Benchmarking.each_run(ENV['matrix']) do |run| task = Elasticsearch::Benchmarking::Simple.new(run) puts "#{'*' * 5} CREATE INDEX #{'*' * 5} \n" puts "#{task.run(:create_index)}" end end desc "Run the \'index smal document\' benchmark test with patron adapter" task :index_document_small_patron do require 'elasticsearch' Elasticsearch::Benchmarking.each_run(ENV['matrix']) do |run| begin require 'patron' rescue LoadError puts "Patron not loaded, skipping test" else task = Elasticsearch::Benchmarking::Simple.new(run, :patron) puts "#{'*' * 5} INDEX SMALL DOCUMENT, PATRON #{'*' * 5} \n" puts "#{task.run(:index_document_small)}" end end end desc "Run the \'index small document\' benchmark test" task :index_document_small do require 'elasticsearch' Elasticsearch::Benchmarking.each_run(ENV['matrix']) do |run| task = Elasticsearch::Benchmarking::Simple.new(run) puts "#{'*' * 5} INDEX SMALL DOCUMENT #{'*' * 5} \n" puts "#{task.run(:index_document_small)}" end end desc "Run the \'index large document\' benchmark test" task :index_document_large do require 'elasticsearch' Elasticsearch::Benchmarking.each_run(ENV['matrix']) do |run| task = Elasticsearch::Benchmarking::Simple.new(run) puts "#{'*' * 5} INDEX LARGE DOCUMENT #{'*' * 5} \n" puts "#{task.run(:index_document_large)}" end end desc "Run the \'get small document\' benchmark test" task :get_document_small do require 'elasticsearch' Elasticsearch::Benchmarking.each_run(ENV['matrix']) do |run| task = Elasticsearch::Benchmarking::Simple.new(run) puts "#{'*' * 5} GET SMALL DOCUMENT #{'*' * 5} \n" puts "#{task.run(:get_document_small)}" end end desc "Run the \'get large document\' benchmark test" task :get_document_large do require 'elasticsearch' Elasticsearch::Benchmarking.each_run(ENV['matrix']) do |run| task = Elasticsearch::Benchmarking::Simple.new(run) puts "#{'*' * 5} GET LARGE DOCUMENT #{'*' * 5} \n" puts "#{task.run(:get_document_large)}" end end desc "Run the \'search small document\' benchmark test" task :search_document_small do require 'elasticsearch' Elasticsearch::Benchmarking.each_run(ENV['matrix']) do |run| task = Elasticsearch::Benchmarking::Simple.new(run) puts "#{'*' * 5} SEARCH SMALL DOCUMENT #{'*' * 5} \n" puts "#{task.run(:search_document_small)}" end end desc "Run the \'search small document\' benchmark test" task :search_document_large do require 'elasticsearch' Elasticsearch::Benchmarking.each_run(ENV['matrix']) do |run| task = Elasticsearch::Benchmarking::Simple.new(run) puts "#{'*' * 5} SEARCH LARGE DOCUMENT #{'*' * 5} \n" puts "#{task.run(:search_document_large)}" end end desc "Run the \'update document\' benchmark test" task :update_document do require 'elasticsearch' Elasticsearch::Benchmarking.each_run(ENV['matrix']) do |run| task = Elasticsearch::Benchmarking::Simple.new(run) puts "#{'*' * 5} UPDATE DOCUMENT #{'*' * 5} \n" puts "#{task.run(:update_document)}" end end desc "Run all simple benchmark tests" task :all, [:matrix] do |t, args| %w[ benchmark:simple:ping benchmark:simple:create_index benchmark:simple:index_document_small benchmark:simple:index_document_large benchmark:simple:get_document_small benchmark:simple:get_document_large benchmark:simple:search_document_small benchmark:simple:search_document_large benchmark:simple:update_document ].each do |task_name| begin require 'elasticsearch' Rake::Task[task_name].invoke(*args) rescue => ex puts "Error in task [#{task_name}], #{ex.inspect}" next end end end # namespace :noop do # # desc "Run the \'search small document\' benchmark test with the noop plugin" # task :search_document_small do # puts "SIMPLE REQUEST BENCHMARK:: SEARCH SMALL DOCUMENT WITH NOOP PLUGIN" # Elasticsearch::Benchmarking::Simple.new.run(:search_document_small, noop: true) # end # end end namespace :complex do task :download_dataset do current_path = File.expand_path(File.dirname(__FILE__)) data_path = [current_path, 'data'].join('/') unless File.exist?([data_path, 'stackoverflow.json'].join('/')) `gsutil cp gs://clients-team-files/stackoverflow.json "#{data_path}/"` end end desc "Run the \'index documents\' benchmark test" task :index_documents => :download_dataset do require 'elasticsearch' Elasticsearch::Benchmarking.each_run(ENV['matrix']) do |run| task = Elasticsearch::Benchmarking::Complex.new(run) puts "#{'*' * 5} INDEX DOCUMENTS #{'*' * 5} \n" puts "#{task.run(:index_documents)}" end end desc "Run the \'search documents\' benchmark test" task :search_documents do require 'elasticsearch' Elasticsearch::Benchmarking.each_run(ENV['matrix']) do |run| task = Elasticsearch::Benchmarking::Complex.new(run) puts "#{'*' * 5} SEARCH DOCUMENTS #{'*' * 5} \n" puts "#{task.run(:search_documents)}" end end desc "Run all complex benchmark test" task :all do %w[ benchmark:complex:index_documents ].each do |task_name| require 'elasticsearch' Rake::Task[task_name].invoke end end end end elastic-elasticsearch-ruby-c38be0c/profile/benchmarking/complex.rb000066400000000000000000000072601462737751600255310ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Benchmarking # Class encapsulating all settings and functionality for running benchmarking # tests making complex requests. # # @since 7.0.0 class Complex include Measurable # Test sending a bulk request to index a large dataset. # # @example Test sending a bulk index request. # task.create_documents(opts) # # @param [ Hash ] opts The test run options. # # @results [ Hash ] The results documents. # # @since 7.0.0 def index_documents(opts = {}) results = [] slices = dataset_slices warmup_repetitions.times do slices.each do |slice| client.bulk(body: slice) end end duration = with_cleanup do Benchmark.realtime do results = measured_repetitions.times.collect do Benchmark.realtime do slices.each do |slice| client.bulk(body: slice) end end end end end options = { duration: duration, operation: __method__, dataset: File.basename(DATASET_FILE), dataset_size: ObjectSpace.memsize_of(dataset), dataset_n_documents: dataset.length } index_results!(results, options) end # Test sending a request a search request. # # @example Test sending a search request. # Benchmarking::Complex.search_documents(10) # # @param [ Integer ] repetitions The number of test repetitions. # # @since 7.0.0 def search_documents(opts = {}) results = [] duration = with_cleanup do slices = dataset_slices sample_slice = slices.collect do |slice| client.bulk(body: slice) slice end[rand(slices.size)-1] sample_document = sample_slice[rand(sample_slice.size)-1][:index][:data] search_criteria = sample_document.find { |k,v| v.is_a?(String) } request = { body: { query: { match: { search_criteria[0] => search_criteria[1] } } } } warmup_repetitions.times do client.search(request) end Benchmark.realtime do results = measured_repetitions.times.collect do Benchmark.realtime do client.search(request) end end end end options = { duration: duration, operation: __method__, dataset: File.basename(DATASET_FILE), dataset_size: ObjectSpace.memsize_of(dataset), dataset_n_documents: dataset.length } index_results!(results, options) end # def mixed_bulk_small(repetitions) # # end # # def mixed_bulk_large(repetitions) # # end end end end elastic-elasticsearch-ruby-c38be0c/profile/benchmarking/data/000077500000000000000000000000001462737751600244415ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/profile/benchmarking/data/largedoc.json000066400000000000000000000031241462737751600271140ustar00rootroot00000000000000{"text":"@wildfits you're not getting one.....","in_reply_to_status_id":22773233453,"retweet_count":null,"contributors":null,"created_at":"Thu Sep 02 19:38:18 +0000 2010","geo":null,"source":"web","coordinates":null,"in_reply_to_screen_name":"wildfits","truncated":false,"entities":{"user_mentions":[{"indices":[0,9],"screen_name":"wildfits","name":"Mairin Goetzinger","id":41832464}],"urls":[],"hashtags":[]},"retweeted":false,"place":null,"user":{"friends_count":179,"profile_sidebar_fill_color":"7a7a7a","location":"Minneapols, MN/Brookings SD","verified":false,"follow_request_sent":null,"favourites_count":0,"profile_sidebar_border_color":"a3a3a3","profile_image_url":"http://a1.twimg.com/profile_images/1110614677/Screen_shot_2010-08-25_at_10.12.40_AM_normal.png","geo_enabled":false,"created_at":"Sun Aug 17 00:23:13 +0000 2008","description":"graphic designer + foodie, with a love of music, movies, running, design, + the outdoors!","time_zone":"Mountain Time (US & Canada)","url":"http://jessiefarris.com/","screen_name":"jessiekf","notifications":null,"profile_background_color":"303030","listed_count":1,"lang":"en","profile_background_image_url":"http://a3.twimg.com/profile_background_images/133733613/Picture_4.png","statuses_count":1010,"following":null,"profile_text_color":"d9a980","protected":false,"show_all_inline_media":false,"profile_background_tile":true,"name":"Jessie Farris","contributors_enabled":false,"profile_link_color":"363636","followers_count":218,"id":15878015,"profile_use_background_image":true,"utc_offset":-25200},"favorited":false,"in_reply_to_user_id":41832464,"id":22824602300}elastic-elasticsearch-ruby-c38be0c/profile/benchmarking/data/smalldoc.json000066400000000000000000000000431462737751600271270ustar00rootroot00000000000000{"id": 49434,"cuisine": "mexican"} elastic-elasticsearch-ruby-c38be0c/profile/benchmarking/measurable.rb000066400000000000000000000206511462737751600262010ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Benchmarking # Helper functions used by benchmarking tasks module Measurable attr_reader :options attr_reader :client_adapter # The default number of measured repetitions. # # @since 7.0.0 DEFAULT_MEASURED_REPETITIONS = 5 # The default number of warmup repetitions. # # @since 7.0.0 DEFAULT_WARMUP_REPETITIONS = 1 # The default number of action iterations. # # @since 7.0.0 DEFAULT_ACTION_ITERATIONS = 1 # Create a benchmark test. # # @example Create a test. # Benchmarking::Simple.new({ 'repetitions' => { 'warmup' => 1 }}, :patron) # # @param [ Hash ] options The options for the benchmarking task. # @param [ Symbol ] adapter The adapter the client should be configured with. # # @since 7.0.0 def initialize(options = {}, adapter = ::Faraday.default_adapter) @options = options @client_adapter = adapter end # Run a benchmark test. # # @example Run a test. # task.run(:ping) # # @param [ Symbol ] type The name of the test to run. # # @return [ Hash ] The test results document. # # @since 7.0.0 def run(type, opts={}) send(type, opts) end # Get the nodes info on the elasticsearch server used for the benchmarking tests. # # @example Get the nodes info. # task.nodes_info # # @return [ Hash ] The nodes info. # # @since 7.0.0 def nodes_info client.nodes.info(os: true) if client.ping end # Get the version of the elasticsearch server used for the benchmarking tests. # # @example Get the server version. # task.server_version # # @return [ String ] The server version. # # @since 7.0.0 def server_version client.perform_request('GET', '/').body['version']['number'] if client.ping end # Get the description of the benchmarking task. # # @example Get the task description. # task.description # # @return [ String ] The task description. # # @since 7.0.0 def description @options['description'] end # Get number of measured repetitions. # # @example Get the number of measured repetitions. # task.measured_repetitions # # @return [ Numeric ] The number of measured repetitions. # # @since 7.0.0 def measured_repetitions @options['repetitions']['measured'] || DEFAULT_MEASURED_REPETITIONS end # Get number of warmup repetitions. # # @example Get the number of warmup repetitions. # task.warmup_repetitions # # @return [ Numeric ] The number of warmup repetitions. # # @since 7.0.0 def warmup_repetitions @options['repetitions']['warmup'] || DEFAULT_WARMUP_REPETITIONS end # Get number of iterations of the action. # # @example Get the number of iterations of the action. # task.action_iterations # # @return [ Numeric ] The number of action iterations. # # @since 7.0.0 def action_iterations @options['repetitions']['action_iterations'] || DEFAULT_ACTION_ITERATIONS end private attr_reader :adapter # The elasticsearch url to use for the tests. # # @return [ String ] The Elasticsearch URL to use in tests. # # @since 7.0.0 ELASTICSEARCH_URL = ENV['ELASTICSEARCH_URL'] || "localhost:#{(ENV['TEST_CLUSTER_PORT'] || 9200)}" # The username for the results cluster. # # @return [ String ] The username for the results cluster. # # @since 7.0.0 ES_RESULT_CLUSTER_USERNAME = ENV['ES_RESULT_CLUSTER_USERNAME'].freeze # The password for the results cluster. # # @return [ String ] The password for the results cluster. # # @since 7.0.0 ES_RESULT_CLUSTER_PASSWORD = ENV['ES_RESULT_CLUSTER_PASSWORD'].freeze # The results cluster url. # # @return [ String ] The results cluster url. # # @since 7.0.0 ES_RESULT_CLUSTER_URL = ENV['ES_RESULT_CLUSTER_URL'].freeze # The current path. # # @return [ String ] The current path. # # @since 7.0.0 CURRENT_PATH = File.expand_path(File.dirname(__FILE__)).freeze # The path to data files used in Benchmarking tests. # # @return [ String ] Path to Benchmarking test files. # # @since 7.0.0 DATA_PATH = [CURRENT_PATH, 'data'].join('/').freeze # The file path and name for the small document. # # @return [ String ] The file path and name for the small document. # # @since 7.0.0 SMALL_DOCUMENT = [DATA_PATH, 'smalldoc.json'].join('/').freeze # The file path and name for the large document. # # @return [ String ] The file path and name for the large document. # # @since 7.0.0 LARGE_DOCUMENT = [DATA_PATH, 'largedoc.json'].join('/').freeze # The file path and name for the dataset. # # @return [ String ] The file path and name for the dataset. # # @since 7.0.0 DATASET_FILE = [DATA_PATH, 'stackoverflow.json'].join('/').freeze # The name of the index to use for benchmark tests. # # @return [ String ] The index to use for benchmarking tests. # # @since 7.0.0 INDEX = 'benchmarking-ruby'.freeze def load_json_from_file(file_name) File.open(file_name, "r") do |f| f.each_line.collect do |line| JSON.parse(line) end end end def with_cleanup client.indices.delete(index: 'benchmarking-*') client.indices.create(index: INDEX) unless client.indices.exists?(index: INDEX) results = yield client.indices.delete(index: 'benchmarking-*') results end def client @client ||= Elasticsearch::Transport::Client.new(host: ELASTICSEARCH_URL, adapter: adapter, tracer: nil) end def dataset_slices(slice_size=10000) @dataset_slices ||= begin dataset.collect do |d| { index: { _index: INDEX, _type: '_doc', data: d } } end.each_slice(slice_size) end end def dataset @dataset ||= load_json_from_file(DATASET_FILE) end def small_document @small_document ||= load_json_from_file(SMALL_DOCUMENT)[0] end def large_document @large_document ||= load_json_from_file(LARGE_DOCUMENT)[0] end def noop_plugin? false end def index_results!(results, options = {}) res = Results.new(self, results, options) if result_cluster_client.ping res.index!(result_cluster_client) puts "#{'*' * 5} Indexed results #{'*' * 5} \n" else puts "#{'*' * 5} Results cluster not available, did not index results #{'*' * 5} \n" end res.results_doc rescue => ex puts "Could not index results, due to #{ex.class}.\n" puts "Error: #{ex}.\n" puts "#{ex.backtrace[0..15]}" end def result_cluster_client @result_cluster_client ||= begin opts = { host: ES_RESULT_CLUSTER_URL } opts.merge!(user: ES_RESULT_CLUSTER_USERNAME) if ES_RESULT_CLUSTER_USERNAME opts.merge!(password: ES_RESULT_CLUSTER_PASSWORD) if ES_RESULT_CLUSTER_PASSWORD Elasticsearch::Client.new(opts) end end end end end elastic-elasticsearch-ruby-c38be0c/profile/benchmarking/results.rb000066400000000000000000000146061462737751600255650ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. module Elasticsearch module Benchmarking # Class encapsulating formatting and indexing the results from a benchmarking run. # # @since 7.0.0 class Results attr_reader :raw_results # String constant for unit of time elapsed. # # @since 7.0.0 MILLISECONDS = 'milliseconds'.freeze # Create a Results object. # # @example Create a results object. # Benchmarking::Results.new(task, [...], options) # # @param [ Elasticsearch::Benchmarking ] task The task that executed the benchmarking run. # @param [ Array ] results An array of the results. # @param [ Hash ] options The options. # # @since 7.0.0 def initialize(task, results, options = {}) @task = task @raw_results = results.map { |r| r * 1000 } @options = options end # Index the results document into elasticsearch. # # @example Index the results. # results.index!(client) # # @param [ Elasticsearch::Client ] client The client to use to index the results. # # @return [ Hash ] The results document. # # @since 7.0.0 def index!(client) create_index!(client) client.index(index: index_name, body: results_doc) results_doc end # The document recording the benchmarking run results, to index into the results cluster. # # @example Get the results document. # results.results_doc # # @return [ Hash ] The results document. # # @since 7.0.0 def results_doc @results_doc ||= begin { '@timestamp' => Time.now.iso8601, event: event_doc, agent: agent_doc, server: server_doc } end end private attr_reader :options DEFAULT_INDEX_NAME = 'benchmarking_results'.freeze DEFAULT_METRICS = ['median'].freeze CLIENT_NAME = 'elasticsearch-ruby-client'.freeze COMPLEXITIES = { Elasticsearch::Benchmarking::Simple => :simple, Elasticsearch::Benchmarking::Complex => :complex }.freeze def action_iterations options[:action_iterations] end def index_name options[:index_name] || DEFAULT_INDEX_NAME end def create_index!(client) unless client.indices.exists?(index: index_name) client.indices.create(index: index_name) end end def event_doc { description: description, category: category, action: action, duration: duration, statistics: statistics_doc, repetitions: repetitions_doc }.tap do |doc| doc.merge!(dataset: dataset, dataset_details: dataset_details) if dataset end end def description @task.description end def category COMPLEXITIES[@task.class] end def action @options[:operation] end def dataset @options[:dataset] end def dataset_details { size: @options[:dataset_size], num_documents: @options[:dataset_n_documents] } end def duration @options[:duration] * 1000 end def statistics_doc { unit: MILLISECONDS, mean: mean, median: median, max: max, min: min, standard_deviation: standard_deviation } end def median raw_results.sort![raw_results.size / 2 - 1] end def mean raw_results.inject { |sum, el| sum + el }.to_f / raw_results.size end def max raw_results.max end def min raw_results.min end def standard_deviation return 0 if raw_results.size < 2 Math.sqrt(sample_variance) end def sample_variance m = mean sum = raw_results.inject(0) { |sum, i| sum +(i-m)**2 } sum/(raw_results.length - 1).to_f end def repetitions_doc { warmup: @task.warmup_repetitions, measured: @task.measured_repetitions, iterations: action_iterations } end def agent_doc { version: Elasticsearch::VERSION, name: CLIENT_NAME, git: git_doc, language: language_doc, os: client_os_doc, adapter: adapter } end def adapter @task.client_adapter end def git_doc sha = `git rev-parse HEAD` branch = /\* (.+)/.match(`git branch`)[1] commit_message = `git log -1 --pretty=%B` repository = 'elasticsearch-ruby' { branch: branch, sha: sha.chomp, commit_message: commit_message.gsub(/\n/, ''), repository: repository.chomp } end def language_doc version = [ RUBY_VERSION, RUBY_PLATFORM, RbConfig::CONFIG['build'] ].compact.join(', ') { runtime_version: version } end def client_os_doc { platform: platform, type: type, architecture: architecture } end def type (RbConfig::CONFIG && RbConfig::CONFIG['host_os']) ? RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase : 'unknown' end def architecture RbConfig::CONFIG['target_cpu'] end def platform [ @platform, RUBY_VERSION, RUBY_PLATFORM, RbConfig::CONFIG['build'] ].compact.join(', ') end def server_doc { version: @task.server_version, nodes_info: @task.nodes_info } end end end end elastic-elasticsearch-ruby-c38be0c/profile/benchmarking/simple.rb000066400000000000000000000311621462737751600253510ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'objspace' module Elasticsearch module Benchmarking # Class encapsulating all settings and functionality for running benchmarking # tasks making simple requests. # # @since 7.0.0 class Simple include Measurable # Test sending a ping request. # # @example Test sending a ping request. # task.ping(opts) # # @param [ Hash ] opts The test run options. # # @results [ Hash ] The results document. # # @since 7.0.0 def ping(opts = {}) results = [] action_iterations = 1_000 warmup_repetitions.times { client.ping } duration = Benchmark.realtime do results = measured_repetitions.times.collect do Benchmark.realtime do action_iterations.times do client.ping end end end end options = { duration: duration, operation: __method__, action_iterations: action_iterations } index_results!(results, options) end # Test sending a create_index request. # # @example Test sending a create index request. # task.create_index(opts) # # @param [ Hash ] opts The test run options. # # @results [ Hash ] The results document. # # @since 7.0.0 def create_index(opts = {}) results = [] action_iterations = 10 warmup_repetitions.times do client.indices.create(index: "benchmarking-#{Time.now.to_f}") end duration = with_cleanup do Benchmark.realtime do results = measured_repetitions.times.collect do |i| index_names = action_iterations.times.collect { |j| (measured_repetitions*i) + j } Benchmark.realtime do action_iterations.times do |j| client.indices.create(index: "benchmarking-#{index_names[j]}") end end end end end options = { duration: duration, operation: __method__, action_iterations: action_iterations } index_results!(results, options) end # Test sending an index document request for a small document. # # @example Test sending an index document request. # task.index_document_small # # @param [ Hash ] opts The test run options. # # @results [ Hash ] The results document. # # @since 7.0.0 def index_document_small(opts={}) results = [] document = small_document action_iterations = 10 warmup_repetitions.times do client.create(index: INDEX, body: document) end duration = with_cleanup do Benchmark.realtime do results = measured_repetitions.times.collect do Benchmark.realtime do action_iterations.times do client.create(index: INDEX, body: document) end end end end end options = { duration: duration, operation: __method__, dataset: 'small_document', dataset_size: ObjectSpace.memsize_of(small_document), dataset_n_documents: 1, action_iterations: action_iterations } index_results!(results, options) end # Test sending an index document request for a large document. # # @example Test sending an index document request. # task.index_document_large # # @param [ Hash ] opts The test run options. # # @results [ Hash ] The results document. # # @since 7.0.0 def index_document_large(opts={}) results = [] document = large_document action_iterations = 1_000 warmup_repetitions.times do client.create(index: INDEX, body: document) end duration = with_cleanup do Benchmark.realtime do results = measured_repetitions.times.collect do Benchmark.realtime do action_iterations.times do client.create(index: INDEX, body: document) end end end end end options = { duration: duration, operation: __method__, dataset: 'large_document', dataset_size: ObjectSpace.memsize_of(large_document), dataset_n_documents: 1, action_iterations: action_iterations } index_results!(results, options) end # Test sending a get document request for a small document. # # @example Test sending a get document request. # Benchmarking::Simple.get_document_small # # @param [ Hash ] opts The test run options. # # @results [ Hash ] The results document. # # @since 7.0.0 def get_document_small(opts={}) results = [] action_iterations = 1_000 duration = with_cleanup do id = client.create(index: INDEX, body: small_document)['_id'] warmup_repetitions.times do client.get(index: INDEX, id: id) end Benchmark.realtime do results = measured_repetitions.times.collect do Benchmark.realtime do action_iterations.times do client.get(index: INDEX, id: id) end end end end end options = { duration: duration, operation: __method__, dataset: 'small_document', dataset_size: ObjectSpace.memsize_of(small_document), dataset_n_documents: 1, action_iterations: action_iterations } index_results!(results, options) end # Test sending a get document request for a large document. # # @example Test sending a get document request. # Benchmarking::Simple.get_document_large # # @param [ Hash ] opts The test run options. # # @results [ Hash ] The results document. # # @since 7.0.0 def get_document_large(opts={}) duration = 0 results = [] action_iterations = 1_000 duration = with_cleanup do id = client.create(index: INDEX, body: large_document)['_id'] warmup_repetitions.times do client.get(index: INDEX, id: id) end Benchmark.realtime do results = measured_repetitions.times.collect do Benchmark.realtime do action_iterations.times do client.get(index: INDEX, id: id) end end end end end options = { duration: duration, operation: __method__, dataset: 'large_document', dataset_size: ObjectSpace.memsize_of(large_document), dataset_n_documents: 1, action_iterations: action_iterations } index_results!(results, options) end # Test sending a search request and retrieving a small document. # # @example Test sending a search request for a small document. # task.search_document_small # # @param [ Hash ] opts The test run options. # # @results [ Hash ] The results documents. # # @since 7.0.0 def search_document_small(opts={}) duration = 0 results = [] action_iterations = 1_000 duration = with_cleanup do client.create(index: INDEX, body: small_document) search_criteria = { match: { cuisine: 'mexican' } } request = { body: { query: search_criteria } } if noop_plugin? Elasticsearch::API.const_set('UNDERSCORE_SEARCH', '_noop_search') else request.merge!(index: INDEX) end warmup_repetitions.times do client.search(request) end Benchmark.realtime do results = measured_repetitions.times.collect do Benchmark.realtime do action_iterations.times do client.search(request) end end end end end options = { duration: duration, operation: __method__, dataset: 'small_document', dataset_size: ObjectSpace.memsize_of(small_document), dataset_n_documents: 1, action_iterations: action_iterations } index_results!(results, options) end # Test sending a search request and retrieving a large document. # # @example Test sending a search request for a large document. # task.search_document_large # # @param [ Hash ] opts The test run options. # # @results [ Hash ] The results documents. # # @since 7.0.0 def search_document_large(opts={}) results = [] action_iterations = 1_000 duration = with_cleanup do client.create(index: INDEX, body: large_document) search_criteria = { match: { 'user.lang': 'en' } } request = { body: { query: search_criteria } } if noop_plugin? Elasticsearch::API.const_set('UNDERSCORE_SEARCH', '_noop_search') else request.merge!(index: INDEX) end warmup_repetitions.times do client.search(request) end Benchmark.realtime do results = measured_repetitions.times.collect do Benchmark.realtime do action_iterations.times do client.search(request) end end end end end options = { duration: duration, operation: __method__, dataset: 'large_document', dataset_size: ObjectSpace.memsize_of(large_document), dataset_n_documents: 1, action_iterations: action_iterations } index_results!(results, options) end # Test sending a update request for a small document. # # @example Test sending an update request for a small document. # Benchmarking::Simple.update_document # # @param [ Hash ] opts The test run options. # # @results [ Hash ] The results documents. # # @since 7.0.0 def update_document(opts={}) results = [] action_iterations = 1_000 duration = with_cleanup do document = small_document id = client.create(index: INDEX, body: document)['_id'] field = document.find { |k,v| k != 'id' && v.is_a?(String) }.first warmup_repetitions.times do |i| client.update(index: INDEX, id: id, body: { doc: { field: "#{document[field]}-#{i}" } }) end Benchmark.realtime do results = measured_repetitions.times.collect do Benchmark.realtime do action_iterations.times do |i| client.update(index: INDEX, id: id, body: { doc: { field: "#{document[field]}-#{i}" } }) end end end end end options = { duration: duration, operation: __method__, dataset: 'small_document', dataset_size: ObjectSpace.memsize_of(small_document), dataset_n_documents: 1, action_iterations: action_iterations } index_results!(results, options) end end end end elastic-elasticsearch-ruby-c38be0c/profile/matrix.yml000066400000000000000000000003651462737751600231330ustar00rootroot00000000000000- description: Basic benchmark, 5 repetitions repetitions: warmup: 1 measured: 5 metrics: - mean - median - max - min - description: Ten Repetitions repetitions: warmup: 5 measured: 10 metrics: - meanelastic-elasticsearch-ruby-c38be0c/rake_tasks/000077500000000000000000000000001462737751600215675ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/rake_tasks/docker_tasks.rake000066400000000000000000000031211462737751600251040ustar00rootroot00000000000000# frozen_string_literal: true # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'mkmf' namespace :docker do desc <<~DOC Start Elasticsearch in a Docker container. Default: rake docker:start[version] E.g.: rake docker:start[7.x-SNAPSHOT] To start the container with X-Pack, pass it in as a parameter: rake docker:start[7.x-SNAPSHOT,xpack] DOC task :start, [:version, :suite] do |_, params| abort 'Docker not installed' unless find_executable 'docker' abort 'You need to set a version, e.g. rake docker:start[7.x-SNAPSHOT]' unless params[:version] test_suite = if ['xpack', 'x-pack', 'platinum'].include? params[:suite] 'platinum' else 'free' end system("STACK_VERSION=#{params[:version]} TEST_SUITE=#{test_suite} ./.ci/run-elasticsearch.sh") end end elastic-elasticsearch-ruby-c38be0c/rake_tasks/elasticsearch_tasks.rake000066400000000000000000000246541462737751600264650ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. ELASTICSEARCH_PATH = "#{CURRENT_PATH}/tmp/elasticsearch".freeze desc 'Clone elasticsearch into the ./tmp directory' task :setup do unless File.exist?('./tmp/elasticsearch') sh 'git clone https://github.com/elasticsearch/elasticsearch.git tmp/elasticsearch' end end namespace :elasticsearch do desc 'Wait for elasticsearch cluster to be in green state' task :wait_for_green do require 'elasticsearch' ready = nil 5.times do |i| begin puts "Attempting to wait for green status: #{i + 1}" if admin_client.cluster.health(wait_for_status: 'green', timeout: '50s') ready = true break end rescue Elasticsearch::Transport::Transport::Errors::RequestTimeout => e puts "Couldn't confirm green status.\n#{e.inspect}." rescue Faraday::ConnectionFailed => e puts "Couldn't connect to Elasticsearch.\n#{e.inspect}." sleep(30) end end unless ready puts "Couldn't connect to Elasticsearch, aborting program." exit(1) end end def package_url(filename, build_hash) begin artifacts = JSON.parse(File.read(filename)) rescue StandardError => e STDERR.puts "[!] Couldn't read JSON file #{filename}" exit 1 end build_hash_artifact = artifacts['version']['builds'].select do |build| build.dig('projects', 'elasticsearch', 'commit_hash') == build_hash end.first unless build_hash_artifact STDERR.puts "[!] Could not find artifact with build hash #{build_hash}, using latest instead" build_hash_artifact = artifacts['version']['builds'].first end # Dig into the elasticsearch packages, search for the rest-resources-zip package and return the URL: build_hash_artifact.dig('projects', 'elasticsearch', 'packages').select { |k,v| k =~ /rest-resources-zip/ }.map { | _, v| v['url'] }.first end def download_file!(url, filename) puts "Downloading #{filename} from #{url}" File.open(filename, "w") do |downloaded_file| URI.open(url, "rb") do |artifact_file| downloaded_file.write(artifact_file.read) end end puts "Successfully downloaded #{filename}" unless File.exist?(filename) STDERR.puts "[!] Couldn't download #{filename}" exit 1 end rescue StandardError => e abort e end desc 'Download artifacts (tests and REST spec) for currently running cluster' task :download_artifacts do json_filename = CURRENT_PATH.join('tmp/artifacts.json') unless (version_number = ENV['STACK_VERSION']) # Get version number and build hash of running cluster: version_number = cluster_info['number'] build_hash = cluster_info['build_hash'] puts "Build hash: #{build_hash}" end # Create ./tmp if it doesn't exist Dir.mkdir(CURRENT_PATH.join('tmp'), 0700) unless File.directory?(CURRENT_PATH.join('tmp')) # Download json file with package information for version: json_url = "https://artifacts-api.elastic.co/v1/versions/#{version_number}" download_file!(json_url, json_filename) # Get the package url from the json file given the build hash zip_url = package_url(json_filename, build_hash) # Download the zip file filename = CURRENT_PATH.join("tmp/#{zip_url.split('/').last}") download_file!(zip_url, filename) spec = CURRENT_PATH.join('tmp/rest-api-spec') FileUtils.remove_dir(spec) if File.directory?(spec) puts "Unzipping file #{filename}" `unzip -o #{filename} -d tmp/` `rm #{filename}` puts 'Artifacts downloaded in ./tmp' end desc <<-DESC Build Elasticsearch for the specified branch ('origin/master' by default) Build a specific branch: $ rake elasticsearch:build[origin/1.x] The task will execute `git fetch` to synchronize remote branches. DESC task :build, :branch do |task, args| Rake::Task['elasticsearch:status'].invoke puts '-' * 80 gitref = args[:branch] || 'origin/master' es_version = gitref.gsub(/^v|origin\/(\d\.+)/, '\1').to_f current_branch = `git --git-dir=#{CURRENT_PATH.join('tmp/elasticsearch/.git')} --work-tree=#{CURRENT_PATH.join('tmp/elasticsearch')} branch --no-color`.split("\n").select { |b| b =~ /^\*/ }.first.gsub(/^\*\s*/, '') STDOUT.puts "Building version [#{es_version}] from [#{gitref}]:", "" case es_version when 0.0, 7.0, 8.0 path_to_build = CURRENT_PATH.join('tmp/elasticsearch/distribution/docker/build/docker/elasticsearch-*.tar.gz') build_command = "cd #{CURRENT_PATH.join('tmp/elasticsearch')} && ./gradlew assemble;" extract_command = <<-CODE.gsub(/ /, '') build=`ls #{path_to_build} | awk '{print $NF}' | awk -F '/' '{print $NF}' | sed s/\.tar\.gz//` if [ $build ]; then rm -rf "#{CURRENT_PATH.join('tmp/builds')}/$build"; echo "cool" else echo "Cannot determine build, exiting..." exit 1 fi tar xvf #{path_to_build} -C #{CURRENT_PATH.join('tmp/builds')}; CODE when 5..1000 path_to_build = CURRENT_PATH.join('tmp/elasticsearch/distribution/tar/build/distributions/elasticsearch-*.tar.gz') build_command = "cd #{CURRENT_PATH.join('tmp/elasticsearch/distribution/tar')} && gradle clean assemble;" extract_command = <<-CODE.gsub(/ /, '') build=`ls #{path_to_build} | xargs -0 basename | sed s/\.tar\.gz//` if [[ $build ]]; then rm -rf "#{CURRENT_PATH.join('tmp/builds')}/$build"; else echo "Cannot determine build, exiting..." exit 1 fi tar xvf #{path_to_build} -C #{CURRENT_PATH.join('tmp/builds')}; CODE when 1.8..4 path_to_build = CURRENT_PATH.join('tmp/elasticsearch/distribution/tar/target/releases/elasticsearch-*.tar.gz') build_command = "cd #{CURRENT_PATH.join('tmp/elasticsearch')} && MAVEN_OPTS=-Xmx1g mvn --projects core,distribution/tar clean package -DskipTests -Dskip.integ.tests;" extract_command = <<-CODE.gsub(/ /, '') build=`ls #{path_to_build} | xargs -0 basename | sed s/\.tar\.gz//` if [[ $build ]]; then rm -rf "#{CURRENT_PATH.join('tmp/builds')}/$build"; else echo "Cannot determine build, exiting..." exit 1 fi tar xvf #{path_to_build} -C #{CURRENT_PATH.join('tmp/builds')}; CODE when 0.1..1.7 path_to_build = CURRENT_PATH.join('tmp/elasticsearch/target/releases/elasticsearch-*.tar.gz') build_command = "cd #{CURRENT_PATH.join('tmp/elasticsearch')} && MAVEN_OPTS=-Xmx1g mvn clean package -DskipTests" extract_command = <<-CODE.gsub(/ /, '') build=`ls #{path_to_build} | xargs -0 basename | sed s/\.tar\.gz//` if [ $build ]; then rm -rf "#{CURRENT_PATH.join('tmp/builds')}/$build"; else echo "Cannot determine build, exiting..." exit 1 fi tar xvf #{path_to_build} -C #{CURRENT_PATH.join('tmp/builds')}; CODE else STDERR.puts "", "[!] Cannot determine a compatible version of the build (gitref: #{gitref}, es_version: #{es_version})" exit(1) end sh <<-CODE.gsub(/ /, '') mkdir -p #{CURRENT_PATH.join('tmp/builds')}; rm -rf '#{CURRENT_PATH.join('tmp/elasticsearch/distribution/tar/target/')}'; cd #{CURRENT_PATH.join('tmp/elasticsearch')} && git fetch origin --quiet; cd #{CURRENT_PATH.join('tmp/elasticsearch')} && git checkout #{gitref}; #{build_command} #{extract_command} echo; echo; echo "Built: $build" CODE puts '', '-' * 80, '' Rake::Task['elasticsearch:builds'].invoke end desc "Display the info for all branches in the Elasticsearch submodule" task :status do sh "git --git-dir=#{CURRENT_PATH.join('tmp/elasticsearch/.git')} --work-tree=#{CURRENT_PATH.join('tmp/elasticsearch')} branch -v -v", :verbose => false end desc "Display the list of builds" task :builds do system "mkdir -p #{CURRENT_PATH.join('tmp/builds')};" puts "Builds:" Dir.entries(CURRENT_PATH.join('tmp/builds')).reject { |f| f =~ /^\./ }.each do |build| puts "* #{build}" end end desc "Display the history of the 'rest-api-spec' repo" task :changes do STDERR.puts "Log: #{CURRENT_PATH.join('tmp/elasticsearch')}/rest-api-spec", "" sh "git --git-dir=#{CURRENT_PATH.join('tmp/elasticsearch/.git')} --work-tree=#{CURRENT_PATH.join('tmp/elasticsearch')} log --pretty=format:'%C(yellow)%h%Creset %s \e[2m[%ar by %an]\e[0m' -- rest-api-spec", :verbose => false end desc "Checkout the build hash from the running Elasticsearch server" task :checkout_build do require 'elasticsearch' branches = `git --git-dir=#{ELASTICSEARCH_PATH}/.git --work-tree=#{ELASTICSEARCH_PATH} branch --no-color` current_branch = branches. split("\n"). select { |b| b =~ /^\*/ }. reject { |b| b =~ /no branch|detached/ }. map { |b| b.gsub(/^\*\s*/, '') }. first unless current_branch STDERR.puts "[!] Unable to determine current branch, defaulting to 'master'" current_branch = 'master' end es_version_info = admin_client.info['version'] unless (build_hash = es_version_info['build_hash']) $stderr.puts "[!] Cannot determine checkout build hash -- server not running" exit(1) end $stdout.puts "ELASTICSEARCH INFO: #{es_version_info}" name = ENV['CI'] ? build_hash : "[\e[1m#{build_hash}\e[0m]" STDERR.puts '-'*80, "YAML tests: Switching to #{name} from #{current_branch}", '-'*80 git_specs("checkout #{build_hash} --force --quiet") end end def git_specs(command, options={}) sh "git --git-dir=#{ELASTICSEARCH_PATH}/.git --work-tree=#{ELASTICSEARCH_PATH} #{command}", options end elastic-elasticsearch-ruby-c38be0c/rake_tasks/test_tasks.rake000066400000000000000000000064411462737751600246240ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. UNIT_TESTED_PROJECTS = [ 'elasticsearch', 'elasticsearch-transport', 'elasticsearch-api', 'elasticsearch-xpack' ].freeze INTEGRATION_TESTED_PROJECTS = (UNIT_TESTED_PROJECTS - ['elasticsearch-api']).freeze namespace :test do require 'open-uri' task bundle: 'bundle:install' desc 'Run all tests in all subprojects' task client: [:unit, :integration] desc 'Run unit tests in all subprojects' task :unit do UNIT_TESTED_PROJECTS.each do |project| puts '-' * 80 sh "cd #{CURRENT_PATH.join(project)} && unset BUNDLE_GEMFILE && unset BUNDLE_PATH && unset BUNDLE_BIN && bundle exec rake test:unit" puts "\n" end end desc 'Run integration tests in all subprojects' task :integration do INTEGRATION_TESTED_PROJECTS.each do |project| puts '-' * 80 sh "cd #{CURRENT_PATH.join(project)} && unset BUNDLE_GEMFILE && bundle exec rake test:integration" puts "\n" end end desc 'Run rest api tests' task rest_api: ['elasticsearch:wait_for_green'] do suite = ENV['TEST_SUITE'] == 'platinum' ? 'xpack' : 'api' project = CURRENT_PATH.join("elasticsearch-#{suite}") puts '-' * 80 sh "cd #{project} && unset BUNDLE_GEMFILE && bundle exec rake test:rest_api" puts "\n" end desc 'Run security (Platinum) rest api yaml tests' task security: 'elasticsearch:wait_for_green' do puts '-' * 80 sh "cd #{CURRENT_PATH.join('elasticsearch-xpack')} && unset BUNDLE_GEMFILE && bundle exec rake test:rest_api" puts "\n" end namespace :cluster do desc 'Start Elasticsearch nodes for tests' task :start do require 'elasticsearch/extensions/test/cluster' Elasticsearch::Extensions::Test::Cluster.start end desc 'Stop Elasticsearch nodes for tests' task :stop do require 'elasticsearch/extensions/test/cluster' Elasticsearch::Extensions::Test::Cluster.stop end task :status do require 'elasticsearch/extensions/test/cluster' (puts "\e[31m[!] Test cluster not running\e[0m"; exit(1)) unless Elasticsearch::Extensions::Test::Cluster.running? Elasticsearch::Extensions::Test::Cluster.__print_cluster_info(ENV['TEST_CLUSTER_PORT'] || 9250) end end # Returns: version_number, build_hash def cluster_info require 'elasticsearch' version_info = admin_client.info['version'] abort('[!] Cannot determine cluster version information -- Is the server running?') unless version_info version_info rescue Faraday::ConnectionFailed => e STDERR.puts "[!] Test cluster not running?" abort e end end elastic-elasticsearch-ruby-c38be0c/rake_tasks/unified_release_tasks.rake000066400000000000000000000063111462737751600267640ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'fileutils' require_relative '../elasticsearch/lib/elasticsearch/version' namespace :unified_release do desc 'Build gem releases and snapshots' task :assemble, [:version, :output_dir] do |_, args| if ENV['WORKFLOW'] == 'snapshot' @zip_filename = "elasticsearch-ruby-#{args[:version]}-SNAPSHOT" @version = "#{args[:version]}.#{Time.now.strftime('%Y%m%d%H%M%S')}-SNAPSHOT" else @version = args[:version] @zip_filename = "elasticsearch-ruby-#{@version}" end Rake::Task['unified_release:bump'].invoke(@version) unless @version == Elasticsearch::VERSION build_gems(args[:output_dir]) create_zip_file(args[:output_dir]) end def build_gems(output_dir) raise ArgumentError, 'You must specify an output dir' unless output_dir # Create dir if it doesn't exist dir = CURRENT_PATH.join(output_dir).to_s FileUtils.mkdir_p(dir) unless File.exist?(dir) RELEASE_TOGETHER.each do |gem| puts '-' * 80 puts "Building #{gem} v#{@version} to #{output_dir}" sh "cd #{CURRENT_PATH.join(gem)} " \ "&& gem build --silent -o #{gem}-#{@version}.gem && " \ "mv *.gem #{CURRENT_PATH.join(output_dir)}" end puts '-' * 80 end def create_zip_file(output_dir) sh "cd #{CURRENT_PATH.join(output_dir)} && " \ "zip -r #{@zip_filename}.zip * " \ end desc <<-DESC Update Rubygems versions in version.rb and *.gemspec files Example: $ rake unified_release:bump[42.0.0] DESC task :bump, :version do |_, args| abort('[!] Required argument [version] missing') unless (version = args[:version]) files = ['elasticsearch/elasticsearch.gemspec'] RELEASE_TOGETHER.each do |gem| files << Dir["./#{gem}/**/**/version.rb"] end version_regexp = Regexp.new(/VERSION = ("|'([0-9.]+(-SNAPSHOT)?)'|")/) gemspec_regexp = Regexp.new(/('elasticsearch-transport'|'elasticsearch-api'),\s+'([0-9x.]+)'/) files.flatten.each do |file| content = File.read(file) regexp = file.match?('gemspec') ? gemspec_regexp : version_regexp if (match = content.match(regexp)) old_version = match[2] content.gsub!(old_version, version) puts "[#{old_version}] -> [#{version}] in #{file.gsub('./','')}" File.open(file, 'w') { |f| f.puts content } else puts "- [#{file}]".ljust(longest_line+20) + " -" end rescue StandardError => e abort "[!!!] #{e.class} : #{e.message}" end end end elastic-elasticsearch-ruby-c38be0c/rake_tasks/update_version.rake000066400000000000000000000101421462737751600254600ustar00rootroot00000000000000# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. desc <<-DESC Update Rubygems versions in version.rb and *.gemspec files Example: $ rake update_version[5.0.0,5.0.1] DESC task :update_version, :old, :new do |_, args| require 'ansi' puts '[!!!] Required argument [old] missing'.ansi(:red) unless args[:old] puts '[!!!] Required argument [new] missing'.ansi(:red) unless args[:new] files = Dir['**/**/version.rb','**/**/*.gemspec'] longest_line = files.map(&:size).max puts "\n", '= FILES '.ansi(:faint) + ('='*92).ansi(:faint), "\n" files.each do |file| begin content = File.read(file) if content.match Regexp.new(args[:old]) content.gsub! Regexp.new(args[:old]), args[:new] puts "+ [#{file}]".ansi(:green).ljust(longest_line+20) + " [#{args[:old]}] -> [#{args[:new]}]".ansi(:green,:bold) File.open(file, 'w') { |f| f.puts content } else puts "- [#{file}]".ansi(:yellow).ljust(longest_line+20) + " -".ansi(:faint,:strike) end rescue Exception => e puts "[!!!] #{e.class} : #{e.message}".ansi(:red,:bold) raise e end end end task :update_changelog do puts "\n\n", '= CHANGELOG '.ansi(:faint) + ('='*88).ansi(:faint), "\n" log = `git --no-pager log --reverse --no-color --pretty='* %s' HEAD --not v#{args[:old]} elasticsearch*`.split("\n") puts log.join("\n") log_entries = {} log_entries[:client] = log.select { |l| l =~ /\[CLIENT\]/ } log_entries[:api] = log.select { |l| l =~ /\[API\]/ } log_entries[:xpack] = log.select { |l| l =~ /\[XPACK\]/ } changelog = File.read(File.open('CHANGELOG.md', 'r')) changelog_update = '' if log.any? { |l| l =~ /CLIENT|API/ } changelog_update << "## #{args[:new]}\n\n" end unless log_entries[:client].empty? changelog_update << "### Client\n\n" changelog_update << log_entries[:client] .map { |l| l.gsub /\[CLIENT\] /, '' } .map { |l| "#{l}" } .join("\n") changelog_update << "\n\n" end unless log_entries[:api].empty? changelog_update << "### API\n\n" changelog_update << log_entries[:api] .map { |l| l.gsub /\[API\] /, '' } .map { |l| "#{l}" } .join("\n") changelog_update << "\n\n" end unless log_entries[:xpack].empty? changelog_update << "### XPACK\n\n" changelog_update << log_entries[:xpack] .map { |l| l.gsub /\[XPACK\] /, '' } .map { |l| "#{l}" } .join("\n") changelog_update << "\n\n" end File.open('CHANGELOG.md', 'w+') { |f| f.write changelog_update and f.write changelog } puts "\n\n", "= DIFF ".ansi(:faint) + ('='*93).ansi(:faint) diff = `git --no-pager diff --patch --word-diff=color --minimal elasticsearch*`.split("\n") puts diff .reject { |l| l =~ /^\e\[1mdiff \-\-git/ } .reject { |l| l =~ /^\e\[1mindex [a-z0-9]{7}/ } .reject { |l| l =~ /^\e\[1m\-\-\- i/ } .reject { |l| l =~ /^\e\[36m@@/ } .map { |l| l =~ /^\e\[1m\+\+\+ w/ ? "\n#{l} " + '-'*(104-l.size) : l } .join("\n") puts "\n\n", '= COMMIT '.ansi(:faint) + ('='*91).ansi(:faint), "\n" puts 'git add CHANGELOG.md elasticsearch*', "git commit --verbose --message='Release #{args[:new]}' --edit", 'rake release', '' end elastic-elasticsearch-ruby-c38be0c/scripts/000077500000000000000000000000001462737751600211275ustar00rootroot00000000000000elastic-elasticsearch-ruby-c38be0c/scripts/wait-cluster.sh000077500000000000000000000010231462737751600241050ustar00rootroot00000000000000#!/bin/bash TEST_ES_SERVER=${TEST_ES_SERVER:-"http://localhost:9200"} echo $TEST_ES_SERVER attempt_counter=0 max_attempts=5 url="${TEST_ES_SERVER}/_cluster/health?wait_for_status=green&timeout=50s" echo "Waiting for Elasticsearch..." while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' --max-time 55 "$url")" != "200" ]]; do if [ ${attempt_counter} -eq ${max_attempts} ];then echo "\nCouldn't connect to Elasticsearch" exit 1 fi printf '.' attempt_counter=$(($attempt_counter+1)) sleep 5 done echo "\nReady"