From 5f990c8a53dbce9ae1f269c58af22c781c358826 Mon Sep 17 00:00:00 2001 From: Ryan Quey Date: Wed, 24 Jun 2020 12:39:33 +0000 Subject: [PATCH] add searchkit, setup express endpoint for searchkit to access Elasticsearch --- README.md | 7 +++ app.js | 68 ++++++++++++++++++++++++--- elasticsearch.yml | 92 +++++++++++++++++++++++++++++++++++++ package.json | 1 + src/App.js | 35 +++++++++----- src/components/FlightHit.js | 22 +++++++++ 6 files changed, 207 insertions(+), 18 deletions(-) create mode 100644 elasticsearch.yml create mode 100644 src/components/FlightHit.js diff --git a/README.md b/README.md index 82587db..234aa37 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,16 @@ This project was bootstrapped with [Create React App](https://github.com/faceboo ## Run in Dev Env +First to start Elassandra on two nodes: +``` +docker-compose --project-name test -f ./ci/docker-compose.yml up -d --scale node=1 +``` + In the project directory, you can run: ### `npm start` + +And then, in a different terminal: ### `nodemon app.js --config ./nodemon.json` Runs the app in the development mode.
diff --git a/app.js b/app.js index fa13724..d927226 100644 --- a/app.js +++ b/app.js @@ -1,14 +1,66 @@ -var express = require('express'); -var path = require('path'); +const express = require('express'); +const path = require('path'); -var indexRouter = require('./routes/index'); - -var app = express(); +const indexRouter = require('./routes/index'); +const bodyParser = require('body-parser'); +const request = require('request') process.env.NODE_ENV = process.env.NODE_ENV || "development" console.log("env:", process.env.NODE_ENV) - const port = process.env.PORT || 8080 +const elasticsearchUrl = process.env.ELASTICSEARCH_URL || "http://localhost:9200" +// for cors +const clientUrl = process.env.CLIENT_URL || "http://localhost:3000" + +const app = express(); + +/* +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: false })); // for parsing application/x-www-form-urlencoded +*/ +app.use(express.json()); + +app.use(function(req, res, next) { + res.header("Access-Control-Allow-Origin", clientUrl); + res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); + next(); +}); + + +app.use("/flight-search", (req, res) => { + const method = req.method.toLowerCase(); + const body = req.body; + + const headers = { + 'Content-Type': "application/json", + } + const url = `${elasticsearchUrl}${req.originalUrl.replace('/flight-search', "/kibana_sample_data_flights")}` + console.log("method", method) + console.log("url", url) + console.log("body", body) + const options = { + uri: url, + headers, + method: 'POST', + json: body, + }; + + request(options, (esError, esRes, esResBody) => { + + if (esError) { + console.error("***error:***") + console.log(esError) + return next(esError); + } else { + console.log(esRes.statusCode) // 200 + console.log(esResBody) // 200 + + return res.send(esResBody); + } + }) +}) + + app.use(express.static(path.join(__dirname, 'build'))); @@ -17,6 +69,10 @@ app.get('/ping', function (req, res) { }); app.use('/', indexRouter); +app.use('*', (req, res, next) => { + console.error("Missed our routes, try again") + next(new Error("This should be a 404")) +}); // error handler app.use(function(err, req, res, next) { diff --git a/elasticsearch.yml b/elasticsearch.yml new file mode 100644 index 0000000..212e983 --- /dev/null +++ b/elasticsearch.yml @@ -0,0 +1,92 @@ +# ======================== Elasticsearch Configuration ========================= +# +# NOTE: Elasticsearch comes with reasonable defaults for most settings. +# Before you set out to tweak and tune the configuration, make sure you +# understand what are you trying to accomplish and the consequences. +# +# The primary way of configuring a node is via this file. This template lists +# the most important settings you may want to configure for a production cluster. +# +# Please consult the documentation for further information on configuration options: +# https://www.elastic.co/guide/en/elasticsearch/reference/index.html +# +# ---------------------------------- Cluster ----------------------------------- +# +# Use a descriptive name for your cluster: +# +#cluster.name: my-application +# +# ------------------------------------ Node ------------------------------------ +# +# Use a descriptive name for the node: +# +#node.name: node-1 +# +# Add custom attributes to the node: +# +#node.attr.rack: r1 +# +# ----------------------------------- Paths ------------------------------------ +# +# Path to directory where to store the data (separate multiple locations by comma): +# +#path.data: /path/to/data +# +# Path to log files: +# +#path.logs: /path/to/logs +# +# ----------------------------------- Memory ----------------------------------- +# +# Lock the memory on startup: +# +#bootstrap.memory_lock: true +# +# Make sure that the heap size is set to about half the memory available +# on the system and that the owner of the process is allowed to use this +# limit. +# +# Elasticsearch performs poorly when the system is swapping the memory. +# +# ---------------------------------- Network ----------------------------------- +# +# Set the bind address to a specific IP (IPv4 or IPv6): +# +#network.host: 192.168.0.1 +# +# Set a custom port for HTTP: +# +#http.port: 9200 +http.cors.enabled : true +http.cors.allow-origin : "*" +http.cors.allow-methods : OPTIONS, HEAD, GET, POST, PUT, DELETE +http.cors.allow-headers : X-Requested-With,X-Auth-Token,Content-Type, Content-Length + +# For more information, consult the network module documentation. +# +# --------------------------------- Discovery ---------------------------------- +# +# Pass an initial list of hosts to perform discovery when new node is started: +# The default list of hosts is ["127.0.0.1", "[::1]"] +# +#discovery.zen.ping.unicast.hosts: ["host1", "host2"] +# +# Prevent the "split brain" by configuring the majority of nodes (total number of master-eligible nodes / 2 + 1): +# +#discovery.zen.minimum_master_nodes: 3 +# +# For more information, consult the zen discovery module documentation. +# +# ---------------------------------- Gateway ----------------------------------- +# +# Block initial recovery after a full cluster restart until N nodes are started: +# +#gateway.recover_after_nodes: 3 +# +# For more information, consult the gateway module documentation. +# +# ---------------------------------- Various ----------------------------------- +# +# Require explicit names when deleting indices: +# +#action.destructive_requires_name: true diff --git a/package.json b/package.json index 791d5b2..d696942 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-scripts": "3.4.1", + "request": "^2.88.2", "searchkit": "^2.4.1-alpha.4" }, "scripts": { diff --git a/src/App.js b/src/App.js index 28c707c..128e01b 100644 --- a/src/App.js +++ b/src/App.js @@ -15,7 +15,7 @@ import { NoHits, HitsStats, SearchkitComponent, - MovieHitsGridItem, + //MovieHitsGridItem, SelectedFilters, MenuFilter, HierarchicalMenuFilter, @@ -24,8 +24,9 @@ import { } from "searchkit"; import './App.css'; -const searchkit = new SearchkitManager("http://demo.searchkit.co/api/movies/") +import FlightHit from './components/FlightHit.js'; +const searchkit = new SearchkitManager("http://localhost:8080/flight-search") function App() { return ( @@ -35,20 +36,30 @@ function App() { + prefixQueryFields={["Carrier^3", "Dest^3", "DestCityName^3", "DestCountry^2", "DestRegion^2", "DestAirportID^5", "DestWeather", "FlightNum^6", "Origin^3", "OriginCityName^3", "OriginCountry^2", "OriginRegion", "OriginAirportID^5", "OriginWeather"]} + /> + fields={["Carrier"]} + title="Carrier" + id="carrier" + /> + size={10} + /> + @@ -63,8 +74,8 @@ function App() { - + diff --git a/src/components/FlightHit.js b/src/components/FlightHit.js new file mode 100644 index 0000000..be709e7 --- /dev/null +++ b/src/components/FlightHit.js @@ -0,0 +1,22 @@ +import { get } from "lodash"; + +import { + Hits, + SearchkitComponent, + HitItemProps +} from "searchkit"; +import React from 'react' + +const FlightHit = (props) => ( +
+
{props.result._source.DestAirportID} -> {props.result._source.OriginAirportID}
+
+ From: +
{props.result._source.Origin}
+ To: +
{props.result._source.Dest}
+
+
+) + +export default FlightHit