Browse Source

Merge branch 'master' of https://github.com/PeliasIntersections/api into pelias-intersections

pull/1058/head
Alex Loyko 8 years ago
parent
commit
a35f809fbf
  1. 12
      .circleci/config.yml
  2. 30
      .circleci/docker.sh
  3. 51
      .dockerignore
  4. 15
      Dockerfile
  5. 5
      app.js
  6. 10
      package.json
  7. 18
      pelias.json.docker
  8. 12
      routes/default.js
  9. 15
      sanitizer/_request_language.js
  10. 8
      sanitizer/_synthesize_analysis.js
  11. 3
      sanitizer/autocomplete.js
  12. 3
      sanitizer/nearby.js
  13. 3
      sanitizer/place.js
  14. 3
      sanitizer/reverse.js
  15. 3
      sanitizer/search.js
  16. 3
      sanitizer/structured_geocoding.js
  17. 1
      test/unit/run.js
  18. 35
      test/unit/sanitizer/_request_language.js
  19. 30
      test/unit/sanitizer/_synthesize_analysis.js
  20. 11
      test/unit/sanitizer/autocomplete.js
  21. 11
      test/unit/sanitizer/nearby.js
  22. 11
      test/unit/sanitizer/place.js
  23. 11
      test/unit/sanitizer/reverse.js
  24. 11
      test/unit/sanitizer/search.js
  25. 11
      test/unit/sanitizer/structured_geocoding.js

12
.circleci/config.yml

@ -0,0 +1,12 @@
version: 2
jobs:
build:
working_directory: /app
docker:
- image: docker:17.05.0-ce-git
steps:
- checkout
- setup_remote_docker
- run:
name: Build and push image to Docker Hub
command: sh .circleci/docker.sh

30
.circleci/docker.sh

@ -0,0 +1,30 @@
#!/bin/bash
set -u
# collect params from ENV vars
DATE=`date +%Y-%m-%d`
DOCKER_REPOSITORY="pelias"
DOCKER_PROJECT="${DOCKER_REPOSITORY}/${CIRCLE_PROJECT_REPONAME}"
# the name of the image that represents the "branch", that is an image that will be updated over time with the git branch
# the production branch is changed to "latest", otherwise the git branch becomes the name of the version
if [[ "${CIRCLE_BRANCH}" == "production" ]]; then
DOCKER_BRANCH_IMAGE_VERSION="latest"
else
DOCKER_BRANCH_IMAGE_VERSION="${CIRCLE_BRANCH}"
fi
DOCKER_BRANCH_IMAGE_NAME="${DOCKER_PROJECT}:${DOCKER_BRANCH_IMAGE_VERSION}"
# the name of the image that represents the "tag", that is an image that is named with the date and git commit and will never be changed
DOCKER_TAG_IMAGE_VERSION="${CIRCLE_BRANCH}-${DATE}-${CIRCLE_SHA1}"
DOCKER_TAG_IMAGE_NAME="${DOCKER_PROJECT}:${DOCKER_TAG_IMAGE_VERSION}"
# build image and login to docker hub
docker build -t $DOCKER_PROJECT .
docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
# copy the image to each of the two tags, and push
docker tag $DOCKER_PROJECT $DOCKER_BRANCH_IMAGE_NAME
docker tag $DOCKER_PROJECT $DOCKER_TAG_IMAGE_NAME
docker push $DOCKER_BRANCH_IMAGE_NAME
docker push $DOCKER_TAG_IMAGE_NAME

51
.dockerignore

@ -0,0 +1,51 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# Git
.git

15
Dockerfile

@ -1,8 +1,10 @@
FROM node:4.6.0 # base image
MAINTAINER Pelias FROM pelias/libpostal_baseimage
# maintainer information
LABEL maintainer="pelias@mapzen.com"
EXPOSE 3100 EXPOSE 3100
LABEL io.openshift.expose-services 3100:http
# Where the app is built and run inside the docker fs # Where the app is built and run inside the docker fs
ENV WORK=/opt/pelias ENV WORK=/opt/pelias
@ -11,18 +13,17 @@ ENV WORK=/opt/pelias
ENV HOME=/opt/pelias ENV HOME=/opt/pelias
WORKDIR ${WORK} WORKDIR ${WORK}
ADD . ${WORK} COPY . ${WORK}
# Build and set permissions for arbitrary non-root user # Build and set permissions for arbitrary non-root user
RUN npm install && \ RUN npm install && \
npm test && \ npm test && \
chmod -R a+rwX . chmod -R a+rwX .
ADD pelias.json.docker pelias.json
# Don't run as root, because there's no reason to (https://docs.docker.com/engine/articles/dockerfile_best-practices/#user). # Don't run as root, because there's no reason to (https://docs.docker.com/engine/articles/dockerfile_best-practices/#user).
# This also reveals permission problems on local Docker. # This also reveals permission problems on local Docker.
RUN chown -R 9999:9999 ${WORK} RUN chown -R 9999:9999 ${WORK}
USER 9999 USER 9999
CMD npm start # start service
CMD [ "npm", "start" ]

5
app.js

@ -1,4 +1,3 @@
var app = require('express')(); var app = require('express')();
var peliasConfig = require( 'pelias-config' ).generate(require('./schema')); var peliasConfig = require( 'pelias-config' ).generate(require('./schema'));
@ -16,6 +15,10 @@ app.use( require('./middleware/jsonp') );
/** ----------------------- routes ----------------------- **/ /** ----------------------- routes ----------------------- **/
var defaultRoutes = require('./routes/default');
defaultRoutes.addRoutes(app);
var v1 = require('./routes/v1'); var v1 = require('./routes/v1');
v1.addRoutes(app, peliasConfig); v1.addRoutes(app, peliasConfig);

10
package.json

@ -59,10 +59,10 @@
"pelias-labels": "1.6.0", "pelias-labels": "1.6.0",
"pelias-logger": "0.2.0", "pelias-logger": "0.2.0",
"pelias-microservice-wrapper": "1.2.0", "pelias-microservice-wrapper": "1.2.0",
"pelias-model": "5.0.0", "pelias-model": "5.0.1",
"pelias-query": "9.0.0", "pelias-query": "9.1.0",
"pelias-sorting": "1.0.1", "pelias-sorting": "1.0.1",
"pelias-text-analyzer": "1.9.0", "pelias-text-analyzer": "1.9.1",
"predicates": "^1.0.1", "predicates": "^1.0.1",
"retry": "^0.10.1", "retry": "^0.10.1",
"stats-lite": "^2.0.4", "stats-lite": "^2.0.4",
@ -78,11 +78,11 @@
"pelias-mock-logger": "1.1.1", "pelias-mock-logger": "1.1.1",
"precommit-hook": "^3.0.0", "precommit-hook": "^3.0.0",
"proxyquire": "^1.7.10", "proxyquire": "^1.7.10",
"semantic-release": "^6.3.2", "semantic-release": "^7.0.1",
"source-map": "^0.5.6", "source-map": "^0.5.6",
"tap-dot": "1.0.5", "tap-dot": "1.0.5",
"tape": "^4.5.1", "tape": "^4.5.1",
"tmp": "0.0.31", "tmp": "0.0.33",
"uglify-js": "^3.0.4" "uglify-js": "^3.0.4"
}, },
"pre-commit": [ "pre-commit": [

18
pelias.json.docker

@ -1,18 +0,0 @@
{
"esclient": {
"hosts": [
{
"env": "production",
"protocol": "http",
"host": "pelias-data-container",
"port": 9200
},
{
"env": "production",
"protocol": "http",
"host": "pelias-data-container",
"port": 9300
}
]
}
}

12
routes/default.js

@ -0,0 +1,12 @@
// set up routes that are outside any particular API version
function addRoutes(app) {
function redirectToV1(req, res, next) {
res.redirect(301, '/v1');
}
// default root URL traffic to V1 root
// which has a link to the readme and other helpful info
app.get('/', redirectToV1);
}
module.exports.addRoutes = addRoutes;

15
sanitizer/_request_language.js

@ -0,0 +1,15 @@
// this sanitizer exists solely to allow `lang` as a request parameter
function _sanitize( raw, clean ){
// error & warning messages
return { errors: [], warnings: [] };
}
function _expected(){
return [{ 'name': 'lang' }];
}
// export function
module.exports = () => ({
sanitize: _sanitize,
expected: _expected
});

8
sanitizer/_synthesize_analysis.js

@ -27,12 +27,8 @@ function isPostalCodeOnly(parsed_text) {
// so because we're treating the entire field as a street address, it's safe // so because we're treating the entire field as a street address, it's safe
// to assume that an identified postcode is actually a house number. // to assume that an identified postcode is actually a house number.
function getHouseNumberField(analyzed_address) { function getHouseNumberField(analyzed_address) {
for (var field of ['number', 'postalcode']) { // return the first field available in the libpostal response, undefined if none
if (analyzed_address.hasOwnProperty(field)) { return _.find(['number', 'postalcode'], _.partial(_.has, analyzed_address));
return field;
}
}
} }
function _sanitize( raw, clean ){ function _sanitize( raw, clean ){

3
sanitizer/autocomplete.js

@ -17,7 +17,8 @@ module.exports.middleware = (_api_pelias_config) => {
location_bias: require('../sanitizer/_location_bias')(_api_pelias_config.defaultParameters), location_bias: require('../sanitizer/_location_bias')(_api_pelias_config.defaultParameters),
geo_autocomplete: require('../sanitizer/_geo_autocomplete')(), geo_autocomplete: require('../sanitizer/_geo_autocomplete')(),
boundary_country: require('../sanitizer/_boundary_country')(), boundary_country: require('../sanitizer/_boundary_country')(),
categories: require('../sanitizer/_categories')() categories: require('../sanitizer/_categories')(),
request_language: require('../sanitizer/_request_language')()
}; };
return ( req, res, next ) => { return ( req, res, next ) => {

3
sanitizer/nearby.js

@ -15,7 +15,8 @@ var sanitizers = {
private: require('../sanitizer/_flag_bool')('private', false), private: require('../sanitizer/_flag_bool')('private', false),
geo_reverse: require('../sanitizer/_geo_reverse')(), geo_reverse: require('../sanitizer/_geo_reverse')(),
boundary_country: require('../sanitizer/_boundary_country')(), boundary_country: require('../sanitizer/_boundary_country')(),
categories: require('../sanitizer/_categories')() categories: require('../sanitizer/_categories')(),
request_language: require('../sanitizer/_request_language')()
}; };
// middleware // middleware

3
sanitizer/place.js

@ -4,7 +4,8 @@ var sanitizeAll = require('../sanitizer/sanitizeAll'),
singleScalarParameters: require('../sanitizer/_single_scalar_parameters')(), singleScalarParameters: require('../sanitizer/_single_scalar_parameters')(),
debug: require('../sanitizer/_debug')(), debug: require('../sanitizer/_debug')(),
ids: require('../sanitizer/_ids')(), ids: require('../sanitizer/_ids')(),
private: require('../sanitizer/_flag_bool')('private', false) private: require('../sanitizer/_flag_bool')('private', false),
request_language: require('../sanitizer/_request_language')()
}; };
// middleware // middleware

3
sanitizer/reverse.js

@ -13,7 +13,8 @@ var sanitizeAll = require('../sanitizer/sanitizeAll'),
size: require('../sanitizer/_size')(/* use defaults*/), size: require('../sanitizer/_size')(/* use defaults*/),
private: require('../sanitizer/_flag_bool')('private', false), private: require('../sanitizer/_flag_bool')('private', false),
geo_reverse: require('../sanitizer/_geo_reverse')(), geo_reverse: require('../sanitizer/_geo_reverse')(),
boundary_country: require('../sanitizer/_boundary_country')() boundary_country: require('../sanitizer/_boundary_country')(),
request_language: require('../sanitizer/_request_language')()
}; };
// middleware // middleware

3
sanitizer/search.js

@ -18,7 +18,8 @@ module.exports.middleware = (_api_pelias_config) => {
boundary_country: require('../sanitizer/_boundary_country')(), boundary_country: require('../sanitizer/_boundary_country')(),
categories: require('../sanitizer/_categories')(), categories: require('../sanitizer/_categories')(),
// this can go away once geonames has been abrogated // this can go away once geonames has been abrogated
geonames_warnings: require('../sanitizer/_geonames_warnings')() geonames_warnings: require('../sanitizer/_geonames_warnings')(),
request_language: require('../sanitizer/_request_language')()
}; };
return ( req, res, next ) => { return ( req, res, next ) => {

3
sanitizer/structured_geocoding.js

@ -19,7 +19,8 @@ module.exports.middleware = (_api_pelias_config) => {
location_bias: require('../sanitizer/_location_bias')(_api_pelias_config.defaultParameters), location_bias: require('../sanitizer/_location_bias')(_api_pelias_config.defaultParameters),
geo_search: require('../sanitizer/_geo_search')(), geo_search: require('../sanitizer/_geo_search')(),
boundary_country: require('../sanitizer/_boundary_country')(), boundary_country: require('../sanitizer/_boundary_country')(),
categories: require('../sanitizer/_categories')() categories: require('../sanitizer/_categories')(),
request_language: require('../sanitizer/_request_language')()
}; };
return ( req, res, next ) => { return ( req, res, next ) => {

1
test/unit/run.js

@ -76,6 +76,7 @@ var tests = [
require('./sanitizer/_layers'), require('./sanitizer/_layers'),
require('./sanitizer/_location_bias'), require('./sanitizer/_location_bias'),
require('./sanitizer/_city_name_standardizer'), require('./sanitizer/_city_name_standardizer'),
require('./sanitizer/_request_language'),
require('./sanitizer/_single_scalar_parameters'), require('./sanitizer/_single_scalar_parameters'),
require('./sanitizer/_size'), require('./sanitizer/_size'),
require('./sanitizer/_sources'), require('./sanitizer/_sources'),

35
test/unit/sanitizer/_request_language.js

@ -0,0 +1,35 @@
const sanitizer = require('../../../sanitizer/_request_language')();
module.exports.tests = {};
module.exports.tests.do_nothing = (test, common) => {
test('sanitize should return empty warnings/erros', t => {
const messages = sanitizer.sanitize();
t.deepEquals(messages.errors, [], 'no errors');
t.deepEquals(messages.warnings, [], 'no warnings');
t.end();
});
};
module.exports.tests.expected = (test, common) => {
test('expected should contain only \'lang\'', t => {
const expected = sanitizer.expected();
t.deepEquals(expected, [{'name': 'lang'}]);
t.end();
});
};
module.exports.all = (tape, common) => {
function test(name, testFunction) {
return tape(`SANITIZE _request_language: ${name}`, testFunction);
}
for( const testCase in module.exports.tests ){
module.exports.tests[testCase](test, common);
}
};

30
test/unit/sanitizer/_synthesize_analysis.js

@ -233,6 +233,36 @@ module.exports.tests.text_parser = function(test, common) {
}); });
test('text_analyzer returning undefined on address resolution should treat as if no house number field was found', t => {
var sanitizer = proxyquire('../../../sanitizer/_synthesize_analysis', {
'pelias-text-analyzer': { parse: function(query) {
t.equals(query, 'Street Value');
return undefined;
}
}});
const raw = {
address: 'Street Value'
};
const clean = {};
const expected_clean = {
parsed_text: {
street: 'Street Value'
}
};
const messages = sanitizer().sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
t.deepEquals(messages.warnings, [], 'no warnings');
t.end();
});
test('return an array of expected parameters in object form for validation', function (t) { test('return an array of expected parameters in object form for validation', function (t) {
const sanitizer = require('../../../sanitizer/_synthesize_analysis'); const sanitizer = require('../../../sanitizer/_synthesize_analysis');
const expected = [ const expected = [

11
test/unit/sanitizer/autocomplete.js

@ -120,6 +120,14 @@ module.exports.tests.sanitizers = function(test, common) {
return { errors: [], warnings: [] }; return { errors: [], warnings: [] };
} }
}; };
},
'../sanitizer/_request_language': () => {
return {
sanitize: () => {
called_sanitizers.push('_request_language');
return { errors: [], warnings: [] };
}
};
} }
}); });
@ -136,7 +144,8 @@ module.exports.tests.sanitizers = function(test, common) {
'_location_bias', '_location_bias',
'_geo_autocomplete', '_geo_autocomplete',
'_boundary_country', '_boundary_country',
'_categories' '_categories',
'_request_language'
]; ];
const req = {}; const req = {};

11
test/unit/sanitizer/nearby.js

@ -109,6 +109,14 @@ module.exports.tests.sanitize = function(test, common) {
return { errors: [], warnings: [] }; return { errors: [], warnings: [] };
} }
}; };
},
'../sanitizer/_request_language': () => {
return {
sanitize: () => {
called_sanitizers.push('_request_language');
return { errors: [], warnings: [] };
}
};
} }
}); });
@ -124,7 +132,8 @@ module.exports.tests.sanitize = function(test, common) {
'_flag_bool', '_flag_bool',
'_geo_reverse', '_geo_reverse',
'_boundary_country', '_boundary_country',
'_categories' '_categories',
'_request_language'
]; ];
const req = {}; const req = {};

11
test/unit/sanitizer/place.js

@ -45,6 +45,14 @@ module.exports.tests.sanitize = function(test, common) {
} else { } else {
throw new Error('incorrect parameters passed to _flag_bool'); throw new Error('incorrect parameters passed to _flag_bool');
} }
},
'../sanitizer/_request_language': () => {
return {
sanitize: () => {
called_sanitizers.push('_request_language');
return { errors: [], warnings: [] };
}
};
} }
}); });
@ -52,7 +60,8 @@ module.exports.tests.sanitize = function(test, common) {
'_single_scalar_parameters', '_single_scalar_parameters',
'_debug', '_debug',
'_ids', '_ids',
'_flag_bool' '_flag_bool',
'_request_language'
]; ];
const req = {}; const req = {};

11
test/unit/sanitizer/reverse.js

@ -101,6 +101,14 @@ module.exports.tests.sanitize = function(test, common) {
return { errors: [], warnings: [] }; return { errors: [], warnings: [] };
} }
}; };
},
'../sanitizer/_request_language': () => {
return {
sanitize: () => {
called_sanitizers.push('_request_language');
return { errors: [], warnings: [] };
}
};
} }
}); });
@ -115,7 +123,8 @@ module.exports.tests.sanitize = function(test, common) {
'_size', '_size',
'_flag_bool', '_flag_bool',
'_geo_reverse', '_geo_reverse',
'_boundary_country' '_boundary_country',
'_request_language'
]; ];
const req = {}; const req = {};

11
test/unit/sanitizer/search.js

@ -133,6 +133,14 @@ module.exports.tests.sanitize = (test, common) => {
} }
} }
}; };
},
'../sanitizer/_request_language': () => {
return {
sanitize: () => {
called_sanitizers.push('_request_language');
return { errors: [], warnings: [] };
}
};
} }
}); });
@ -151,7 +159,8 @@ module.exports.tests.sanitize = (test, common) => {
'_geo_search', '_geo_search',
'_boundary_country', '_boundary_country',
'_categories', '_categories',
'_geonames_warnings' '_geonames_warnings',
'_request_language'
]; ];
const req = {}; const req = {};

11
test/unit/sanitizer/structured_geocoding.js

@ -137,6 +137,14 @@ module.exports.tests.sanitize = function(test, common) {
} }
} }
}; };
},
'../sanitizer/_request_language': () => {
return {
sanitize: () => {
called_sanitizers.push('_request_language');
return { errors: [], warnings: [] };
}
};
} }
}); });
@ -155,7 +163,8 @@ module.exports.tests.sanitize = function(test, common) {
'_location_bias', '_location_bias',
'_geo_search', '_geo_search',
'_boundary_country', '_boundary_country',
'_categories' '_categories',
'_request_language'
]; ];
var req = {}; var req = {};

Loading…
Cancel
Save