From 547a59135fab56c0b80564c2cc948ded7c029532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Wed, 9 Dec 2020 13:58:38 -0300 Subject: [PATCH] Refatora Solr API (#3322) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refatora solr_api * Conserta bug ao zipar subdir * Remove zip de controle de versão * Adiciona try/catch nos res.json() * Faz o zip de subdir * Mais mudanças * WIP * Conserta bug em zip file * Remoção de linhas de debug * Adiciona create-collection.sh * Adiciona upload-config.sh * Adiciona delete-collection.sh * Adiciona delete-config.sh * Adiciona delete-records.sh * Adiciona list-collections-configs.sh * Adiciona update-configset.sh * Update and rename delete-records.sh to delete-all-documents.sh * Update update-configset.sh Co-authored-by: eribeiro --- docker/solr_api.py | 71 +++++++++++++++++---- solr/bin/create-collection.sh | 6 ++ solr/bin/delete-all-documents.sh | 6 ++ solr/bin/delete-collection.sh | 6 ++ solr/bin/delete-config.sh | 5 ++ solr/bin/list-collections-configs.sh | 6 ++ solr/bin/update-configset.sh | 10 +++ solr/bin/upload-config.sh | 11 ++++ solr/sapl_configset/conf/saplconfigset.zip | Bin 28360 -> 0 bytes 9 files changed, 108 insertions(+), 13 deletions(-) create mode 100644 solr/bin/create-collection.sh create mode 100644 solr/bin/delete-all-documents.sh create mode 100644 solr/bin/delete-collection.sh create mode 100644 solr/bin/delete-config.sh create mode 100644 solr/bin/list-collections-configs.sh create mode 100644 solr/bin/update-configset.sh create mode 100644 solr/bin/upload-config.sh delete mode 100644 solr/sapl_configset/conf/saplconfigset.zip diff --git a/docker/solr_api.py b/docker/solr_api.py index 7713619a2..3ca06bba7 100755 --- a/docker/solr_api.py +++ b/docker/solr_api.py @@ -1,26 +1,37 @@ - +from io import BytesIO +import argparse +import os import requests import subprocess import sys -import argparse +import zipfile +from pathlib import Path +## +## Este módulo deve ser executado na raiz do projeto +## class SolrClient: LIST_CONFIGSETS = "{}/solr/admin/configs?action=LIST&omitHeader=true&wt=json" UPLOAD_CONFIGSET = "{}/solr/admin/configs?action=UPLOAD&name={}&wt=json" LIST_COLLECTIONS = "{}/solr/admin/collections?action=LIST&wt=json" - STATUS_COLLECTION = "{}/solr/admin/collections?action=CLUSTERSTATUS&collection={}&wt=json" + STATUS_COLLECTION = "{}/solr/admin/collections?action=CLUSTERSTATUS" \ + "&collection={}&wt=json" STATUS_CORE = "{}/admin/cores?action=STATUS&name={}" EXISTS_COLLECTION = "{}/solr/{}/admin/ping?wt=json" OPTIMIZE_COLLECTION = "{}/solr/{}/update?optimize=true&wt=json" - CREATE_COLLECTION = "{}/solr/admin/collections?action=CREATE&name={}&collection.configName={}&numShards={}&replicationFactor={}&maxShardsPerNode={}&wt=json" + CREATE_COLLECTION = "{}/solr/admin/collections?action=CREATE&name={}" \ + "&collection.configName={}&numShards={}" \ + "&replicationFactor={}&maxShardsPerNode={}&wt=json" DELETE_COLLECTION = "{}/solr/admin/collections?action=DELETE&name={}&wt=json" DELETE_DATA = "{}/solr/{}/update?commitWithin=1000&overwrite=true&wt=json" QUERY_DATA = "{}/solr/{}/select?q=*:*" CONFIGSET_NAME = "sapl_configset" + CONFIGSET_PATH = "./solr/sapl_configset/conf" + def __init__(self, url): self.url = url @@ -32,7 +43,7 @@ class SolrClient: dic = res.json() return dic["response"]["numFound"] except Exception as e: - print(F"Erro no get_num_docs: {e}") + print(F"Erro no get_num_docs. Erro: {e}") print(res.content) return 0 @@ -40,23 +51,52 @@ class SolrClient: def list_collections(self): req_url = self.LIST_COLLECTIONS.format(self.url) res = requests.get(req_url) - dic = res.json() - return dic['collections'] + try: + dic = res.json() + return dic['collections'] + except Exception as e: + print(F"Erro no list_collections. Erro: {e}") + print(res.content) + return 0 def exists_collection(self, collection_name): collections = self.list_collections() return True if collection_name in collections else False + def zip_configset(self): + try: + base_path = Path(self.CONFIGSET_PATH).expanduser().resolve(strict=True) + + # zip files in memory + _zipfile = BytesIO() + with zipfile.ZipFile(_zipfile, 'w', zipfile.ZIP_DEFLATED) as zipf: + for file in base_path.rglob('*'): + zipf.write(file, file.relative_to(base_path)) + return _zipfile + except Exception as e: + print(e) + raise e + def maybe_upload_configset(self, force=False): req_url = self.LIST_CONFIGSETS.format(self.url) res = requests.get(req_url) - dic = res.json() - configsets = dic['configSets'] + try: + dic = res.json() + configsets = dic['configSets'] + except Exception as e: + print(F"Erro ao configurar configsets. Erro: {e}") + print(res.content) + # UPLOAD configset if not self.CONFIGSET_NAME in configsets or force: + + # GENERATE in memory configset + configset_zip = self.zip_configset() + data = configset_zip.getvalue() + configset_zip.close() + files = {'file': ('saplconfigset.zip', - open('./solr/sapl_configset/conf/saplconfigset.zip', - 'rb'), + data, 'application/octet-stream', {'Expires': '0'})} @@ -64,6 +104,7 @@ class SolrClient: resp = requests.post(req_url, files=files) print(resp.content) + else: print('O %s já presente no servidor, NÃO enviando.' % self.CONFIGSET_NAME) @@ -80,8 +121,12 @@ class SolrClient: print("Collection '%s' created succesfully" % collection_name) else: print("Error creating collection '%s'" % collection_name) - as_json = res.json() - print("Error %s: %s" % (res.status_code, as_json['error']['msg'])) + try: + as_json = res.json() + print("Error %s: %s" % (res.status_code, as_json['error']['msg'])) + except Exception as e: + print(F"Erro ao verificar erro na resposta. Erro: {e}") + print(res.content) return False return True diff --git a/solr/bin/create-collection.sh b/solr/bin/create-collection.sh new file mode 100644 index 000000000..3288ae43c --- /dev/null +++ b/solr/bin/create-collection.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +SOLR_URL=${SOLR_URL-'http://localhost:8983/solr'} +SOLR_COLLECTION=${SOLR_COLLECTION-'sapl'} + +curl -X POST "$SOLR_URL/admin/collections?action=CREATE&name=$SOLR_COLLECTION&numShards=1&replicationFactor=1&collection.configName=sapl_configset" \ No newline at end of file diff --git a/solr/bin/delete-all-documents.sh b/solr/bin/delete-all-documents.sh new file mode 100644 index 000000000..c9a7b09cf --- /dev/null +++ b/solr/bin/delete-all-documents.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +SOLR_URL=${SOLR_URL-'http://localhost:8983/solr'} +SOLR_COLLECTION=${SOLR_COLLECTION-'sapl'} + +curl -X POST "$SOLR_URL/$SOLR_COLLECTION/update?commit=true" -H "Content-Type: text/xml" --data-binary '*:*' diff --git a/solr/bin/delete-collection.sh b/solr/bin/delete-collection.sh new file mode 100644 index 000000000..9e4fb466e --- /dev/null +++ b/solr/bin/delete-collection.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +SOLR_URL=${SOLR_URL-'http://localhost:8983/solr'} +SOLR_COLLECTION=${SOLR_COLLECTION-'sapl'} + +curl -X POST "$SOLR_URL/admin/collections?action=DELETE&name=$SOLR_COLLECTION" \ No newline at end of file diff --git a/solr/bin/delete-config.sh b/solr/bin/delete-config.sh new file mode 100644 index 000000000..b8ca38823 --- /dev/null +++ b/solr/bin/delete-config.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +SOLR_URL=${SOLR_URL-'http://localhost:8983/solr'} + +curl -X POST "$SOLR_URL/admin/configs?action=DELETE&name=sapl_configset&omitHeader=true" \ No newline at end of file diff --git a/solr/bin/list-collections-configs.sh b/solr/bin/list-collections-configs.sh new file mode 100644 index 000000000..32bcb9e43 --- /dev/null +++ b/solr/bin/list-collections-configs.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +SOLR_URL=${SOLR_URL-'http://localhost:8983/solr'} + +curl -X GET "$SOLR_URL/admin/collections?action=LIST" + +curl -X GET "$SOLR_URL/admin/configs?action=LIST" \ No newline at end of file diff --git a/solr/bin/update-configset.sh b/solr/bin/update-configset.sh new file mode 100644 index 000000000..52861868b --- /dev/null +++ b/solr/bin/update-configset.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +if [[ -z $SOLR_HOME ]]; then + echo 'Cannot run script! You need to setup $SOLR_HOME' + exit +fi + +ZK_HOST=${ZK_HOST-'localhost:9983'} + +$SOLR_HOME/bin/solr zk upconfig -n sapl_configset -d solr/sapl_configset/ -z $ZK_HOST diff --git a/solr/bin/upload-config.sh b/solr/bin/upload-config.sh new file mode 100644 index 000000000..8d1d7ba36 --- /dev/null +++ b/solr/bin/upload-config.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +SOLR_URL=${SOLR_URL-'http://localhost:8983/solr'} + +# zip configset sapl_configset +cd ../sapl_configset/conf && zip -r sapl_configset.zip . + +curl -X POST --header "Content-Type:application/octet-stream" --data-binary @sapl_configset.zip "$SOLR_URL/admin/configs?action=UPLOAD&name=sapl_configset" + +cd - +rm ../sapl_configset/conf/sapl_configset.zip \ No newline at end of file diff --git a/solr/sapl_configset/conf/saplconfigset.zip b/solr/sapl_configset/conf/saplconfigset.zip deleted file mode 100644 index 2bd9c45f37a0786fbe2e1c31627426ca30b6897e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28360 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 O{r1mn=`sK7?Ee6~Cr3sA