diff --git a/.meteor/.finished-upgraders b/.meteor/.finished-upgraders index 2a56593d3f..8f397c7dad 100644 --- a/.meteor/.finished-upgraders +++ b/.meteor/.finished-upgraders @@ -16,3 +16,4 @@ notices-for-facebook-graph-api-2 1.4.1-add-shell-server-package 1.4.3-split-account-service-packages 1.5-add-dynamic-import-package +1.7-split-underscore-from-meteor-base diff --git a/.meteor/packages b/.meteor/packages index 1c125ff835..cc6046c204 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -3,10 +3,10 @@ # 'meteor add' and 'meteor remove' will edit this fill for you, # but you can also edit it by hand. -accounts-base@1.3.2 -accounts-github@1.3.0 -accounts-password@1.4.0 -accounts-ui@1.1.9 +accounts-base@1.4.3 +accounts-github@1.4.2 +accounts-password@1.5.1 +accounts-ui@1.3.1 alanning:roles aldeed:autoform aldeed:autoform-bs-button-group-input @@ -22,37 +22,35 @@ arillo:flow-router-helpers benmgreene:moment-range blaze-html-templates@1.0.4 cfs:filesystem -check@1.2.5 +check@1.3.1 dandv:jquery-rateit dburles:collection-helpers deepwell:bootstrap-datepicker2 -dynamic-import -ecmascript@0.8.2 -ejson@1.0.14 +dynamic-import@0.5.0 +ecmascript@0.12.4 +ejson@1.1.0 email@1.2.3 fastclick@1.0.13 fortawesome:fontawesome froatsnook:valid-email -github-config-ui@1.0.0 +github-config-ui@1.0.1 gwendall:autoform-i18n harrison:papa-parse -http@1.2.12 +http@1.4.1 jquery@1.11.10 juliancwirko:s-alert juliancwirko:s-alert-stackslide kadira:blaze-layout kadira:dochead kadira:flow-router -kurounin:pagination-blaze -kurounin:pagination@=1.0.21 -less@2.7.9 -logging@1.1.17 +less@2.8.0 +logging@1.1.20 matb33:collection-hooks -meteor-base@1.1.0 +meteor-base@1.4.0 meteorhacks:subs-manager michalvalasek:autoform-bootstrap-colorpicker -mobile-experience@1.0.4 -mongo@1.2.0 +mobile-experience@1.0.5 +mongo@1.6.0 nimble:restivus@=0.8.11 olragon:uri-js pahans:inline-help @@ -64,35 +62,40 @@ raix:handlebar-helpers raix:rssfeed raix:ui-dropped-event rajit:bootstrap3-datepicker -random@1.0.10 -reactive-dict@1.1.9 +random@1.1.0 +reactive-dict@1.2.1 reactive-var@1.0.11 -reload@1.1.11 +reload@1.2.0 reywood:publish-composite sacha:spin service-configuration@1.0.11 -session@1.1.7 -shell-server@0.2.4 +session@1.2.0 +shell-server@0.4.0 simple:reactive-method softwarerero:accounts-t9n spacebars@1.0.12 spiderable@1.0.14-release-testing.0 -standard-minifier-css@1.3.4 -standard-minifier-js@2.1.1 +standard-minifier-css@1.5.2 +standard-minifier-js@2.4.0 tap:i18n tap:i18n-ui tmeasday:publish-counts todda00:friendly-slugs -tracker@1.1.3 -u2622:persistent-session +tracker@1.2.0 useraccounts:bootstrap useraccounts:core useraccounts:flow-routing vsivsi:file-collection -zimme:active-route +zimme:active-route@2.3.2 aldeed:autoform-select2 natestrauser:select2 meteorhacks:aggregate apinf:api-umbrella apinf:accounts-admin-ui -oauth +cleandersonlobo:mdi-icons +yasaricli:textcounter +oauth@1.2.6 + +underscore@1.0.10 +kurounin:pagination +kurounin:pagination-blaze@=1.0.6 diff --git a/.meteor/release b/.meteor/release index 47c31abcf4..91e05fc15b 100644 --- a/.meteor/release +++ b/.meteor/release @@ -1 +1 @@ -METEOR@1.5.2 +METEOR@1.8.0.2 diff --git a/.meteor/versions b/.meteor/versions index e842ed582c..29faae6cd1 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -1,9 +1,9 @@ -accounts-base@1.3.2 -accounts-github@1.3.0 -accounts-oauth@1.1.15 -accounts-password@1.4.0 -accounts-ui@1.1.9 -accounts-ui-unstyled@1.2.1 +accounts-base@1.4.3 +accounts-github@1.4.2 +accounts-oauth@1.1.16 +accounts-password@1.5.1 +accounts-ui@1.3.1 +accounts-ui-unstyled@1.4.1 alanning:roles@1.2.16 aldeed:autoform@5.8.1 aldeed:autoform-bs-button-group-input@1.0.3 @@ -12,169 +12,174 @@ aldeed:collection2@2.10.0 aldeed:collection2-core@1.2.0 aldeed:schema-deny@1.1.0 aldeed:schema-index@1.1.1 -aldeed:simple-schema@1.5.3 +aldeed:simple-schema@1.5.4 aldeed:template-extension@4.1.0 -allow-deny@1.0.9 +allow-deny@1.1.0 amplify@1.0.0 apinf:accounts-admin-ui@0.3.4 -apinf:accounts-fiware@0.1.1 +apinf:accounts-fiware@0.1.2 apinf:api-umbrella@1.4.1 apinf:autoform-bs-datepicker@1.1.2 apinf:bootstrap@3.3.7 apinf:create-role-if-undefined@0.1.1 apinf:first-admin@0.1.2 -apinf:fiware@0.2.0 +apinf:fiware@0.2.1 apinf:restivus-swagger@0.4.0 aramk:quill@0.1.1 arillo:flow-router-helpers@0.5.2 -autoupdate@1.3.12 -babel-compiler@6.20.0 -babel-runtime@1.0.1 -base64@1.0.10 +autoupdate@1.5.0 +babel-compiler@7.2.4 +babel-runtime@1.3.0 +base64@1.0.11 benmgreene:moment-range@2.10.6 -binary-heap@1.0.10 -blaze@2.3.2 +binary-heap@1.0.11 +blaze@2.3.3 blaze-html-templates@1.1.2 blaze-tools@1.0.10 -boilerplate-generator@1.2.0 -caching-compiler@1.1.9 -caching-html-compiler@1.1.2 -callback-hook@1.0.10 +boilerplate-generator@1.6.0 +caching-compiler@1.2.1 +caching-html-compiler@1.1.3 +callback-hook@1.1.0 cfs:base-package@0.0.30 cfs:filesystem@0.1.2 cfs:http-methods@0.0.32 -cfs:storage-adapter@0.2.3 -check@1.2.5 -coffeescript@1.12.7_1 -coffeescript-compiler@1.12.7_1 +cfs:storage-adapter@0.2.4 +check@1.3.1 +cleandersonlobo:mdi-icons@1.3.0 +coffeescript@1.0.17 dandv:jquery-rateit@1.0.22_2 dburles:collection-helpers@1.1.0 -ddp@1.3.0 -ddp-client@2.1.0 -ddp-common@1.2.9 +ddp@1.4.0 +ddp-client@2.3.3 +ddp-common@1.4.0 ddp-rate-limiter@1.0.7 -ddp-server@2.0.0 +ddp-server@2.2.0 deepwell:bootstrap-datepicker2@1.3.0 deps@1.0.12 -diff-sequence@1.0.7 -dynamic-import@0.1.1 -ecmascript@0.8.2 -ecmascript-runtime@0.4.1 -ecmascript-runtime-client@0.4.3 -ecmascript-runtime-server@0.4.1 -ejson@1.0.14 +diff-sequence@1.1.1 +dynamic-import@0.5.0 +ecmascript@0.12.4 +ecmascript-runtime@0.7.0 +ecmascript-runtime-client@0.8.0 +ecmascript-runtime-server@0.7.1 +ejson@1.1.0 email@1.2.3 -es5-shim@4.6.15 +es5-shim@4.8.0 fastclick@1.0.13 +fetch@0.1.0 fortawesome:fontawesome@4.7.0 froatsnook:valid-email@1.0.0 geojson-utils@1.0.10 -github-config-ui@1.0.0 -github-oauth@1.2.0 +github-config-ui@1.0.1 +github-oauth@1.2.2 gwendall:autoform-i18n@0.1.9_1 handlebars@1.0.7 harrison:papa-parse@1.1.7 hot-code-push@1.0.4 html-tools@1.0.11 htmljs@1.0.11 -http@1.2.12 -id-map@1.0.9 -jquery@1.11.10 +http@1.4.1 +id-map@1.1.0 +inter-process-messaging@0.1.0 +jquery@1.11.11 juliancwirko:s-alert@3.2.0 juliancwirko:s-alert-stackslide@3.1.3 kadira:blaze-layout@2.3.0 kadira:dochead@1.5.0 kadira:flow-router@2.12.1 -kurounin:pagination@1.0.21 -kurounin:pagination-blaze@1.0.2 +kurounin:pagination@1.0.25 +kurounin:pagination-blaze@1.0.6 launch-screen@1.1.1 -less@2.7.9 +less@2.8.0 livedata@1.0.18 -localstorage@1.1.1 -logging@1.1.17 +localstorage@1.2.0 +logging@1.1.20 markdown@1.0.12 matb33:collection-hooks@0.8.4 mdg:validation-error@0.5.1 -meteor@1.7.1 -meteor-base@1.1.0 +meteor@1.9.2 +meteor-base@1.4.0 meteorhacks:aggregate@1.3.0 meteorhacks:collection-utils@1.2.0 meteorhacks:subs-manager@1.6.4 meteorspark:util@0.2.0 michalvalasek:autoform-bootstrap-colorpicker@0.1.0 -minifier-css@1.2.16 -minifier-js@2.1.3 -minimongo@1.3.0 -mobile-experience@1.0.4 +minifier-css@1.4.1 +minifier-js@2.4.0 +minimongo@1.4.5 +mobile-experience@1.0.5 mobile-status-bar@1.0.14 -modules@0.10.0 -modules-runtime@0.8.0 -momentjs:moment@2.18.1 -mongo@1.2.0 -mongo-dev-server@1.0.1 -mongo-id@1.0.6 +modern-browsers@0.1.3 +modules@0.13.0 +modules-runtime@0.10.3 +momentjs:moment@2.24.0 +mongo@1.6.0 +mongo-decimal@0.1.1 +mongo-dev-server@1.1.0 +mongo-id@1.0.7 mongo-livedata@1.0.12 natestrauser:select2@4.0.3 nimble:restivus@0.8.11 npm-bcrypt@0.9.3 -npm-mongo@2.2.30 -oauth@1.1.13 -oauth2@1.1.11 +npm-mongo@3.1.1 +oauth@1.2.6 +oauth2@1.2.1 observe-sequence@1.0.16 olragon:uri-js@1.13.1 -ordered-dict@1.0.9 +ordered-dict@1.1.0 pahans:inline-help@1.0.2 peppelg:bootstrap-3-modal@1.0.4 percolate:migrations@0.9.8 percolate:synced-cron@1.3.2 pfafman:filesaver@1.3.2 -promise@0.9.0 +promise@0.11.2 raix:eventemitter@0.1.3 raix:handlebar-helpers@0.2.5 raix:rssfeed@0.0.5 raix:ui-dropped-event@0.0.7 -rajit:bootstrap3-datepicker@1.7.1 -random@1.0.10 -rate-limit@1.0.8 -reactive-dict@1.1.9 +rajit:bootstrap3-datepicker@1.7.1_1 +random@1.1.0 +rate-limit@1.0.9 +reactive-dict@1.2.1 reactive-var@1.0.11 -reload@1.1.11 -retry@1.0.9 +reload@1.2.0 +retry@1.1.0 reywood:publish-composite@1.5.2 -routepolicy@1.0.12 +routepolicy@1.1.0 sacha:spin@2.3.1 service-configuration@1.0.11 -session@1.1.7 +session@1.2.0 sha@1.0.9 -shell-server@0.2.4 +shell-server@0.4.0 showdown@1.0.8 simple:json-routes@2.1.0 simple:reactive-method@1.0.2 +socket-stream-client@0.2.2 softwarerero:accounts-t9n@1.3.11 spacebars@1.0.15 spacebars-compiler@1.1.3 spiderable@1.0.14-release-testing.0 -srp@1.0.10 -standard-minifier-css@1.3.4 -standard-minifier-js@2.1.1 +srp@1.0.12 +standard-minifier-css@1.5.2 +standard-minifier-js@2.4.0 tap:i18n@1.8.2 tap:i18n-ui@0.8.0 templating@1.3.2 -templating-compiler@1.3.2 +templating-compiler@1.3.3 templating-runtime@1.3.2 templating-tools@1.1.2 tmeasday:publish-counts@0.8.0 todda00:friendly-slugs@0.6.0 -tracker@1.1.3 +tracker@1.2.0 trever:quill@0.0.5 -u2622:persistent-session@0.4.4 ui@1.0.13 underscore@1.0.10 -url@1.1.0 +url@1.2.0 useraccounts:bootstrap@1.14.2 useraccounts:core@1.14.2 useraccounts:flow-routing@1.14.2 -vsivsi:file-collection@1.3.8 -webapp@1.3.18 +vsivsi:file-collection@1.3.5 +webapp@1.7.1 webapp-hashing@1.0.9 +yasaricli:textcounter@0.0.1 zimme:active-route@2.3.2 diff --git a/.scripts/docker_build.sh b/.scripts/docker_build.sh index f87a5c519b..e85d365097 100755 --- a/.scripts/docker_build.sh +++ b/.scripts/docker_build.sh @@ -7,9 +7,10 @@ set -ev +docker build -t apinf/platform:$DOCKER_TAG . + if [ "${TRAVIS_PULL_REQUEST}" = "false" -a "${TRAVIS_REPO_SLUG}" = "apinf/platform" ] then - docker build -t apinf/platform:$DOCKER_TAG . - docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" - docker push apinf/platform:$DOCKER_TAG +docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" +docker push apinf/platform:$DOCKER_TAG fi diff --git a/.travis.yml b/.travis.yml index 585b5a21dc..46b8946df9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,10 @@ -sudo: false - -group: deprecated-2017Q4 +dist: xenial language: node_js node_js: - - '4' - -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-4.8 + - '8' + +addons: chrome: stable branches: @@ -21,41 +14,36 @@ branches: before_cache: - rm -f $HOME/.meteor/log/*.log -cache: - yarn: true - directories: - - $HOME/.meteor - services: - docker + - xvfb before_install: - - free -m - - pwd - ls -la + - sudo apt-get update + - sudo apt-get install g++ build-essential xvfb + # Install meteor locally on CI - if [ ! -e "$HOME/.meteor/meteor" ]; then cat .travis_install_meteor | sed s/--progress-bar/-sL/g | /bin/sh; fi before_script: - - yarn - - yarn run lint +#Previously used yarn, but now after migrating to meteor 1.8, yarn fails to create some binaries. + - meteor npm install + - npm run lint - npm view chimp version - npm view chromedriver version - # Start X Virtual Frame Buffer for headless testing with real browsers - - ./.scripts/start-xvfb.sh - + install: - export PATH="$HOME/.meteor:$PATH" script: # Run meteor and chimp from node.js - - travis_retry yarn test + - travis_retry npm run test # Build docker image - ./.scripts/docker_build.sh env: global: - DISPLAY=:99.0 - - TEST_MODE: "true" - - CXX=g++-4.8 + - TEST_MODE: "true" diff --git a/.travis_install_meteor b/.travis_install_meteor index 255ce7453d..f2cbfd1b75 100644 --- a/.travis_install_meteor +++ b/.travis_install_meteor @@ -30,7 +30,7 @@ run_it () { # ~/.meteor, replacing whatever is already there. (~/.meteor is only a cache of # packages and package metadata; no personal persistent data is stored there.) -RELEASE="1.5.2" +RELEASE="1.8.0.2" # Now, on to the actual installer! diff --git a/Dockerfile b/Dockerfile index b4e21388dd..f4886ccb10 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,7 @@ # A base Docker image for Meteor applications. https://hub.docker.com/r/jshimko/meteor-launchpad/ -FROM jshimko/meteor-launchpad:v1.1.1 - +#FROM jshimko/meteor-launchpad:latest - jessie deps +#FROM abernix/meteord:onbuild - is not starting +FROM pixolution/meteor-launchpad:v2.3.1 +# the version (that bit after :) is dependent somehow on meteor versions. it used to be 1.1.1 but now as we go for Meteor 1.8, let's use latest. +# If you get in trouble with starting Meteor, this might be something to look at MAINTAINER apinf diff --git a/INSTALL.md b/INSTALL.md index 6a320bc813..07179b0084 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -28,15 +28,23 @@ # Installation +## Note on migration +We are in the process of updating MeteorJS version from 1.5.2 to 1.8. If you need to update the installation which is based on Meteor 1.5.2 to version which uses Meteor 1.8, you need to run MongoDB migration. More information here: https://docs.mongodb.com/manual/release-notes/3.6-upgrade-standalone/ + +The issue is that new version of MongoDB which comes with MeteorJS version 1.8 has new database engine; Procedure is to 1) mongo dump 2) upgrade to version with meteor 1.8 3)meteor reset 4) mongo restore + +## Note on different Umbrella versions +We have forked the NREL/api-umbrella: https://github.com/apinf/apinf-umbrella; We have removed MongoDB from the umbrella image. You should deploy MongoDB in another container/machine and configure APInf Umbrella to use that external instance of MongoDB. + ## From Source Code -1. Install [API Umbrella](http://apiumbrella.io/download/) (or follow the [Developer Setup](http://apiumbrella.io/docs/development-setup/)) +1. Clone APInf fork of umbrella: https://github.com/apinf/api-umbrella and follow the instructions in that repo. Easiest way to get started is to follow "With Docker Compose" section below and when you got that working, start exploring options. 2. Install [Meteor.js](https://www.meteor.com/install) 3. Clone [Apinf](https://github.com/apinf/platform) -4. Run `npm install` +4. Run `meteor npm install` - using meteor instead npm makes sure the same npm is used that comes with meteor distribution 5. Type `meteor` in the project directory -## With Docker +## With Docker -OBSOLETED 1. Run API-umbrella container http://api-umbrella.readthedocs.io/en/latest/getting-started.html#running-with-docker 2. Obtaining API Key and Authentication token. You can obtain the *Authentication Token* and *API Key* from the API Umbrella platform by following instructions in the [Getting Started](http://apiumbrella.io/docs/getting-started/) and [API Umbrella Admin API](http://apiumbrella.io/docs/admin-api/) documentation. @@ -52,23 +60,34 @@ Register a new admin account. The first user will become Admin. 3. Fill APInf settings http://YOUR_SITE_DOMAIN/settings ## With Docker Compose +Have a server with minimum of 2 GB ram and 20 GB disk. One core should be ok. Get a FQDN name for server - dont use Amazon AWS as we are using Let's Encrypt and they have blacklisted autogenerated AWS domain names. Or then you have to assign name on your own. + +Make sure that you have github application created for this domain. You need this in step 7. Here is a good read on how-to: https://auth0.com/docs/connections/social/github authorization callback url needs to be like https://YOUR_SITE_DOMAIN:3002 make sure to include the port. + 1. Create "docker-compose.yml" file on your server and copy content from [docker-compose.yml](https://github.com/apinf/platform/blob/develop/docker-compose.yml). -2. In the same folder create file "docker/api-umbrella/config/api-umbrella.yml" based on example "docker/api-umbrella/config/api-umbrella.yml.example". ATTENTION: replace "example.com" on YOUR_SITE_DOMAIN for keys "ssl_cert" and "ssl_cert_key". +2. In the same folder create file "docker/api-umbrella/config/api-umbrella.yml" based on example "docker/api-umbrella/config/api-umbrella.yml.example". ATTENTION: Replace "example.com" on YOUR_SITE_DOMAIN for keys "ssl_cert" and "ssl_cert_key". 3. Create file "docker/env.apinf" based on example "docker/env.apinf.example". 4. Create file "docker/env.ssl" based on example "docker/env.ssl.example". -5. Run ```docker-compose up -d```. The first launch of will be slow because (take couple of minutes) of the DH parameter computation and configure Let's Encrypt certificate. -6. Visit https://YOUR_SITE_DOMAIN:3002/signup/ and fill form for get API Key. -7. Visit https://YOUR_SITE_DOMAIN:3002/admin/ and click on 'My Account' link for find Admin API Token. -8. Visit https://YOUR_SITE_DOMAIN/sign-up and create new account. -9. Fill data in "Project Branding: APInf Configuration Wizard". -10. Fill data in "Settings for API Umbrella: APInf Configuration Wizard". -* Host: "https://YOUR_SITE_DOMAIN:3002" -* API Key: from step #6 -* Auth Token: from step #7 -* Base URL: "https://YOUR_SITE_DOMAIN:3002/api-umbrella/" -* Elasticsearch: "http://elasticsearch.docker:9200" -11. Add API backend https://YOUR_SITE_DOMAIN/api/new - +5. Modify api-umbrella.yml to have github credentials (client_id and client_secret). Github only login is enabled at this time. If you have the skills, by modifying the api-umbrella.yml you can enable other login methods. Make sure also to modify the "initial_superusers" as you need to be able to login as super user. +6. Run ```docker-compose up -d```. The first launch of it will be slow because (take couple of minutes) of the DH parameter computation and configure Let's Encrypt certificate. +6. Visit https://YOUR_SITE_DOMAIN:3002 to verify that proxy is running +8. Visit https://YOUR_SITE_DOMAIN:3002/admin/login and log in. +9. API key and Auth token you can get from umbrella, so login if you have not done so. The "Auth Token" need to come from admin, so on the right hand side pulldown menu (looks like a gear) pick "account or my account", there you can get the "Admin API token" (referred as Auth token later on). To get the API key, you need to go to https://YOUR_SITE_DOMAIN:3002/signup and fill the form. Copy the Auth token and API key. You need those in the next step. +10. Login to apinf platfrom https://YOUR_SITE_DOMAIN. When signing up as 1st user you get admin rights. To define proxy settings: Under your account pulldown menu, choose "proxy", click "add proxy" and fill in the following details: +* name: whatever you like +* description: whatever you like +* type: apiUmbrella +following fields are revealed as you pick the "type": +* url: https://YOUR_SITE_DOMAIN:3002 +* API KEY: - from umbrella, step 9 +* AUTH TOKEN: - from umbrella, step 9 +* ElasticSearch: "http://elasticsearch.docker:9200" +-> hit save. Now you are ready to add your 1st API. +11. Add API backend https://YOUR_SITE_DOMAIN/api/new + +You can use for example http://restcountries.eu/#api-endpoints-name as a test API. Note! It's better to pass the x-api-key as a header than in the URL! That's it. Now you can go to and check the Quick start, watch the video and enjoy! + +A Few random notes: API Key and Auth token need to be from the same user. If you get into trouble, send us an email: info@apinf.io or raise an issue. ## mail The mail object contains a username and password for the Mailgun service. You will need to register with Mailgun. Once registered, you can use your 'sandbox' domain credentials in a development environment or a custom domain in production: diff --git a/README.md b/README.md index 7ea31b78e4..52b9bfbe52 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,18 @@ +# APInf API Management Framework + +[![](https://nexus.lab.fiware.org/repository/raw/public/badges/chapters/api-management.svg)](https://www.fiware.org/developers/catalogue/) +[![License badge](https://img.shields.io/github/license/apinf/platform.svg)](https://opensource.org/licenses/EUPL-1.1) +[![Docker Pulls](https://img.shields.io/docker/pulls/apinf/platform.svg)](https://hub.docker.com/r/apinf/platform/) +[![](https://img.shields.io/badge/tag-fiware-orange.svg?logo=stackoverflow)](http://stackoverflow.com/questions/tagged/fiware) +
+[![Build Status](https://travis-ci.org/apinf/platform.svg?branch=feature%2F631-nightly-deployment)](https://travis-ci.org/apinf/platform) +![Status](https://nexus.lab.fiware.org/static/badges/statuses/apinf.svg) + **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* - - [Build](#build) - - [Docker image](#docker-image) -- [API Umbrella Dashboard](#api-umbrella-dashboard) +- [Docker image](#docker-image) - [Development status](#development-status) - [Automated testing](#testing) - [Nightly build](#nightly-build) @@ -14,28 +22,30 @@ -[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/apinf/platform/develop/LICENSE) [![Docs Status](https://img.shields.io/badge/docs-latest-brightgreen.svg?style=flat)](http://apinf.org/docs/) [![Gitter](https://img.shields.io/badge/GITTER-JOIN_CHAT_%E2%86%92-1dce73.svg)](https://gitter.im/apinf/public) [![Open Development Method badge](https://camo.githubusercontent.com/9065d5a7f38cb53b9934c0f1b15087e177360af6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f446576656c6f706d656e742532304d6574686f642d4f70656e2d626c75652e737667)](https://opendevelopmentmethod.org/) -## Build - -[![Build Status](https://travis-ci.org/apinf/platform.svg?branch=feature%2F631-nightly-deployment)](https://travis-ci.org/apinf/platform) - ## Docker image [![](https://images.microbadger.com/badges/image/apinf/platform.svg)](http://microbadger.com/images/apinf/platform) [![](https://images.microbadger.com/badges/version/apinf/platform.svg)](http://microbadger.com/images/apinf/platform) -# API Umbrella Dashboard -The APInf platform offers a comprehensive tool for API management. Building on [API Umbrella](http://nrel.github.io/api-umbrella/), it provides enhanced user interface features for API managers and consumers alike. +Docker images are hosted in Dockerhub: https://hub.docker.com/r/apinf/platform/tags + +# APInf API management +The APInf platform offers a comprehensive tool for API management. Building on [APInf Umbrella](https://github.com/apinf/api-umbrella), it provides enhanced user interface features for API managers and consumers alike. For API consumers APInf provides simple key management, key usage analytics and API discovery along with API documentation. Managers have simplified workflow for common tasks, such as key management, rate limiting and viewing API usage analytics. +Why to use? If you have APIs and you are looking for additional control on API access, API documentation and analytics in one package, this is for you. + + +| :page_facing_up: [Site](https://apinf.io/) | :mortar_board: [Academy](https://fiware-academy.readthedocs.io/en/latest/data-publication/apinf) | :whale: [Docker Hub](https://hub.docker.com/r/apinf/platform) | :dart: [Roadmap](roadmap.md) | +|---|---|---|---| # Development status [![Community dashboard badge](https://img.shields.io/badge/Community-Dashboard-blue.svg)](https://dashboard.cauldron.io/goto/afe91edf4f1c66a3bcfd3717f12e43c5) -[![Stories in Ready](https://badge.waffle.io/apinf/platform.png?label=ready&title=Ready)](https://waffle.io/apinf/api-umbrella-dashboard) +[![Stories in Ready](https://badge.waffle.io/apinf/platform.png?label=ready&title=Ready)](https://waffle.io/apinf/platform) [![Throughput Graph](https://graphs.waffle.io/apinf/platform/throughput.svg)](https://waffle.io/apinf/platform/metrics) @@ -57,3 +67,9 @@ More about APInf: [apinf.com](https://apinf.com). APInf saas service: [apinf.io](https://apinf.io). +## License + +APInf is licensed under the [EUPL-1.1](LICENSE) License. + +© 2019 APInf Oy + diff --git a/apinf_packages/about/client/about.html b/apinf_packages/about/client/about.html index 41e78231f4..990075f264 100644 --- a/apinf_packages/about/client/about.html +++ b/apinf_packages/about/client/about.html @@ -33,18 +33,13 @@

Apinf
- 0.58.0 + 0.60.0
API Umbrella
- 0.15.0-apinf2.1 -
-
- Version -
-
+ 0.15.0-apinf2.1.1
Branch @@ -70,7 +65,7 @@

{{_ "aboutApinf_copyright" }}

- 2018 Apinf Oy + 2019 Apinf Oy
{{_ "aboutApinf_license" }} @@ -107,14 +102,6 @@

https://github.com/apinf/platform/issues -
- {{_ "aboutApinf_documentation" }} -
-
- - http://apinf.org/docs - -
@@ -126,7 +113,7 @@

{{_ "aboutApinf_createdBy" }}

- + APInf Oy
@@ -134,7 +121,7 @@

{{_ "aboutApinf_contributors" }}
- Jawid Ahmadi, Taija Björklund, Vesa Härkönen, Nazia Hasan, Ville Jyrkkä, Matti Leppänen, Philippe Luickx, Ilari Mikkonen, Jarkko Moilanen, Alapan Mukherjee, Damir Mustafin, Sridevi Nittoor, Illya Nizyev, Yan Nunes, Brylie Christopher Oxley, Sebastian Pancia, Massimo Rangoni, Vinay Sanker, Saransh Dev Singh, Shalva Usubov, Juuso Vallius, Sarala Vanipenta, Cassiano Vellames, Maurício Vieira, Daria Voytova + Jawid Ahmadi, Taija Björklund, Vesa Härkönen, Nazia Hasan, Ville Jyrkkä, Matti Leppänen, Philippe Luickx, Ilari Mikkonen, Jarkko Moilanen, Alapan Mukherjee, Damir Mustafin, Sridevi Nittoor, Illya Nizyev, Yan Nunes, Brylie Christopher Oxley, Sakari Paloviita, Sebastian Pancia, Massimo Rangoni, Vinay Sanker, Saransh Dev Singh, Shalva Usubov, Juuso Vallius, Sarala Vanipenta, Cassiano Vellames, Maurício Vieira, Daria Voytova, Vikram Kyama, Sumedh Alshi
{{_ "aboutApinf_openSource" }} @@ -171,11 +158,6 @@

dc.js -
  • - - Intro.js - -
  • Lodash diff --git a/apinf_packages/about/client/about.js b/apinf_packages/about/client/about.js index fc2f16f0d6..2b41a71a23 100644 --- a/apinf_packages/about/client/about.js +++ b/apinf_packages/about/client/about.js @@ -4,7 +4,6 @@ import { Template } from 'meteor/templating'; Template.aboutApinf.onRendered(() => { Meteor.call('fetchVersionData', (error, result) => { - $('#show_version').text(result.version); $('#show_branch').text(result.branch); $('#show_commit').text(result.commit); $('#show_tag').text(result.tag); diff --git a/apinf_packages/analytics/server/methods.js b/apinf_packages/analytics/server/methods.js index 34cadeb659..b79777cecf 100644 --- a/apinf_packages/analytics/server/methods.js +++ b/apinf_packages/analytics/server/methods.js @@ -18,13 +18,14 @@ import _ from 'lodash'; import { calculateTrend } from '/apinf_packages/dashboard/lib/trend_helpers'; Meteor.methods({ - timelineChartData (filter) { + // Made all functions in async - await mode for intended data - Sumedh + async timelineChartData (filter) { check(filter, Object); const requestPathsData = {}; // Get list of all requested path of particular Proxy Backend - const allPathsMatrix = AnalyticsData.find( + const allPathsMatrix = await AnalyticsData.find( { proxyBackendId: filter.proxyBackendId, date: { $gte: filter.fromDate, $lt: filter.toDate }, }).map(data => { @@ -42,7 +43,7 @@ Meteor.methods({ // Keep only unique paths const uniquePathsList = [...new Set(allPathsList)]; - AnalyticsData.aggregate( + await AnalyticsData.aggregate( [ { $match: { @@ -93,13 +94,13 @@ Meteor.methods({ return { allRequestPaths: uniquePathsList, requestPathsData }; }, - errorsStatisticsData (filter) { + async errorsStatisticsData (filter) { check(filter, Object); let errors = []; // Fetch all data for Errors table - AnalyticsData.find( + await AnalyticsData.find( { date: { $gte: filter.fromDate, $lt: filter.toDate }, proxyBackendId: filter.proxyBackendId, errors: { $ne: [] } }, @@ -111,7 +112,7 @@ Meteor.methods({ return errors; }, - summaryStatisticNumber (filter, proxyBackendIds) { + async summaryStatisticNumber (filter, proxyBackendIds) { check(filter, Object); check(proxyBackendIds, Array); @@ -123,7 +124,7 @@ Meteor.methods({ const requestPathsData = {}; - AnalyticsData.aggregate( + const summaryAggregateData = await AnalyticsData.aggregate( [ { $match: matchQuery, @@ -148,12 +149,15 @@ Meteor.methods({ }, }, ] - ).forEach(dataset => { + ).toArray(); + // Removed async - await from 'forEach' below and made the 'forEach' itself to await - Sumedh + await summaryAggregateData.forEach(dataset => { // Expend query matchQuery.prefix = dataset._id; matchQuery.requestNumber = { $ne: 0 }; // Get the number of date when requests were no 0 + // using async - await due to breaking changes in meteor 1.5-1.8 update const existedValuesCount = AnalyticsData.find(matchQuery).count(); // Calculate average (mean) value of Response time and Uniques users during period @@ -175,10 +179,9 @@ Meteor.methods({ Object.assign(requestPathsData[dataset._id], dataset); }); - return requestPathsData; }, - statusCodesData (filter) { + async statusCodesData (filter) { check(filter, Object); // Create query to $match @@ -196,7 +199,7 @@ Meteor.methods({ const requestPathsData = {}; - AnalyticsData.aggregate( + await AnalyticsData.aggregate( [ { $match: matchQuery, @@ -222,7 +225,7 @@ Meteor.methods({ return requestPathsData; }, - overviewChartsData (filter) { + async overviewChartsData (filter) { // Return aggregated data for overview charts check(filter, Object); @@ -240,7 +243,7 @@ Meteor.methods({ const requestPathsData = {}; - AnalyticsData.aggregate( + await AnalyticsData.aggregate( [ { $match: matchQuery, @@ -267,16 +270,15 @@ Meteor.methods({ ).forEach(dataset => { requestPathsData[dataset._id] = dataset; }); - return requestPathsData; }, - totalNumberRequestsAndTrend (filter, proxyBackendIds) { + async totalNumberRequestsAndTrend (filter, proxyBackendIds) { check(filter, Object); check(proxyBackendIds, Array); // Get data for Current period const currentPeriodResponse = - Meteor.call('summaryStatisticNumber', filter, proxyBackendIds); + await Meteor.call('summaryStatisticNumber', filter, proxyBackendIds); // Create date range filter for Previous period const previousPeriodFilter = { @@ -286,12 +288,12 @@ Meteor.methods({ // Get data for Previous period const previousPeriodResponse = - Meteor.call('summaryStatisticNumber', previousPeriodFilter, proxyBackendIds); + await Meteor.call('summaryStatisticNumber', previousPeriodFilter, proxyBackendIds); const response = []; // Compare the current and previous periods data - _.mapKeys(currentPeriodResponse, (dataset, path) => { + await _.mapKeys(currentPeriodResponse, (dataset, path) => { const proxyBackend = ProxyBackends.findOne({ 'apiUmbrella.url_matches.frontend_prefix': dataset.prefix, }); @@ -301,20 +303,19 @@ Meteor.methods({ dataset.apiName = proxyBackend.apiName(); dataset.apiSlug = proxyBackend.apiSlug(); dataset.apiId = proxyBackend.apiId; - } - // Create a comparison data - const previousPeriodData = previousPeriodResponse[path] || {}; - dataset.compareRequests = - calculateTrend(previousPeriodData.requestNumber, dataset.requestNumber); - dataset.compareResponse = - calculateTrend(previousPeriodData.medianResponseTime, dataset.medianResponseTime); - dataset.compareUsers = - calculateTrend(previousPeriodData.avgUniqueUsers, dataset.avgUniqueUsers); + // Create a comparison data + const previousPeriodData = previousPeriodResponse[path] || {}; + dataset.compareRequests = + calculateTrend(previousPeriodData.requestNumber, dataset.requestNumber); + dataset.compareResponse = + calculateTrend(previousPeriodData.medianResponseTime, dataset.medianResponseTime); + dataset.compareUsers = + calculateTrend(previousPeriodData.avgUniqueUsers, dataset.avgUniqueUsers); - response.push(dataset); + response.push(dataset); + } }); - return response; }, }); diff --git a/apinf_packages/analytics/server/startup.js b/apinf_packages/analytics/server/startup.js index 547d208c20..5aec70a7d1 100644 --- a/apinf_packages/analytics/server/startup.js +++ b/apinf_packages/analytics/server/startup.js @@ -60,6 +60,6 @@ Meteor.startup(() => { if (proxies.length > 0 && proxyBackendsCount > 0) { // Restart all cron tasks are related to fetching Analytics Data - // Meteor.call('restartAnalyticsDataCron'); + Meteor.call('restartAnalyticsDataCron'); } }); diff --git a/apinf_packages/analytics/server/store.js b/apinf_packages/analytics/server/store.js index de024dc497..21faacf90b 100644 --- a/apinf_packages/analytics/server/store.js +++ b/apinf_packages/analytics/server/store.js @@ -164,7 +164,7 @@ Meteor.methods({ requestPath: dataset.key, // Get value of request code status status: status.key, - // Get value of request number + // Get value of request count calls: status.doc_count, }); }); @@ -215,9 +215,4 @@ Meteor.methods({ // Return "date" value return analytics && analytics.date; }, - getServerTimeZone () { - const serverTime = new Date(); - const timeZone = serverTime.toString().substring(25); - return timeZone; - }, }); diff --git a/apinf_packages/api_catalog/client/api_catalog.html b/apinf_packages/api_catalog/client/api_catalog.html index 173c109149..2aeb34b332 100644 --- a/apinf_packages/api_catalog/client/api_catalog.html +++ b/apinf_packages/api_catalog/client/api_catalog.html @@ -4,41 +4,49 @@ https://joinup.ec.europa.eu/community/eupl/og_page/european-union-public-licence-eupl-v11 --> diff --git a/apinf_packages/api_catalog/client/api_catalog.js b/apinf_packages/api_catalog/client/api_catalog.js index 9ac4971667..e677a2493c 100644 --- a/apinf_packages/api_catalog/client/api_catalog.js +++ b/apinf_packages/api_catalog/client/api_catalog.js @@ -20,6 +20,7 @@ import Apis from '/apinf_packages/apis/collection'; import ApiBookmarks from '/apinf_packages/bookmarks/collection'; import ApiDocs from '/apinf_packages/api_docs/collection'; import Branding from '/apinf_packages/branding/collection'; +import Settings from '/apinf_packages/settings/collection'; import 'locale-compare-polyfill'; @@ -77,7 +78,7 @@ Template.apiCatalog.onCreated(function () { // Set initial settings of pagination instance.pagination = new Meteor.Pagination(Apis, { // Count of cards in catalog - perPage: 24, + perPage: 12, // Set sort by name on default sort: defaultSort, filters, @@ -283,6 +284,33 @@ Template.apiCatalog.helpers({ apisCount () { return Template.instance().pagination.totalItems(); }, + userCanAddApi () { + // Get settigns document + const settings = Settings.findOne(); + + if (settings) { + // Get access setting value + // If access field doesn't exist, these is false. Allow users to add an API on default + const onlyAdminsCanAddApis = settings.access ? settings.access.onlyAdminsCanAddApis : false; + + // Allow user to add an API because not only for admin + if (!onlyAdminsCanAddApis) { + return true; + } + + // Otherwise check of user role + // Get current user Id + const userId = Meteor.userId(); + + // Check if current user is admin + const userIsAdmin = Roles.userIsInRole(userId, ['admin']); + + return userIsAdmin; + } + // Return true because no settings are set + // By default allowing all user to add an API + return true; + }, }); Template.apiCatalog.events({ diff --git a/apinf_packages/api_catalog/client/api_catalog.less b/apinf_packages/api_catalog/client/api_catalog.less index c41af31521..d69d624793 100644 --- a/apinf_packages/api_catalog/client/api_catalog.less +++ b/apinf_packages/api_catalog/client/api_catalog.less @@ -30,11 +30,28 @@ https://joinup.ec.europa.eu/community/eupl/og_page/european-union-public-licence border: 0; } -.col-grid{ - margin-bottom: 1.87em; -} - .navbar-right > a.rss-feed { font-size: 38px; padding: 0px; } + +.pagination-container { + margin-top: 2em; +} + +@media (max-width: 767px) { + .catalog-header { + margin-bottom: 10px !important; + } + .catalog-header-search { + display: none !important; + } + #catalog-toolbar { + padding-left: 15px !important; + } +} + +ul.catalog-header > li { + padding-right: 0px; + padding-left: 0px; +} diff --git a/apinf_packages/api_catalog/client/lib/router.js b/apinf_packages/api_catalog/client/lib/router.js index 36cbb5fcdb..f30e83b7aa 100644 --- a/apinf_packages/api_catalog/client/lib/router.js +++ b/apinf_packages/api_catalog/client/lib/router.js @@ -14,10 +14,10 @@ FlowRouter.route('/apis', { // Get query parameters for Catalog page on Enter triggersEnter: [function (context) { if (!context.queryParams.sortBy) { - context.queryParams.sortBy = 'name-asc'; + context.queryParams.sortBy = 'bookmarkCount'; } if (!context.queryParams.viewMode) { - context.queryParams.viewMode = 'grid'; + context.queryParams.viewMode = 'table'; } if (!context.queryParams.filterBy && Meteor.userId()) { context.queryParams.filterBy = 'all'; @@ -47,3 +47,4 @@ FlowRouter.route('/myapis', { BlazeLayout.render('masterLayout', { bar: 'navbar', main: 'apiCatalog' }); }, }); + diff --git a/apinf_packages/api_catalog/client/table/table.html b/apinf_packages/api_catalog/client/table/table.html index f6805ec0c5..9850e79a23 100644 --- a/apinf_packages/api_catalog/client/table/table.html +++ b/apinf_packages/api_catalog/client/table/table.html @@ -1,72 +1,51 @@ - diff --git a/apinf_packages/api_keys/client/api_key.html b/apinf_packages/api_keys/client/api_key.html index bd901b61a6..20805686c4 100644 --- a/apinf_packages/api_keys/client/api_key.html +++ b/apinf_packages/api_keys/client/api_key.html @@ -1,33 +1,29 @@ + +