{"id":16542299,"url":"https://github.com/estesp/flightassist","last_synced_at":"2025-10-28T15:30:59.354Z","repository":{"id":18875630,"uuid":"78644406","full_name":"estesp/flightassist","owner":"estesp","description":"Node.js example application for demos/comparisons with deployment technologies","archived":false,"fork":false,"pushed_at":"2024-03-28T02:04:29.000Z","size":3549,"stargazers_count":8,"open_issues_count":1,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-04-14T19:37:38.561Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/estesp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-01-11T14:01:30.000Z","updated_at":"2024-05-02T02:26:43.927Z","dependencies_parsed_at":"2024-05-02T02:26:31.581Z","dependency_job_id":"45e68663-e79d-4230-9dc5-a07fb917b33d","html_url":"https://github.com/estesp/flightassist","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/estesp%2Fflightassist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/estesp%2Fflightassist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/estesp%2Fflightassist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/estesp%2Fflightassist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/estesp","download_url":"https://codeload.github.com/estesp/flightassist/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219859376,"owners_count":16556036,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T18:57:09.164Z","updated_at":"2025-10-28T15:30:53.705Z","avatar_url":"https://github.com/estesp.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# flightassist\nFlightassist is a Node.js example application for demonstrating and\ncomparing various application deployment technologies in the IBM Bluemix\npublic cloud.\n\nThe intent for this project, when complete, is that it will be\ndeployable as a Cloud Foundry application, a containerized application\nusing at least one factored-out microservice, and as a set of\nfunctions deployable to OpenWhisk, the IBM Bluemix function-as-a-service\noffering.\n\nSpecifically, a set of trade-offs and comparisons can be made between\nthese deployment models, and this application is a proving ground for\nthose discussions. This will be the basis for the talk given by\nLin Sun and Phil Estes at [IBM Interconnect 2017](https://www.ibm.com/cloud-computing/us/en/interconnect/)\ntitled [Containerize, PaaS, or Go Serverless? A Case Study in\nApplication Deployment Models](https://myibm.ibm.com/events/interconnect/all-sessions/session/4467A).\n\n## Development configuration\n\nThis application relies on four distinct services; two of which are\navailable in the IBM [Bluemix service catalog](https://console.ng.bluemix.net/catalog/):\nthe [Cloudant NoSQL DB](https://console.ng.bluemix.net/catalog/services/cloudant-nosql-db/) and\nThe [Weather Company weather data](https://console.ng.bluemix.net/catalog/services/weather-company-data/) service. You can use the free tier\nvariants of both of these services and connect them to your Bluemix\nhosted CF application.\n\nThe two non-Bluemix services used are API credentials for [TripIt](https://www.tripit.com/developer) and\n[FlightStats](https://developer.flightstats.com/api-docs/).\n\n\u003e Note that the application uses the *Connections* API for FlightStats,\n\u003e which is only available under a 30-day trial license key, or under\n\u003e a commercial premium account with FlightStats.\n\nFor detailed deployment guides for the various application models\nsupported in the **flightassist** code and configuration, see the\n[Deployment Guides section](#deployguides) below.\n\n## Application design/layout\n\nThe \"CF mode\" of the application is as a single Node.js application\non the server, providing multiple HTTP endpoints for data/API access\nfrom a live \"AJAX\"/HTML5 web front-end.\n\nThe application flow starts with an Oauth2-based authentication\nstep against the TripIt API (see the `/authorize` handler). Since we are wanting to query a user's\nset of upcoming trips, the user authorizes our application to their\nTripIt data via this Oauth2 flow.\n\nOn authentication success, the callback URL provided to TripIt will\nstart the query of trip data at our `/flights` endpoint, beginning\nby storing the access tokens in the HTTP session and accessing the\nuser's TripIt profile for basic user details.\n\nAt the end of the `/flights` handling the results page is rendered\nwhich will begin the use of AJAX callbacks into the application,\nwhich will use the stored token data in the session for further\ncalls to TripIt.\n\nThe first callback simply calls `/tripdata` to perform a pull of\nthe user's trip data from TripIt which we will post-process and\ncache into Cloudant. Because of our cache, only flight changes will\ncause us to update, and a timestamp will decrease our round-trips\nto TripIt to only request \"updated since\" content.\n\n\u003e TODO: We do have to add a remove trips sweep on some interval as\n\u003e the TripIt API recommendations note that trip deletion is not\n\u003e provided in the \"updated since\" API flow. Without this, a user\n\u003e might be shown a trip which they have already deleted in TripIt.\n\nOur processing of TripIt data throws away all information except for\n\"air segment\" data, as our application only shows details related to\nflights. This decreases our cacheing and resolution of updates when\nround-tripping to TripIt for any recent updates.\n\nOn the client side, the `trips.js` client script will take the\nresults of the `/tripdata` AJAX call and fill out a results section\nwith either a notification that no upcoming trips were found, or\nthat the next trip is over 24 hours in the future. Our application\nis most useful when a trip is starting soon, as it will update the\nuser about potential flight issues and show alternate connecting\nroutes between their origin and destination airports.\n\nIf the user **does have** an upcoming flight within the next 24 hours\nthose flights will be displayed and a series of AJAX callbacks will\nbegin to gather weather and flight status data for the results.\nWeather data will be cached given our free tier API key will quickly\nexhaust its API limits.\n\nAs results are gathered client-side from the `/weather`, `/conninfo`, and\n`/flightinfo` endpoints, the results display will be updated with\nthis additional information for the user of the application.\n\n### Containerized application model\n\nThe first common step to containerize an existing application is to use\na strategy termed \"lift and shift.\" Just like how it sounds, you simply\ntake the application as-is and place it inside a container image with the\nsame basic application characteristics and requirements. You gain the\nability to now use it in various more complex deployment flows that use\ncontainer images, but other than that you've left the application unchanged.\n\nFor **flightassist**, you can run the containerized version in a local\nenvironment (assuming you have the docker client installed and configured)\nby using the `localctr` Makefile target.\n\n\u003e **Note**: Because you don't have a cloud foundry instance handling environment\n\u003e configuration, similar to running on your local system in development mode\n\u003e you will need to copy the `dot-env` file to `.env` and insert all required\n\u003e API keys and secrets/configuration parameters in this local file. This\n\u003e `.env` file is ignored by `git` in this repo configuration and therefore\n\u003e saves you the embarrassment of checking in a set of secrets/credentials.\n\nA `Makefile` has been created for automating simple `docker build` and `docker run`\nsteps on your local system. Simply use `make localctr` to build and run\nthe image from your local clone of this repo after creating the `.env` file\nand populating it with the required information.\n\nAlternatively, if your local shell is set up and authenticated to the IBM\nBluemix container service, you can use the `make bxdeploy` target. You must have the\nlocal shell configured with `DOCKER_HOST` for this to use the IBM container\nservice as the target Docker engine. See this [documentation on the client\nconfiguration](https://console.ng.bluemix.net/docs/containers/container_cli_cfic_install.html) in Bluemix to configure these variables. If the `cf ic` tools are already installed and your command\nline is already set up/logged in you can use `cf ic init` to display\nthe three environment variables you need to export to use your `docker` client\ntargeting the IBM container service. To simplify your workflow, you may add\nthese variables to the `.env` file and then the `Makefile` targets interacting\nwith the Bluemix container service will work without any extra configuration.\n\n#### Microservices\n\nGiven this \"lift and shift\" model is just a stepping stone to more adantageous\nuse of containerized architectures, we've taken the weather endpoint from\nthe Node.js application and created a separate containerized microservice for\nretrieving weather data. Because containers and microservices decouple our\napplication components, you'll notice that our weather microservice does not\nneed to be written in Node.js nor does it use any of the same dependencies of\nour monolithic application. In this case, we've used Python as a simple language\nin which to write the weather data retrieval service.\n\nYou can find the code for our weather microservice\nin the [flightassist-weather](https://github.com/estesp/flightassist-weather) Github repository.\n\nOf course, the fact that we can develop these microservices in a parallel but\nseparate space means we can improve the weather service or refactor it, or \nchange its backend data source without impacting development of the main application.\n\n### FaaS application model\n\nSimilar to our initial baby step to break out the weather API query\ninto a microservice, our FaaS model takes that same capability (our\nweather lookup) and offloads it to an OpenWhisk-based action in IBM\nBluemix. Because the OpenWhisk system packages already include a weather\nforecast lookup using our same IBM Weather Insights API credentials, it was\nsimple to call this OpenWhisk action via its default HTTP endpoint already\navailable in the OpenWhisk ecosystem through this default system package.\n\nIt would be interesting to continue to grow the use of FaaS in **flightassist**\nby writing new actions in OpenWhisk that handle the entire cache lookup,\nexternal API query (if needed), and cache update/formatted response work\nas a single callable action.\n\n## \u003ca name=\"deployguides\"\u003e\u003c/a\u003eDeployment Guides\n\nThe following sections provide specific step-by-step guides for deploying\n**flightassist** using the various models described to this point.\n\n### External service pre-requisites\n\nAll deployment methods require credentials for a set of services used\nby the application.  Without these service configurations and their\ncredentials the application will not work properly.\n\nThe first two services are part of IBM's Bluemix cloud service catalog. To\ncreate instances of these services for free, you can create a 30-day trial\naccount at this [Bluemix sign-up page](https://console.ng.bluemix.net/registration/).\n\nOnce you have a Bluemix account, you can create \"Free tier\" instances of\nboth a Cloudant NoSQL database and the Weather Insights API. For simplicity,\nlinks to these services are below:\n\n * [The Cloudant NoSQL database service](https://console.ng.bluemix.net/catalog/services/cloudant-nosql-db?env_id=ibm:yp:us-south)\n * [Weather Company Data, also known as Weather Insights](https://console.ng.bluemix.net/catalog/services/weather-company-data?env_id=ibm:yp:us-south)\n\n\u003e **Note:** Cloud Foundry power users will know that you can create service\n\u003e instances via the `cf` command line tool.\n\nOnce you have created free tier instances of these services, you can view\nyour credentials and, for each, copy the *url* variant of the credential info\nin the next steps when asked for the `WEATHER_URL` or `CLOUDANT_URL`.\n\nBefore moving on, the demo application is missing code to create the databases used\nto cache API responses in your newly created Cloudant instance. One simple way\nto make sure these databases are initialized is through the Bluemix console UI.\nGo to your new Cloudant service and open the Cloudant UI console using the link from your\nservice instance page. Once at the Cloudant console you will need to\ncreate the **trips**, **weather**, and **connections** databases for\nthe cacheing code to work properly.\n\nNote that if you deploy the application to Cloud Foundry in IBM Bluemix,\nyou will also create CF service bindings between your service instances\nand the application you deploy, relieving you of the need to set up \nenvironmental parameters with the credential details. Information on that\nstep is below in the Cloud Foundry section.\n\nWith your two IBM Bluemix services instantiated with credentials assigned, you\nwill also be required to create a developer account for both the TripIt API and\nthe FlightStats API. The following links will take you to the appropriate signup\npages for these two developer APIs.\n\n * [TripIt Developer API](https://www.tripit.com/developer/create)\n * [FlightStats Developer API](https://developer.flightstats.com/signup)\n\nWhen signing up for a FlightStats developer key, note that there is a\nreview process that may take 24 hours or more to get your application\ncredentials activated for a 30-day trial with the API.\n\nOnce you have valid credentials to all four services, you can use any of the\nfollowing application deployment models to use and demonstrate the application\nbehavior.\n\n### Standalone Node.js monolithic application\n\nTo run **flightassist** as a standalone Node.js application, the system\non which you want to run the application requires an installation of Node.js/npm\nutilities and optionally `make` (to utilize the `Makefile` targets set up\nfor ease of deployment configuration).\n\n 1. Clone this repository: `git clone https://github.com/estesp/flightassist`\n 2. Copy `dot-env` to `.env`: `cd flightassist \u0026\u0026 cp dot-env .env`\n 3. Edit `.env` and fill in all required credentials from your four services\n 4. Leave `DEVMODE` and `DEV_URL` as set as this will allow the local deployment\n 5. Read about the rest of the variables; make sure `USE_WEATHER_SERVICE=false`\n 6. If using the `Makefile` type `make localdeploy` to run npm and start the Node application.\n\nIf you performed the setup steps correctly, you now have a working application which\nyou can visit locally via http://localhost:3000 in your browser.\n\n### Cloud Foundry monolithic application hosted in IBM Bluemix\n\nPushing the Node.js application to Bluemix as a CF application is quite similar\nto running the Node.js application locally. The main steps to perform are in the\nBluemix console for binding the Bluemix catalog service instances to your application\nand setting up the external API credentials as environment variables.\n\nBecause we already have a `manifest.yml` in the root of the project, you can\nget started by simply using `cf push` from the root of the repository:\n\n 1. Clone the project: `git clone https://github.com/estesp/flightassist`\n 2. Edit `manifest.yml` and select your own application name and `host`. Since my application instance already owns the route `flightassist` on `mybluemix.net` you will have to select a unique name.\n 3. Edit `flightassist.js` to set the `baseURL` variable (around line 16) to your selected CF route hostname.\n 4. Either type `cf push` after making these edits or `make cfdeploy` to do the same action.\n 5. Once your application is deployed, you need to make service bindings; go to the Bluemix console, open your application and use the UI to bind your two Bluemix services (Cloudant and Weather Data) to your application.\n 6. Go to the *Runtime* settings for your application and add these four environment variables to set up external credentials to the TripIt and FlightStats services:\n   - `FLIGHTSTATS_APP_ID` : application ID assigned by FlightStats\n   - `FLIGHTSTATS_APP_KEY` : application key assigned by FlightStats\n   - `TRIPIT_API_KEY` : API key assigned by TripIt\n   - `TRIPIT_API_SECRET` : API secret assigned by TripIt\n\nYour application should restart automatically, but can be done manually as well\nin the UI. With the service bindings and added environment variables, the\napplication should be operational at the hostname route you selected for your CF\napplication. Note that the `FORCE_FLIGHT_VIEW` variable can optionally be set to `true`\nas an added environment variable for demonstrating the application function even\nif no flights are upcoming in the next day with the TripIt user credentials\nauthorized via the application.\n\n### Local Docker container deployment as a monolithic application\n\nTo deploy the application wholesale in a Docker container, the project\nalready includes a simple \"lift and shift\" `Dockerfile` that \npackages the application very similar to the standalone model already\ndiscussed. The only benefit is that the image can be reused and doesn't\nforce the local system to have any of the Node.js SDK dependencies\ninstalled.\n\n 1. Clone the project: `git clone https://github.com/estesp/flightassist`\n 2. Copy `dot-env` to `.env`: `cd flightassist \u0026\u0026 cp dot-env .env`\n 3. Edit `.env` and fill in all required credentials from your four services\n 4. Leave `DEVMODE` and `DEV_URL` as set as this will allow the local deployment\n 5. Read about the rest of the variables; make sure `USE_WEATHER_SERVICE=false`\n 6. Use the `Makefile` to perform the `docker build` and `docker run`: `make localctr`\n 7. Note you can also build/rebuild the container image using the `Makefile`: `make localimage`\n\nVery similar to the standalone non-containerized application version,\nyou can visit http://localhost:3000 and use the application as this\nport is exposed from the running container.\n\n### IBM Container Service (legacy) deployment as a monolithic application\n\nYou can also use the legacy IBM Container Service capability to point your\n`docker` client at the hosted public container service API endpoint and\nregistry and deploy the same single container runtime, and have public IP\naddress assignment, simple container group (scaling) capability, and image vulnerability\nscanning.  The steps are the same as running Docker locally with the following\nchanges:\n\n 1. Make sure you are logged in with the `cf ic login` command (Requires the IBM Container Service plugin)\n 2. Get the required settings for the `DOCKER_HOST` and other variables (re-run `cf ic init` to have them displayed in your terminal) and place them in the appropriate locations in your `.env` file.\n 3. Assuming you have your environment configured properly, you can now type `make bxdeploy` to build your container image, tag and push it to the IBM private registry and then run it in the IBM container service.\n\nNow that IBM Bluemix has released the Kubernetes-based cluster capability for the\nIBM Container Service in beta, see the Kubenetes deployment section below\nfor a more up-to-date method for deployment the microservice-based variant of\n**flightassist** in this new Bluemix beta service.\n\n### Docker Swarm-based micro-service based application deployment\n\nWith the advent of Docker Swarm in Docker 1.12 and above, you can use a\nrecent installation of the Docker engine with Swarm enabled (`docker swarm init`)\nand the new Docker Compose v3.1 format to deploy **flightassist** as\na containerized micro-service-using application onto a Swarm cluster.\n\nThis deployment will use the new `docker secret` and `docker stack deploy`\ncapabilities of Docker 1.13.1 and above, so the minimum required Docker\nversion is 1.13.1. Docker for Mac updated to the most recent edition is\na great way to try this out.\n\n 1. Clone the project: `git clone https://github.com/estesp/flightassist`\n 2. Copy `dot-env` to `.env`: `cd flightassist \u0026\u0026 cp dot-env .env`\n 3. Edit `.env` and fill in all required credentials from your four services\n 4. Uncomment `DEPLOY` and set the value to `swarm`\n 5. Make sure `export USE_WEATHER_SERVICE=true` is uncommented\n 6. Clone the weather microservice project: `git clone https://github.com/estesp/flightassist-weather`\n 7. Enter that project directory and type: `make localimage` to get the image built (depended on by the compose service definition)\n 8. Go back to the root of the `flightassist` repo and type `make swarmdeploy`. This will first create the secrets using the values you have placed in `.env` using the `docker secret create` command and then use the `docker stack deploy` command to bring up your two services in the Swarm.\n\nThe application should be available now on http://localhost, assuming you are using a local\nDocker edition (like Docker for Mac) or a locally installed Docker\ndaemon on a Linux system. If the application is hosted on a known IP or host, you can\nmodify the `docker-compose.yaml` file with those details and access the application\non that host/IP information. All the standard Swarm tools can be used to view logs\nor validate that the services are up and running properly.\n\n### Docker + Kubernetes based application deployment (minikube)\n\nThe *yaml* files for a Kubernetes deployment of the weather microservice and\nthe main application have been created in the base repository and tested.\n\nConcrete instructions for making a local deployment with **minikube** is coming soon.\n\n### Docker + Kubernetes based application deployment (IBM Container Service beta)\n\nThe *yaml* files exist in the repository for creating a Kubernetes deployment\nwith the weather microservice and the main application. \n\n1. Follow the create kubernetes cluster tutorial to create the kubernetes cluster in IBM Container service [https://console.ng.bluemix.net/docs/containers/cs_tutorials.html#cs_tutorials].\n\n2. Create the cloudant and weather insight service if you don't have them deployed yet:\n  * ```bx service create cloudantNoSQLDB Lite mycloudant```\n  * ``` bx service create weatherinsights Free-v2 myweatherinsights```\n\n3. Bind the two services to the kubernete cluster deployed earlier:\n  * ```bx cs cluster-service-bind {your-cluster-name} default mycloudant```\n  * ```bx cs cluster-service-bind {your-cluster-name} default myweatherinsights```\n\n  The examples above use the default kubernetes namespace and you could choose a different namespace.\n\n4. Modify the secret.yaml file with flightstats-app-id, flightstats-app-key, tripit-api-key, and tripit-api-secret.\n\n5. Edit the flightassist.yaml and replace the ```\u003cnamespace\u003e``` with your own namespace.  Also replace \u003cyour-app-end-point-url\u003e with the endpoint of the application.  If you are using the free cluster provided by IBM Container service, this is your node ip and nodeport, e.g. 169.47.237.139:30080\n\n5. Deploy the secret and deployment:\n  * ```kubectl create -f secret.yaml```\n  * ```kubectl create -f flightassist.yaml```\n  \n### Existing application deployment + OpenWhisk action for Weather API\n\nInstead of using the weather microservice container, the code allows us\nto utilize any of the \"monolith\" deployment models (standalone, hosted CF,\nor containerized), but use an OpenWhisk action to handle the weather\nforecast query. Thanks to OpenWhisk built-in system packages, which includes\na weather API, we don't even have to write our own action to try it out with\na simple weather forecast lookup.\n\nUse any of the above guides with the following changes to use the existing\nOpenWhisk system action to call the Weather Insights API:\n\n 1. Edit your `.env` and unset the `USE_WEATHER_SERVICE=true` if it was set\n (or set it to `false`)\n 2. Uncomment the `export USE_WEATHER_SERVERLESS=true` (or add it if you don't\n have this variable copied in from the `dot-env` template)\n 3. Login to the IBM Bluemix console and set up the [OpenWhisk client](https://console.ng.bluemix.net/openwhisk/cli), making sure\n to run the setup command to set the host and authentication parameters.\n 4. Run `wsk property get --auth | awk  '{print $3}'` to get the authentication\n string from OpenWhisk and set a new variable in `.env`: `export OPENWHISK_AUTH=\u003cauth-string` with\n the data you got back from the `get --auth` command.\n 5. Run your deployment of **flightassist** and verify in your logs that the\n OpenWhisk action is being utilized to query the weather data for each airport.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Festesp%2Fflightassist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Festesp%2Fflightassist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Festesp%2Fflightassist/lists"}