web-dev-qa-db-fra.com

Comment parler au service aws elasticsearch à l'aide du client élastique Java client?

J'ai configuré un serveur elasticsearch à l'aide de AWS elasticsearch service (pas EC2). Cela m'a donné un point de terminaison https://xxx-xxxxxxxx.us-west-2.es.amazonaws.com/ et si je clique sur ce point de terminaison (notez qu'aucun port n'est spécifié), je peux obtenir l'attendu

{
  status: 200,
  name: "Mastermind",
  cluster_name: "xxxx",
  version: {
    number: "1.5.2",
    build_hash: "yyyyyy",
    build_timestamp: "2015-04-27T09:21:06Z",
    build_snapshot: false,
    lucene_version: "4.10.4"
  },
  tagline: "You Know, for Search"
}

La question est de savoir comment obtenir cela via le client elasticsearch Java sans numéro de port? L'exemple de code que j'obtiens est

Client client = TransportClient.builder().build()
    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("Host1"), 9300));

Si j'utilise ce code et que je remplace simplement "Host1" par mon point de terminaison, je reçois "NoNodeAvailableException"

ps: La version du client Java Java que j'utilise est 2.0.0.

Edit J'ai finalement décidé de choisir Jest , une tierce partie REST client. Mais ce que Brooks a répondu ci-dessous est également très utile - AWS utilise le port 80 pour http et 443 pour https. Le bloqueur pour moi était le pare-feu je suppose.

Edit2 La documentation du service AWS ES indique explicitement:
Le service prend en charge HTTP sur le port 80, mais ne prend pas en charge TCP.

13
Edmond

Croyez-le ou non, AWS ne lance pas Elasticsearch en utilisant 9200 et 9300. Il est lancé via l'ancien port 80 ordinaire.

Donc, pour démontrer, essayez ceci ...

curl -XPOST "http://xxx-xxxxxxxx.us-west-2.es.amazonaws.com:80/myIndex/myType" -d '["name":"Edmond"}'

Ou

curl -XPOST "https://xxx-xxxxxxxx.us-west-2.es.amazonaws.com:443/myIndex/myType" -d '["name":"Edmond"}'

Il doit répondre avec: {"_index": "myIndex", "_ type": "myType", "_ id": "SOME_ID _ #", "_ version": 1, "created": true}

Enregistrez-vous à Kibana et vous verrez que c'est là.

Donc, dans votre code, cela devrait être:

Client client = TransportClient.builder().build()
    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("xxx-xxxxxxxx.us-west-2.es.amazonaws.com"), 80));

Malheureusement, je ne sais pas comment transmettre crypté via SSL/HTTPS en utilisant le client de transport. Vous pouvez essayer d'utiliser des appels réguliers REST à la place en utilisant JERSEY.

Enfin, assurez-vous que votre stratégie d'accès Elasticsearch est correctement configurée. Quelque chose dans le sens de:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "es:*",
      "Resource": "arn:aws:es:us-east-1:yyyyyyy:domain/myDomain/*"
    },
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "es:*",
      "Resource": "arn:aws:es:us-east-1:yyyyyyyyy:domain/myDomain"
    }
  ]
}

REMARQUE: La politique d'accès ci-dessus est complètement ouverte et n'est pas recommandée pour quoi que ce soit à distance proche de la production. Juste pour que vous sachiez ....

14
Brooks

Le service de recherche élastique géré dans AWS ne fournit pas le port pour le protocole de transport jusqu'à présent.
On a répondu à cette question ici,

client Elastic Transport sur AWS Managed ElasticSearch1

Il y a également une discussion dans le forum AWS concernant le protocole de transport. Voici le lien

Quel est le port pour le protocole de transport?

3
Shahin Alam

Après beaucoup de recherches, j'ai trouvé un exemple qui utilisait une requête GET, donc j'y ai apporté des modifications mineures pour autoriser les requêtes POST afin que les requêtes complexes puissent être soumises via le corps POST. L'implémentation est disponible sur https://github.com/dy10/aws-elasticsearch-query-Java

En plus de configurer correctement l'accès à votre AWS ES (c'est-à-dire ne l'ouvrez pas au public), assurez-vous d'utiliser https (le code ci-dessus utilise http; remplacez simplement http par https dans le code et cela fonctionnera).

Une autre mise en œuvre utile mais partielle est à https://github.com/aws/aws-sdk-Java/issues/861

1
dy10