Solr 8.4.0 – zarządzanie pluginami

Wraz z premierą Solr 8.4.0 dostajemy w nasze ręce nową funkcjonalność – zarządzanie dodatkami do Solr. Solr udostępnia nam możliwość instalowania oraz zarządzania dodatkami i repozytoriami dodatków. Spójrzmy zatem jak to działa.

Zarządzanie pakietami, czyli co?

Wraz z Solr 8.4.0 dostaliśmy nie tylko sam skrypt umożliwiający pobieranie i usuwanie pakietów. W ramach zmian dostaliśmy także cały pakiet zmian takich jak przechowywanie informacji o pakietach, zarządzanie kluczami, API do odczytu i zapisu oraz odizolowanie na poziomie classloadera.

Zacznijmy zatem od początku, uruchamiamy pojedynczą instancję SolrCloud następującym poleceniem:

$ bin/solr start -c -f -Denable.packages=true

I zaczynamy zabawę pakietami.

Podstawy zarządzania pakietami

Po wpisaniu komendy:

$ bin/solr package 

Dostaniemy następujące informacje:

Found 1 Solr nodes:
 
Solr process 20949 running on port 8983
Package Manager

./solr package add-repo  
Add a repository to Solr.

./solr package install [:]
Install a package into Solr. This copies over the artifacts from the repository into Solr's internal package store and sets up classloader for this package to be used.

./solr package deploy [:] [-y] [--update] -collections <package-name>[:] [-y] [--update] -collections  [-p param1=value1 -p param2=value2 …
Bootstraps a previously installed package into the specified collections. It the package accepts parameters for its setup commands, they can be specified (as per package documentation).

./solr package list-installed
Print a list of packages installed in Solr.

./solr package list-available
Print a list of packages available in the repositories.

./solr package list-deployed -c 
Print a list of packages deployed on a given collection.

./solr package list-deployed 
Print a list of collections on which a given package has been deployed.

./solr package undeploy  -collections 
Undeploys a package from specified collection(s)

Note: (a) Please add '-solrUrl http://host:port' parameter if needed (usually on Windows).
      (b) Please make sure that all Solr nodes are started with '-Denable.packages=true' parameter.

Jak widać mamy dostępnych całkiem sporo opcji, a sam mechanizm zarządzania pakietami weryfikuje działające instancje Solr i sprawdza pakiety na nich zainstalowane.

Dodawanie nowego repozytorium

W celu dodania nowego repozytorium musimy podać jego nazwę oraz jego lokalizację – URL pod którym można dostać się do repozytorium. Oczywiście w podanym repozytorium muszą znajdować się pliki, których Solr oczekuje – na przykład pliku repository.json wyglądający następująco (przykład z kodu źródłowego Solr):

[
  {
    "name": "question-answer",
    "description": "A natural language question answering plugin",
    "versions": [
      {
        "version": "1.0.0",
        "date": "2019-01-01",
        "artifacts": [
          {
            "url": "qarh-1.0.jar",
            "sig": "C9UWKkucmY3UNzqn0VLneVMe9kCbJjw7Urc76vGenoRwp32xvNn5ZIGZ7G34xZP7cVjqn/ltDlLWBZ/C3eAtuw=="
          }
        ],
        "manifest": {
          "version-constraint": "8 - 9",
          "plugins": [
            {
              "name": "request-handler",
              "setup-command": {
                "path": "/api/collections/${collection}/config",
                "payload": {"add-requesthandler": {"name": "${RH-HANDLER-PATH}", "class": "question-answer:fullstory.QARequestHandler"}},
                "method": "POST"
              },
              "uninstall-command": {
                "path": "/api/collections/${collection}/config",
                "payload": {"delete-requesthandler": "${RH-HANDLER-PATH}"},
                "method": "POST"
              },
              "verify-command": {
                "path": "/api/collections/${collection}/config/requestHandler?componentName=${RH-HANDLER-PATH}&meta=true",
                "method": "GET",
                "condition": "$['config'].['requestHandler'].['${RH-HANDLER-PATH}'].['_packageinfo_'].['version']",
                "expected": "${package-version}"
              }
            }
          ],
          "parameter-defaults": {
            "RH-HANDLER-PATH": "/mypath"
          }
        }
      }
    ]
  }
]

Spróbujmy zatem dodać nowe repozytorium za pomocą następującego polecenia oraz korzystając z plików dostępnych w kodzie źródłowym Solr:

$ bin/solr package add-repo solrpl http://repo.solr.pl

W przypadku poprawnego dodania repozytorium powinniśmy zobaczyć następujący komunikat:

Added repository: solrpl

Uwaga: w powyższym przykładzie skorzystałem z repozytorium do którego można się dostać bez SSL – proszę, nie powtarzajcie tego. Nie jest to dobra praktyka ze względu na możliwość ataków typu man in the middle i podmiany plików pobieranych z repozytorium.

Instalowanie i usuwanie pakietów

Po dodaniu repozytorium możemy sprawdzić listę pakietów jakie mamy dostępne. Aby to zrobić uruchamiamy polecenie:

$ bin/solr package list-available

W odpowiedzi powinniśmy dostać następujące informacje:

Available packages:
-----
question-answer 		A natural language question answering plugin
	Version: 1.0.0

Przed instalacją pakietów musimy jeszcze dodać klucz publiczny, za pomocą którego Solr będzie w stanie zweryfikować pliki związane z pakietami. Gdzie szukać takiego klucza? W repozytorium lub u dostawcy pakietów 🙂 Mając już klucz możemy go zainstalować następującym poleceniem:

$ bin/solr package add-key publickey.der

Mając te dane oraz dodany klucz możemy zacząć instalować pakiety. To dość proste, wystarczy nam następujące polecenie:

$ bin/solr package install question-answer:1.0.0

Odpowiedź powinna być następująca:

Posting manifest...
Posting artifacts...
Executing Package API to register this package...
Response: {"responseHeader":{
    "status":0,
    "QTime":66}}
question-answer installed.

Oznacza to, iż nasz pakiet jest gotowy do wykorzystania. Musimy wybrać kolekcję oraz uruchomić polecenie deploy, np w następujący sposób:

$ bin/solr package deploy question-answer:1.0.0 -collections test

Tym razem odpowiedź Solr była następująca:

Executing {"add-requesthandler":{"name":"/mypath","class":"question-answer:fullstory.QARequestHandler"}} for path:/api/collections/test/config
Execute this command (y/n):
y
Executing http://localhost:8983/api/collections/test/config/requestHandler?componentName=/mypath&meta=true for collection:test
{
  "responseHeader":{
    "status":0,
    "QTime":0},
  "config":{"requestHandler":{"/mypath":{
        "name":"/mypath",
        "class":"question-answer:fullstory.QARequestHandler",
        "_packageinfo_":{
          "package":"question-answer",
          "version":"1.0.0",
          "files":["/package/question-answer/1.0.0/question-answer-request-handler-1.0.jar"],
          "manifest":"/package/question-answer/1.0.0/manifest.json",
          "manifestSHA512":"a91ab5a2c5abd53f0f72c256592c2be8b667cecb8226ac054aeed4d28aac9d743311442f2d58539bb83663a19bd1efb310aaadfd77bea458f3d475161721a114"}}}}}

Actual: 1.0.0, expected: 1.0.0
Deployed on [test] and verified package: question-answer, version: 1.0.0
Deployment successful

Jeżeli wszystko poszło tak, jak się spodziewaliśmy oraz odpowiedzieliśmy, iż chcemy dodać pakiet do kolekcji jesteśmy gotowi 🙂

Gdy chcemy pozbyć się niechcianych pakietów wystarczy wysłać do Solr polecenie undeploy wraz z nazwą kolekcji oraz pakietem z którego nie chcemy już więcej korzystać. Na przykład, jeżeli nie chcemy już korzystać z pakietu, który dodaliśmy wcześniej wystarczy następujące polecenie:

$ bin/solr package undeploy question-answer -collections test

W tym wypadku odpowiedź będzie następująca:

Executing {"delete-requesthandler":"/mypath"} for path:/api/collections/test/config

Jak to naprawdę działa?

Całość zaimplementowanego mechanizmu kręci się tak naprawdę wokół ładowania klas. Mechanizm zakłada, iż jakakolwiek zmiana w plikach znajdujących się w classpath Solr wymaga restartu serwera. Wszystkie inne pliki mogą być ładowane dynamicznie i związane są z konfiguracją, która trzymana jest w Zookeeper.

U podstaw całego mechanizmu znajduje się tak zwany Package Store. Rozproszony system plików, który trzyma swoje dane na każdej z instancji Solr w katalogu $SOLR_HOME/filestore, a każdy plik opisany jest za pomocą metadanych trzymanych w pliku JSON. Meta dane pliku przechowują sumę kontrolną pliku pozwalając tym samym na weryfikację.

Na tym wszystkim zbudowane jest API pozwalające na zarządzanie pojedynczymi plikami, jak również całymi pakietami – np. instalowanie pakietów, czy ich uruchamianie dla poszczególnych kolekcji.

API

Oczywiście bin/solr oraz instalowanie pakietów z poziomu tego narzędzia to nie wszystko co oferuje Solr. Do dyspozycji dostaliśmy także API pozwalające na:

  • dodawanie plików do Solr za pomocą metody PUT protokołu HTTP z wykorzystaniem /api/cluster/files/{ścieżka_do_pliku}
  • pobieranie plików za pomocą metody GET protokołu HTTP z wykorzystaniem /api/cluster/files/{ścieżka_do_pliku}
  • pobieranie meta danych o danym pliku za pomocą metody GET protokołu HTTP z wykorzystaniem /api/cluster/files/{ścieżka_do_pliku}?meta=true
  • pobieranie dostępnych plików w ramach podanej ścieżki za pomocą metody GET protokołu HTTP z wykorzystaniem /api/cluster/files/{ścieżka_do_katalogu}

Warto pamiętać, iż dodanie pliku to nie tylko same wysłanie go do Solr, należy go najpierw podpisać kluczem, który dostępny jest dla Solr. Oficjalna dokumentacja Solr pokazuje, jak to zrobić: https://lucene.apache.org/solr/guide/8_5/package-manager-internals.html.

Jednak API do instalowania plików i ich pobierania to nie wszystko. Mamy także możliwość dodawania, usuwania oraz pobierania pakietów i ich wersji, czyli:

  • GET na /api/cluster/package w celu pobrania listy pakietów
  • PUT na /api/cluster/package w celu dodania pakietu
  • DELETE na /api/cluster/package w celu usunięcia pakietu

Na przykład dodanie pakietu do Solr mogłoby odbyć się za pomocą następującego polecenia:

curl -XPUT 'http://localhost:8983/api/cluster/package' -H 'Content-type:application/json' -d  '{
 "add": {
  "package" : "testsolrpl",
  "version" : "1.0.0",
  "files" : [
   "/test/solrpl/1.0.0/testsolrpl.jar"
  ]
 }
}'

Bezpieczeństwo

Korzystanie z elastyczności, jaką daje hot-deploy oraz możliwość instalowania pakietów rozszerzających możliwości Solr w dowolnym momencie niesie ze sobą szereg niebezpieczeństw. Ze względu na to nie powinniśmy instalować pakietów ze źródeł, których nie znamy lub nie jesteśmy pewni co się w nich znajduje. Warto też pamiętać o korzystaniu tylko z tych repozytoriów, które dodaliśmy z wykorzystaniem SSL co zapobiegnie atakom typu man in the middle. Oczywiście wszystko to powinno być także poprzedzone normalnym zabezpieczeniem Solr – np. brakiem możliwości dostania się do Solr z zewnątrz.

Podsumowanie

Funkcjonalność instalowania pakietów bez konieczności manualnego wgrywania ich na każdy z serwerów, bez konieczności ponownego uruchamiania Solr, możliwość zarządzania nimi za pomocą API oraz weryfikacja samych plików binarnych jest bardzo fajną funkcjonalnością i przyda się niektórym użytkownikom. Należy jednak pamiętać, iż elastyczność niesie za sobą pewne niebezpieczeństwo. Jeżeli jednak pamiętamy z jakimi ograniczeniami i potencjalnymi problemami możemy mieć do czynienia nie powinniśmy obawiać się korzystania z opisanej funkcjonalności.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *