2
votes

Comment générer un UUID dans le script de réindexation Elasticsearch sans douleur

J'essaie d'utiliser l'API de réindexation pour créer une copie d'un ensemble de documents. L'un des champs ( uuid ) du document est un UUID. J'ai besoin que les documents copiés aient de nouveaux UUID pour le champ uuid .

Selon [1] et [2] la méthode java.util.UUID.randomUUID () code > n'est pas sur la liste blanche pour une utilisation dans des scripts indolores.

Questions:

1) Comment puis-je générer un UUID sans douleur?

2) Pourquoi UUID.randomUUID () est-il considéré comme une opération non sécurisée? Ou est-ce juste un oubli de ne pas être sur la liste blanche?

3) Comment puis-je ajouter UUID.randomUUID () dans le contexte "reindex" ? J'ai essayé de créer ma propre extension / plugin indolore elasticsearch pour le faire en me basant sur l'exemple de [3]. Le problème est que cela ne fonctionne que pour le contexte "SearchScript" . Il ne semble pas y avoir de "ReindexContext" équivalent .

Voici une version simplifiée de ce que j'essaye:

curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
{
  "source": {
    "index": "product1"
  },
  "dest": {
    "index": "product2"
  },
  "script": {
    "source": "ctx._source.uuid = java.util.UUID.fromString(\u0027ad139caa-5b54-4179-b812-5015daecad1e\u0027).toString()",
    "lang": "painless"
  }
}
'

Ce qui produit l'erreur suivante:

{
  "error" : {
    "root_cause" : [
      {
        "type" : "script_exception",
        "reason" : "compile error",
        "script_stack" : [
          "... rce.uuid = java.util.UUID.randomUUID().toString()",
          "                             ^---- HERE"
        ],
        "script" : "ctx._source.uuid = java.util.UUID.randomUUID().toString()",
        "lang" : "painless"
      }
    ],
    "type" : "script_exception",
    "reason" : "compile error",
    "script_stack" : [
      "... rce.uuid = java.util.UUID.randomUUID().toString()",
      "                             ^---- HERE"
    ],
    "script" : "ctx._source.uuid = java.util.UUID.randomUUID().toString()",
    "lang" : "painless",
    "caused_by" : {
      "type" : "illegal_argument_exception",
      "reason" : "method [java.util.UUID, randomUUID/0] not found"
    }
  },
  "status" : 500
}

Je sais que mon approche est valide et que ce qui précède est un problème de liste blanche indolore car lorsque j'essaie une méthode différente ( fromString () ) Je n'obtiens aucune erreur:

curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
{
  "source": {
    "index": "product1"
  },
  "dest": {
    "index": "product2"
  },
  "script": {
    "source": "ctx._source.uuid = java.util.UUID.randomUUID().toString()",
    "lang": "painless"
  }
}
'

Références:

[1] - https: //discuss.elastic. co / t / generate-a-uuid-using-randomuuid-in-painless / 144354/3

[2] - https://www.elastic.co/guide/en/elasticsearch/painless/6.6/painless-api- reference.html

[3] - https: // github.com/elastic/elasticsearch/tree/v6.6.0/plugins/examples/painless-whitelist

Autres remarques:


2 commentaires

Vous pouvez définir votre propre implémentation / méthode personnalisée dans le script pour générer des uuid selon vos besoins et utiliser cette méthode. En gros, contourner la dépendance


Ma demande de fonctionnalité pour résoudre ce problème a été acceptée et mise en œuvre ici: github.com/elastic/elasticsearch/ numéros / 39080


3 Réponses :


0
votes
You can simply do the following,

curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
{
  "source": {
    "index": "product1"`enter code here`
  },
  "dest": {
    "index": "product2"
  },
  "script": {
    "source": "ctx._id=ctx._id+1",
    "lang": "painless"
  }
}
'
ctx._id = will always give you a new id and plus 1 will generate the new one.
this is just a solution to get unique id by adding suffix

1 commentaires

Merci d'avoir répondu. Cependant, la question concerne la mise à jour d'un champ uuid et le résultat doit être un uuid valide.



0
votes

L'approche la plus simple est d'utiliser une fonction auto-écrite, voici la mienne. Bien sûr, ce n'est qu'une solution de contournement, mais cela devrait aider dans la plupart des cas.

String generateUUID(boolean addDashes, boolean upperCase) {
    def chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];

    def dashIndices = [7, 11, 15, 19];

    def sb = new StringBuilder();

    def r = new Random();

    for (def pos = 0; pos < 32; pos += 1) {
       sb.append(chars[r.nextInt(16)]);

       if (addDashes && dashIndices.contains(pos)) {
         sb.append('-');
       }
    }

    def result = sb.toString();

    return upperCase ? result.toUpperCase() : result;
}

Copiez-le dans votre script et ci-dessous vous pourrez obtenir l'UUID en appelant, par exemple, generateUUID (vrai, faux) , si vous avez besoin d'un UUID avec des tirets et en minuscules.


3 commentaires

Ma demande de fonctionnalité pour résoudre ce problème a été acceptée et mise en œuvre ici: github.com/elastic/elasticsearch/ numéros / 39080


@OliverHenlich Excellent travail! Il est bon de savoir que Indolore deviendra un peu moins douloureux dans un avenir proche.


Si vous générez votre propre UUID aléatoire de cette manière, assurez-vous de définir les bits appropriés pour le marquer comme un UUID aléatoire . Voir: tools.ietf.org/html/rfc4122 section 4.4.



1
votes

Ma demande de fonctionnalité pour résoudre ce problème a été acceptée et mise en œuvre ici: https: // github .com / élastique / elasticsearch / issues / 39080


0 commentaires