{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"ce8cdaaf-e082-4860-854a-2d66a3854e51","name":"FIWARE Context Providers","description":"This tutorial builds on the **Store** entity created in the previous [stock management example](https://github.com/Fiware/tutorials.CRUD-Operations/) and enables a user to \nretrieve data about a store which is not held directly within the Orion Context Broker.\n\nThe `docker-compose` file for this tutorial can be found on GitHub: \n\n![GitHub](https://fiware.github.io/tutorials.Context-Providers/icon/GitHub-Mark-32px.png) [FIWARE 104: Registering Context Providers](https://github.com/Fiware/tutorials.Context-Providers)\n\n# Context Providers\n\n> \"Knowledge is of two kinds. We know a subject ourselves, or we know where we can find information about it.\"\n>\n> — Samuel Johnson (Boswell's Life of Johnson)\n\n\nWithin the FIWARE platform, an entity represents the state of a physical or conceptural object which exists in the real world. \nFor example, a **Store** is a real world bricks and mortar building.\n\nThe context data of that entity defines the state of that real-world object at a given moment in time. \n\nIn all of the tutorials so far, we are holding all of the context data for our **Store** entities directly within the Orion \nContext Broker, for example stores would have attributes such as:\n\n* A unique identifier for the store e.g. `urn:ngsi-ld:Store:002`\n* The name of the store e.g. \"Checkpoint Markt\"\n* The address \"Friedrichstraße 44, 10969 Kreuzberg, Berlin\"\n* A physical location  e.g. *52.5075 N, 13.3903 E*\n\nAs you can see, most of these attributes are completely static (such as the location) and the others are unlikely to be\nchanged on a regular basis - though a street could be renamed, or the store name could be rebranded.\n\nThere is however another class of context data about the **Store** entity which is much more dynamic, information such as:\n\n* The current temperature at the store location\n* The current relative humidity at the store location\n* Recent social media tweets regarding the store \n\nThis information is always changing, and if it were held in a database, the data would always be out-of-date. To keep the context\ndata fresh, and to be able to retrieve the current state of the system on demand, new values for these dynamic data attributes will \nneed to be retrieved whenever the entity context is requested.\n\nSmart solutions are designed to react on the current state of the real-world. They are \"aware\" since they rely on dynamic data readings from \nexternal sources (such social media, IoT sensors, user inputs). The FIWARE platform makes the gathering and presentation of real-time \ncontext data transparent, since whenever an [NGSI](https://swagger.lab.fiware.org/?url=https://raw.githubusercontent.com/Fiware/specifications/master/OpenAPI/ngsiv2/ngsiv2-openapi.json) request is made to the Orion Context\nBroker it will always return the latest context by combining the data held within its database along with real-time data readings from \nany registered external context providers.\n\nIn order to be able to fulfil these requests, the Orion Context Broker, must first be supplied with two types of information:\n\n* The static context data held within Orion itself  (*Entities that Orion \"knows\" about*) \n* Registered external context providers associated with existing entities (*Entities that Orion can \"find information\" about*) \n\n\n## Entities within a stock management system\n\n\nWithin our simple stock management system, our **Store** entity currently returns `id`, `name`,  `address` and `location` attributes. \nWe will augment this with additional real-time context data from the following free publicly available data sources:\n\n* The temperature and relative humidity from the [Weather Underground API](https://www.wunderground.com/weather/api/d/docs?MR=1)\n* Recent social media tweets regarding the store from the [Twitter API](https://developer.twitter.com/](https://developer.twitter.com/)\n\nThe relationship between our entities is defined as shown:\n\n![](https://fiware.github.io/tutorials.Context-Providers/img/entities.png)\n\n# Architecture\n\nThis application will only make use of one FIWARE component - the [Orion Context Broker](https://catalogue.fiware.org/enablers/publishsubscribe-context-broker-orion-context-broker). Usage of the Orion Context Broker is sufficient for an application to qualify as *“Powered by FIWARE”*.\n\nCurrently, the Orion Context Broker relies on open source [MongoDB](https://www.mongodb.com/) technology to keep persistence of the context data it holds. \nTo request context data from external sources, we will now need to add a simple Context Provider NGSI proxy.\n\n\nTherefore, the architecture will consist of three elements:\n\n* The Orion Context Broker server which will receive requests using [NGSI](https://swagger.lab.fiware.org/?url=https://raw.githubusercontent.com/Fiware/specifications/master/OpenAPI/ngsiv2/ngsiv2-openapi.json)\n* The underlying MongoDB database associated to the Orion Context Broker server\n* The Context Provider NGSI proxy which will will:\n  + receive requests using [NGSI](https://swagger.lab.fiware.org/?url=https://raw.githubusercontent.com/Fiware/specifications/master/OpenAPI/ngsiv2/ngsiv2-openapi.json)\n  + makes requests to publicly available data sources using their own APIs in a proprietory format \n  + returns context data back to the Orion Context Broker in [NGSI](https://swagger.lab.fiware.org/?url=https://raw.githubusercontent.com/Fiware/specifications/master/OpenAPI/ngsiv2/ngsiv2-openapi.json) format.\n\nSince all interactions between the elements are initiated by HTTP requests, the entities can be containerized and run from exposed ports. \n\n![](https://fiware.github.io/tutorials.Context-Providers/img/architecture.png)\n\nThe necessary configuration information for the **Context Provider NGSI proxy** can be seen in the services section the of the associated `docker-compose.yml`  file:\n\n```yaml\n  context-provider:\n    image: fiware/cp-web-app:latest\n    hostname: context-provider\n    container_name: context-provider\n    networks:\n        - default\n    expose:\n        - \"3000\"\n    ports:\n        - \"3000:3000\"\n    environment:\n        - \"DEBUG=proxy:*\"\n        - \"PORT=3000\" \n        - \"CONTEXT_BROKER=http://orion:1026/v2\" \n        - \"WUNDERGROUND_KEY_ID=<ADD_YOUR_KEY_ID>\"\n        - \"TWITTER_CONSUMER_KEY=<ADD_YOUR_CONSUMER_KEY>\"\n        - \"TWITTER_CONSUMER_SECRET=<ADD_YOUR_CONSUMER_SECRET>\"\n```\n\nThe `context-provider` container is driven by environment variables as shown:\n\n| Key |Value|Description|\n|-----|-----|-----------|\n|DEBUG|`proxy:*`| Debug flag used for logging |\n|PORT|`3000`|Port used by the content provider proxy and web-app for viewing data |\n|CONTEXT_BROKER|`http://orion:1026/v2`| URL of the context broker to  connect to update context|\n|WUNDERGROUND_KEY_ID|`<ADD_YOUR_KEY_ID>`| A consumer key used to obtain access to the Weather Underground API|\n|TWITTER_CONSUMER_KEY|`<ADD_YOUR_CONSUMER_KEY>`| A consumer key used to obtain access to the Twitter API|\n|TWITTER_CONSUMER_SECRET|`<ADD_YOUR_CONSUMER_SECRET>`| A user key used to obtain access to the Twitter API |\n\nThe other `context-provider` container configuration values described in the YAML file are not used in this tutorial.\n\n\nThe configuration information for MongoDB and the Orion Context Broker\nhas been described in a [previous tutorial](https://github.com/Fiware/tutorials.Entity-Relationships/)\n\n# Prerequisites\n\n## Docker\n\nTo keep things simple both components will be run using [Docker](https://www.docker.com). **Docker** is a container technology which allows to different components isolated into their respective environments. \n\n* To install Docker on Windows follow the instructions [here](https://docs.docker.com/docker-for-windows/)\n* To install Docker on Mac follow the instructions [here](https://docs.docker.com/docker-for-mac/)\n* To install Docker on Linux follow the instructions [here](https://docs.docker.com/install/)\n\n**Docker Compose** is a tool for defining and running multi-container Docker applications. A [YAML file](https://raw.githubusercontent.com/Fiware/tutorials.Entity-Relationships/master/docker-compose.yml) is used configure the required\nservices for the application. This means all container sevices can be brought up in a single commmand. Docker Compose is installed by default as part of Docker for Windows and  Docker for Mac, however Linux users will need to follow the instructions found [here](https://docs.docker.com/compose/install/)\n\n## Cygwin \n\nWe will start up our services using a simple bash script. Windows users should download [cygwin](www.cygwin.com) to provide a command line functionality similar to a Linux distribution on Windows. \n\n## Context Provider NGSI proxy\n\nA simple [nodejs](https://nodejs.org/) [Express](https://expressjs.com/) application has been bundled as part of the repository. The application offers an NGSI v1 interface for four different context providers - the Weather Underground API, the Twitter Search API and two dummy data context providers - a static data provider (which always returns the same data) and a random data context provider (which will change every time it is invoked). \n\nMore information about the proxy endpoints can be found [here](https://github.com/Fiware/tutorials.Context-Providers/blob/master/proxy/README.md)\n\n* In order to access the Weather Underground API, you will need to sign up for a key at https://www.wunderground.com/weather/api/ \n* In order to access the Twitter Search API, you will have to create an app in Twitter via  https://apps.twitter.com/app/new to obtain a \nConsumer Key & Consumer Secret. \n\n\nReplace the placeholders in `docker-compose.yml` in the root of the repository with the values you obtain for your application:\n\n```yaml\n    environment:\n        - \"DEBUG=proxy:*\"\n        - \"WUNDERGROUND_KEY_ID=<ADD_YOUR_KEY_ID>\"\n        - \"TWITTER_CONSUMER_KEY=<ADD_YOUR_CONSUMER_KEY>\"\n        - \"TWITTER_CONSUMER_SECRET=<ADD_YOUR_CONSUMER_SECRET>\"\n```\n\nIf you do not wish to sign-up for an API key, you can use data from the random data context provider instead.\n\n# Start Up\n\nAll services can be initialised from the command line by running the bash script provided within the repository:\n\n```console\n./services create; ./services start;\n```\n\nThis command will also import seed data from the previous [Stock Management example](https://github.com/Fiware/tutorials.CRUD-Operations) on startup.","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":true,"owner":"513743","team":157450,"collectionId":"ce8cdaaf-e082-4860-854a-2d66a3854e51","publishedId":"RW1XLMKz","public":true,"publicUrl":"https://documenter-api.postman.tech/view/513743/RW1XLMKz","privateUrl":"https://go.postman.co/documentation/513743-ce8cdaaf-e082-4860-854a-2d66a3854e51","customColor":{"top-bar":"FFFFFF","right-sidebar":"4C4C4C","highlight":"233C68"},"documentationLayout":"classic-double-column","version":"8.10.0","publishDate":"2020-01-02T11:02:46.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{},"logos":{}},"statusCode":200},"environments":[],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/d7085d490b9144732c65203aa6e3b68b31884d1c33a86b8a00d15da75147ae33","favicon":""},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"}],"canonicalUrl":"https://documenter.gw.postman.com/view/metadata/RW1XLMKz"}