From 07ac69ac275092b7b2a0b44feb41064c20176465 Mon Sep 17 00:00:00 2001 From: Peter Shepley Date: Mon, 9 Dec 2019 13:31:00 -0500 Subject: [PATCH 01/10] Add .idea to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 9f671835..24ca8c89 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ yarn.lock lerna-debug.log *.lerna_backup _book +.idea/ From c3a237b83566c9120841e874c7f2e33faf3499a4 Mon Sep 17 00:00:00 2001 From: marquet Date: Tue, 10 Dec 2019 13:19:34 -0500 Subject: [PATCH 02/10] updated node --- .circleci/config.yml | 2 +- Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1f64348b..c04f2301 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,7 +17,7 @@ references: jobs: build_and_test: docker: - - image: circleci/node:8.11 + - image: circleci/node:12.0 steps: - *restore_repo - checkout diff --git a/Dockerfile b/Dockerfile index c83e2437..50af9cf5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ # - ES_HOST: Elasticsearch https endpoint -FROM node:8 +FROM node:12 ENV \ HOME=/home/sat-utils From 3108432eecb8792dbf87ca0d5349bc9313d6bc21 Mon Sep 17 00:00:00 2001 From: marquet Date: Tue, 10 Dec 2019 22:22:38 -0500 Subject: [PATCH 03/10] added stac api + extensions - transaction --- packages/api-lib/api.yaml | 1744 +++++++++++++++++++++++++++++++++++++ 1 file changed, 1744 insertions(+) create mode 100644 packages/api-lib/api.yaml diff --git a/packages/api-lib/api.yaml b/packages/api-lib/api.yaml new file mode 100644 index 00000000..4ef5f4d5 --- /dev/null +++ b/packages/api-lib/api.yaml @@ -0,0 +1,1744 @@ +openapi: 3.0.1 +info: + title: The SpatioTemporal Asset Catalog API + Extensions + version: 0.8.1 + license: + name: Apache License 2.0 + url: 'http://www.apache.org/licenses/LICENSE-2.0' + description: >- + This is an OpenAPI definition of the core SpatioTemporal Asset Catalog API + specification. Any service that implements this endpoint to allow search of + spatiotemporal assets can be considered a STAC API. The endpoint is also + available as an OpenAPI fragment that can be integrated with other OpenAPI + definitions, and is designed to slot seamlessly into a OGC API - Features + definition. + contact: + name: STAC Specification + url: 'http://stacspec.org' +tags: + - name: Capabilities + description: essential characteristics of this API + - name: Data + description: access to data (features) + - name: STAC + description: >- + Extension to OGC API - Features to support STAC metadata model and search + API +paths: + /: + get: + tags: + - Capabilities + summary: landing page + description: |- + The landing page provides links to the API definition, the conformance + statements and to the feature collections in this dataset. + operationId: getLandingPage + responses: + '200': + $ref: '#/components/responses/LandingPage' + '500': + $ref: '#/components/responses/ServerError' + /conformance: + get: + tags: + - Capabilities + summary: information about specifications that this API conforms to + description: |- + A list of all conformance classes specified in a standard that the + server conforms to. + operationId: getConformanceDeclaration + responses: + '200': + $ref: '#/components/responses/ConformanceDeclaration' + '500': + $ref: '#/components/responses/ServerError' + /collections: + get: + tags: + - Capabilities + summary: the feature collections in the dataset + operationId: getCollections + responses: + '200': + $ref: '#/components/responses/Collections' + '500': + $ref: '#/components/responses/ServerError' + '/collections/{collectionId}': + get: + tags: + - Capabilities + summary: describe the feature collection with id `collectionId` + operationId: describeCollection + parameters: + - $ref: '#/components/parameters/collectionId' + responses: + '200': + $ref: '#/components/responses/Collection' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/ServerError' + '/collections/{collectionId}/items': + get: + tags: + - Data + summary: fetch features + description: |- + Fetch features of the feature collection with id `collectionId`. + Every feature in a dataset belongs to a collection. A dataset may + consist of multiple feature collections. A feature collection is often a + collection of features of a similar type, based on a common schema. + Use content negotiation to request HTML or GeoJSON. + operationId: getFeatures + parameters: + - $ref: '#/components/parameters/collectionId' + - $ref: '#/components/parameters/limit' + - $ref: '#/components/parameters/bbox' + - $ref: '#/components/parameters/datetime' + responses: + '200': + $ref: '#/components/responses/Features' + '400': + $ref: '#/components/responses/InvalidParameter' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/ServerError' + '/collections/{collectionId}/items/{featureId}': + get: + tags: + - Data + summary: fetch a single feature + description: |- + Fetch the feature with id `featureId` in the feature collection + with id `collectionId`. + Use content negotiation to request HTML or GeoJSON. + operationId: getFeature + parameters: + - $ref: '#/components/parameters/collectionId' + - $ref: '#/components/parameters/featureId' + responses: + '200': + $ref: '#/components/responses/Feature' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/ServerError' + /stac: + get: + summary: Return the root catalog or collection. + description: >- + Returns the root STAC Catalog or STAC Collection that is the entry point + for users to browse with STAC Browser or for search engines to crawl. + This can either return a single STAC Collection or more commonly a STAC + catalog that usually lists sub-catalogs of STAC Collections, i.e. a + simple catalog that lists all collections available through the API. + tags: + - STAC + responses: + '200': + description: A catalog JSON definition. Used as an entry point for a crawler. + content: + application/json: + schema: + $ref: '#/components/schemas/catalogDefinition' + /stac/search: + get: + summary: Search STAC items with simple filtering. + description: >- + Retrieve Items matching filters. Intended as a shorthand API for simple + queries. This method is optional, but you MUST implement `POST + /stac/search` if you want to implement this method. + operationId: getSearchSTAC + tags: + - STAC + parameters: + - $ref: '#/components/parameters/bbox' + - $ref: '#/components/parameters/datetime' + - $ref: '#/components/parameters/limit' + - $ref: '#/components/parameters/next' + - $ref: '#/components/parameters/ids' + - $ref: '#/components/parameters/collectionsArray' + - $ref: '#/components/parameters/query' + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/fields' + responses: + '200': + description: A feature collection. + content: + application/geo+json: + schema: + $ref: '#/components/schemas/itemCollection' + text/html: + schema: + type: string + default: + description: An error occurred. + content: + application/json: + schema: + $ref: '#/components/schemas/exception' + text/html: + schema: + type: string + post: + summary: Search STAC items with full-featured filtering. + description: >- + retrieve items matching filters. Intended as the standard, full-featured + query API. This method is mandatory to implement if `GET /stac/search` + is implemented. If this endpoint is implemented on a server, it is + required to add a link with `rel` set to `search` to the `links` array + in `GET /stac` that refers to this endpoint. + operationId: postSearchSTAC + tags: + - STAC + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/searchBody' + responses: + '200': + description: A feature collection. + content: + application/geo+json: + schema: + $ref: '#/components/schemas/itemCollection' + text/html: + schema: + type: string + default: + description: An error occurred. + content: + application/json: + schema: + $ref: '#/components/schemas/exception' + text/html: + schema: + type: string +components: + parameters: + bbox: + name: bbox + in: query + description: >- + Only features that have a geometry that intersects the bounding box are + selected. The bounding box is provided as four or six numbers, depending + on whether the coordinate reference system includes a vertical axis + (height or depth): * Lower left corner, coordinate axis 1 * Lower left + corner, coordinate axis 2 * Minimum value, coordinate axis 3 (optional) + * Upper right corner, coordinate axis 1 * Upper right corner, coordinate + axis 2 * Maximum value, coordinate axis 3 (optional) The coordinate + reference system of the values is WGS 84 longitude/latitude + (http://www.opengis.net/def/crs/OGC/1.3/CRS84) unless a different + coordinate reference system is specified in the parameter `bbox-crs`. + For WGS 84 longitude/latitude the values are in most cases the sequence + of minimum longitude, minimum latitude, maximum longitude and maximum + latitude. However, in cases where the box spans the antimeridian the + first value (west-most box edge) is larger than the third value + (east-most box edge). If the vertical axis is included, the third and + the sixth number are the bottom and the top of the 3-dimensional + bounding box. If a feature has multiple spatial geometry properties, it + is the decision of the server whether only a single spatial geometry + property is used to determine the extent or all relevant geometries. + required: false + schema: + type: array + minItems: 4 + maxItems: 6 + items: + type: number + style: form + explode: false + collectionId: + name: collectionId + in: path + description: local identifier of a collection + required: true + schema: + type: string + datetime: + name: datetime + in: query + description: >- + Either a date-time or an interval, open or closed. Date and time + expressions adhere to RFC 3339. Open intervals are expressed using + double-dots. Examples: * A date-time: "2018-02-12T23:20:50Z" * A closed + interval: "2018-02-12T00:00:00Z/2018-03-18T12:31:12Z" * Open intervals: + "2018-02-12T00:00:00Z/.." or "../2018-03-18T12:31:12Z" Only features + that have a temporal property that intersects the value of `datetime` + are selected. If a feature has multiple temporal properties, it is the + decision of the server whether only a single temporal property is used + to determine the extent or all relevant temporal properties. + required: false + schema: + type: string + style: form + explode: false + featureId: + name: featureId + in: path + description: local identifier of a feature + required: true + schema: + type: string + limit: + name: limit + in: query + description: >- + The optional limit parameter limits the number of items that are + presented in the response document. Only items are counted that are on + the first level of the collection in the response document. Nested + objects contained within the explicitly requested items shall not be + counted. Minimum = 1. Maximum = 10000. Default = 10. + required: false + schema: + type: integer + minimum: 1 + maximum: 10000 + default: 10 + style: form + explode: false + next: + name: next + in: query + description: >- + The token to retrieve the next set of results, e.g., offset, page, + continuation token + required: false + schema: + $ref: '#/components/schemas/next' + style: form + ids: + name: ids + in: query + description: > + Array of Item ids to return. All other filter parameters that further + restrict the number of search results (except `next` and `limit`) are + ignored + required: false + schema: + $ref: '#/components/schemas/ids' + explode: false + collectionsArray: + name: collections + in: query + description: | + Array of Collection IDs to include in the search for items. + Only Items in one of the provided Collections will be searched + required: false + schema: + $ref: '#/components/schemas/collectionsArray' + explode: false + query: + name: query + in: query + description: >- + query for properties in items. Use the JSON form of the queryFilter used + in POST. + required: false + schema: + type: string + sort: + name: sort + in: query + description: Allows sorting results by the specified properties + required: false + schema: + $ref: '#/components/schemas/sort' + fields: + name: fields + in: query + description: Determines the shape of the features in the response + required: false + schema: + $ref: '#/components/schemas/fields' + style: form + explode: false + schemas: + collection: + type: object + required: + - id + - links + - stac_version + - description + - license + - extent + properties: + id: + description: 'identifier of the collection used, for example, in URIs' + type: string + example: address + title: + description: human readable title of the collection + type: string + example: address + description: + description: >- + Detailed multi-line description to fully explain the collection. + [CommonMark 0.29](http://commonmark.org/) syntax MAY be used for + rich text representation. + type: string + example: An address. + links: + type: array + items: + $ref: '#/components/schemas/link' + example: + - href: 'http://data.example.com/buildings' + rel: item + - href: 'http://example.com/concepts/buildings.html' + rel: describedBy + type: text/html + extent: + $ref: '#/components/schemas/extent' + itemType: + description: >- + indicator about the type of the items in the collection (the default + value is 'feature'). + type: string + default: feature + crs: + description: the list of coordinate reference systems supported by the service + type: array + items: + type: string + default: + - 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' + example: + - 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' + - 'http://www.opengis.net/def/crs/EPSG/0/4326' + stac_version: + $ref: '#/components/schemas/stac_version' + stac_extensions: + $ref: '#/components/schemas/stac_extensions' + keywords: + type: array + description: List of keywords describing the collection. + items: + type: string + version: + type: string + description: Version of the collection. + license: + $ref: '#/components/schemas/license' + providers: + $ref: '#/components/schemas/providers' + summaries: + $ref: '#/components/schemas/summaries' + example: + stac_version: 0.8.1 + stac_extensions: [] + id: Sentinel-2 + title: 'Sentinel-2 MSI: MultiSpectral Instrument, Level-1C' + description: | + Sentinel-2 is a wide-swath, high-resolution, multi-spectral + imaging mission... + license: proprietary + keywords: + - copernicus + - esa + - eu + - msi + - radiance + - sentinel + providers: + - name: ESA + roles: + - producer + - licensor + url: 'https://sentinel.esa.int/web/sentinel/user-guides/sentinel-2-msi' + extent: + spatial: + bbox: + - - -180 + - -56 + - 180 + - 83 + temporal: + interval: + - - '2015-06-23T00:00:00Z' + - '2019-07-10T13:44:56Z' + summaries: + datetime: + min: '2015-06-23T00:00:00Z' + max: '2019-07-10T13:44:56Z' + 'sci:citation': + - 'Copernicus Sentinel data [Year]' + 'eo:gsd': + - 10 + - 30 + - 60 + 'eo:platform': + - sentinel-2a + - sentinel-2b + 'eo:constellation': + - sentinel-2 + 'eo:instrument': + - msi + 'eo:off_nadir': + min: 0 + max: 100 + 'eo:sun_elevation': + min: 6.78 + max: 89.9 + 'eo:bands': + - - name: B1 + common_name: coastal + center_wavelength: 4.439 + gsd: 60 + - name: B2 + common_name: blue + center_wavelength: 4.966 + gsd: 10 + - name: B3 + common_name: green + center_wavelength: 5.6 + gsd: 10 + - name: B4 + common_name: red + center_wavelength: 6.645 + gsd: 10 + - name: B5 + center_wavelength: 7.039 + gsd: 20 + - name: B6 + center_wavelength: 7.402 + gsd: 20 + - name: B7 + center_wavelength: 7.825 + gsd: 20 + - name: B8 + common_name: nir + center_wavelength: 8.351 + gsd: 10 + - name: B8A + center_wavelength: 8.648 + gsd: 20 + - name: B9 + center_wavelength: 9.45 + gsd: 60 + - name: B10 + center_wavelength: 1.3735 + gsd: 60 + - name: B11 + common_name: swir16 + center_wavelength: 1.6137 + gsd: 20 + - name: B12 + common_name: swir22 + center_wavelength: 2.2024 + gsd: 20 + links: + - rel: self + href: 'http://cool-sat.com/collections/Sentinel-2' + - rel: root + href: 'http://cool-sat.com/collections' + - rel: license + href: >- + https://scihub.copernicus.eu/twiki/pub/SciHubWebPortal/TermsConditions/Sentinel_Data_Terms_and_Conditions.pdf + title: >- + Legal notice on the use of Copernicus Sentinel Data and Service + Information + collections: + type: object + required: + - links + - collections + properties: + links: + type: array + items: + $ref: '#/components/schemas/link' + collections: + type: array + items: + $ref: '#/components/schemas/collection' + confClasses: + type: object + required: + - conformsTo + properties: + conformsTo: + type: array + items: + type: string + exception: + type: object + description: >- + Information about the exception: an error code plus an optional + description. + required: + - code + properties: + code: + type: string + description: + type: string + extent: + type: object + description: >- + The extent of the features in the collection. In the Core only spatial + and temporal extents are specified. Extensions may add additional + members to represent other extents, for example, thermal or pressure + ranges. + properties: + spatial: + description: The spatial extent of the features in the collection. + type: object + properties: + bbox: + description: >- + One or more bounding boxes that describe the spatial extent of + the dataset. In the Core only a single bounding box is + supported. Extensions may support additional areas. If multiple + areas are provided, the union of the bounding boxes describes + the spatial extent. + type: array + minItems: 1 + items: + description: >- + Each bounding box is provided as four or six numbers, + depending on whether the coordinate reference system includes + a vertical axis (height or depth): * Lower left corner, + coordinate axis 1 * Lower left corner, coordinate axis 2 * + Minimum value, coordinate axis 3 (optional) * Upper right + corner, coordinate axis 1 * Upper right corner, coordinate + axis 2 * Maximum value, coordinate axis 3 (optional) The + coordinate reference system of the values is WGS 84 + longitude/latitude + (http://www.opengis.net/def/crs/OGC/1.3/CRS84) unless a + different coordinate reference system is specified in `crs`. + For WGS 84 longitude/latitude the values are in most cases the + sequence of minimum longitude, minimum latitude, maximum + longitude and maximum latitude. However, in cases where the + box spans the antimeridian the first value (west-most box + edge) is larger than the third value (east-most box edge). If + the vertical axis is included, the third and the sixth number + are the bottom and the top of the 3-dimensional bounding box. + If a feature has multiple spatial geometry properties, it is + the decision of the server whether only a single spatial + geometry property is used to determine the extent or all + relevant geometries. + type: array + minItems: 4 + maxItems: 6 + items: + type: number + example: + - -180 + - -90 + - 180 + - 90 + crs: + description: >- + Coordinate reference system of the coordinates in the spatial + extent (property `bbox`). The default reference system is WGS 84 + longitude/latitude. In the Core this is the only supported + coordinate reference system. Extensions may support additional + coordinate reference systems and add additional enum values. + type: string + enum: + - 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' + default: 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' + required: + - bbox + temporal: + description: The temporal extent of the features in the collection. + type: object + properties: + interval: + description: >- + One or more time intervals that describe the temporal extent of + the dataset. The value `null` is supported and indicates an open + time intervall. In the Core only a single time interval is + supported. Extensions may support multiple intervals. If + multiple intervals are provided, the union of the intervals + describes the temporal extent. + type: array + minItems: 1 + items: + description: >- + Begin and end times of the time interval. The timestamps are + in the coordinate reference system specified in `trs`. By + default this is the Gregorian calendar. + type: array + minItems: 2 + maxItems: 2 + items: + type: string + format: date-time + nullable: true + example: + - '2011-11-11T12:22:11Z' + - null + trs: + description: >- + Coordinate reference system of the coordinates in the temporal + extent (property `interval`). The default reference system is + the Gregorian calendar. In the Core this is the only supported + temporal reference system. Extensions may support additional + temporal reference systems and add additional enum values. + type: string + enum: + - 'http://www.opengis.net/def/uom/ISO-8601/0/Gregorian' + default: 'http://www.opengis.net/def/uom/ISO-8601/0/Gregorian' + required: + - interval + required: + - spatial + - temporal + featureCollectionGeoJSON: + type: object + required: + - type + - features + properties: + type: + type: string + enum: + - FeatureCollection + features: + type: array + items: + $ref: '#/components/schemas/item' + links: + type: array + items: + $ref: '#/components/schemas/link' + timeStamp: + $ref: '#/components/schemas/timeStamp' + numberMatched: + $ref: '#/components/schemas/numberMatched' + numberReturned: + $ref: '#/components/schemas/numberReturned' + featureGeoJSON: + type: object + required: + - type + - geometry + - properties + properties: + type: + type: string + enum: + - Feature + geometry: + $ref: '#/components/schemas/geometryGeoJSON' + properties: + type: object + nullable: true + id: + oneOf: + - type: string + - type: integer + links: + type: array + items: + $ref: '#/components/schemas/link' + geometryGeoJSON: + oneOf: + - $ref: '#/components/schemas/pointGeoJSON' + - $ref: '#/components/schemas/multipointGeoJSON' + - $ref: '#/components/schemas/linestringGeoJSON' + - $ref: '#/components/schemas/multilinestringGeoJSON' + - $ref: '#/components/schemas/polygonGeoJSON' + - $ref: '#/components/schemas/multipolygonGeoJSON' + - $ref: '#/components/schemas/geometrycollectionGeoJSON' + geometrycollectionGeoJSON: + type: object + required: + - type + - geometries + properties: + type: + type: string + enum: + - GeometryCollection + geometries: + type: array + items: + $ref: '#/components/schemas/geometryGeoJSON' + landingPage: + type: object + required: + - links + properties: + title: + type: string + example: Buildings in Bonn + description: + type: string + example: >- + Access to data about buildings in the city of Bonn via a Web API + that conforms to the OGC API Features specification. + links: + type: array + items: + $ref: '#/components/schemas/link' + linestringGeoJSON: + type: object + required: + - type + - coordinates + properties: + type: + type: string + enum: + - LineString + coordinates: + type: array + minItems: 2 + items: + type: array + minItems: 2 + items: + type: number + link: + type: object + required: + - href + - rel + properties: + href: + type: string + example: 'http://www.geoserver.example/stac/naip/child/catalog.json' + format: url + rel: + type: string + example: child + type: + type: string + example: application/geo+json + hreflang: + type: string + example: en + title: + type: string + example: NAIP Child Catalog + length: + type: integer + title: Link + multilinestringGeoJSON: + type: object + required: + - type + - coordinates + properties: + type: + type: string + enum: + - MultiLineString + coordinates: + type: array + items: + type: array + minItems: 2 + items: + type: array + minItems: 2 + items: + type: number + multipointGeoJSON: + type: object + required: + - type + - coordinates + properties: + type: + type: string + enum: + - MultiPoint + coordinates: + type: array + items: + type: array + minItems: 2 + items: + type: number + multipolygonGeoJSON: + type: object + required: + - type + - coordinates + properties: + type: + type: string + enum: + - MultiPolygon + coordinates: + type: array + items: + type: array + items: + type: array + minItems: 4 + items: + type: array + minItems: 2 + items: + type: number + numberMatched: + description: |- + The number of features of the feature type that match the selection + parameters like `bbox`. + type: integer + minimum: 0 + example: 127 + numberReturned: + description: |- + The number of features in the feature collection. + A server may omit this information in a response, if the information + about the number of features is not known or difficult to compute. + If the value is provided, the value shall be identical to the number + of items in the "features" array. + type: integer + minimum: 0 + example: 10 + pointGeoJSON: + type: object + required: + - type + - coordinates + properties: + type: + type: string + enum: + - Point + coordinates: + type: array + minItems: 2 + items: + type: number + polygonGeoJSON: + type: object + required: + - type + - coordinates + properties: + type: + type: string + enum: + - Polygon + coordinates: + type: array + items: + type: array + minItems: 4 + items: + type: array + minItems: 2 + items: + type: number + timeStamp: + description: >- + This property indicates the time and date when the response was + generated. + type: string + format: date-time + example: '2017-08-17T08:05:32Z' + license: + type: string + description: >- + License(s) of the data as a SPDX [License + identifier](https://spdx.org/licenses/) or + [expression](https://spdx.org/spdx-specification-21-web-version#h.jxpfx0ykyb60). + Alternatively, use `proprietary` if the license is not on the SPDX + license list or `various` if multiple licenses apply. In these two cases + links to the license texts SHOULD be added, see the `license` link + relation type. Non-SPDX licenses SHOULD add a link to the license text + with the `license` relation in the links section. The license text MUST + NOT be provided as a value of this field. If there is no public license + URL available, it is RECOMMENDED to host the license text and link to + it. + example: Apache-2.0 + providers: + type: array + description: >- + A list of providers, which may include all organizations capturing or + processing the data or the hosting provider. Providers should be listed + in chronological order with the most recent provider being the last + element of the list. + items: + type: object + title: Provider + required: + - name + properties: + name: + description: The name of the organization or the individual. + type: string + description: + description: >- + Multi-line description to add further provider information such as + processing details for processors and producers, hosting details + for hosts or basic contact information. CommonMark 0.29 syntax MAY + be used for rich text representation. + type: string + roles: + description: >- + Roles of the provider. The provider's role(s) can be one or more + of the following elements: * licensor: The organization that is + licensing the dataset under the license specified in the + collection's license field. * producer: The producer of the data + is the provider that initially captured and processed the source + data, e.g. ESA for Sentinel-2 data. * processor: A processor is + any provider who processed data to a derived product. * host: The + host is the actual provider offering the data on their storage. + There should be no more than one host, specified as last element + of the list. + type: array + items: + type: string + enum: + - producer + - licensor + - processor + - host + url: + description: >- + Homepage on which the provider describes the dataset and publishes + contact information. + type: string + format: url + searchBody: + description: The search criteria + type: object + allOf: + - $ref: '#/components/schemas/bboxFilter' + - $ref: '#/components/schemas/datetimeFilter' + - $ref: '#/components/schemas/intersectsFilter' + - $ref: '#/components/schemas/nextFilter' + - $ref: '#/components/schemas/collectionsFilter' + - $ref: '#/components/schemas/idsFilter' + - $ref: '#/components/schemas/limitFilter' + - $ref: '#/components/schemas/queryFilter' + - $ref: '#/components/schemas/sortFilter' + - $ref: '#/components/schemas/fieldsFilter' + next: + type: string + description: >- + The token to retrieve the next set of results, e.g., offset, page, + continuation token + default: null + limit: + type: integer + minimum: 1 + example: 10 + default: 10 + maximum: 10000 + description: The maximum number of results to return (page size). Defaults to 10 + bbox: + description: | + Only features that have a geometry that intersects the bounding box are + selected. The bounding box is provided as four or six numbers, + depending on whether the coordinate reference system includes a + vertical axis (elevation or depth): + * Lower left corner, coordinate axis 1 + * Lower left corner, coordinate axis 2 + * Lower left corner, coordinate axis 3 (optional) + * Upper right corner, coordinate axis 1 + * Upper right corner, coordinate axis 2 + * Upper right corner, coordinate axis 3 (optional) + The coordinate reference system of the values is WGS84 + longitude/latitude (http://www.opengis.net/def/crs/OGC/1.3/CRS84) unless + a different coordinate reference system is specified in the parameter + `bbox-crs`. + For WGS84 longitude/latitude the values are in most cases the sequence + of minimum longitude, minimum latitude, maximum longitude and maximum + latitude. However, in cases where the box spans the antimeridian the + first value (west-most box edge) is larger than the third value + (east-most box edge). + If a feature has multiple spatial geometry properties, it is the + decision of the server whether only a single spatial geometry property + is used to determine the extent or all relevant geometries. + type: array + minItems: 4 + maxItems: 6 + items: + type: number + example: + - -110 + - 39.5 + - -105 + - 40.5 + bboxFilter: + type: object + description: Only return items that intersect the provided bounding box. + properties: + bbox: + $ref: '#/components/schemas/bbox' + collectionsArray: + type: array + description: | + Array of Collection IDs to include in the search for items. + Only Items in one of the provided Collections will be searched + items: + type: string + ids: + type: array + description: > + Array of Item ids to return. All other filter parameters that further + restrict the number of search results (except `next` and `limit`) are + ignored + items: + type: string + datetimeFilter: + description: An object representing a date+time based filter. + type: object + properties: + datetime: + $ref: '#/components/schemas/datetime' + intersectsFilter: + type: object + description: Only returns items that intersect with the provided polygon. + properties: + intersects: + $ref: 'https://geojson.org/schema/Geometry.json' + limitFilter: + type: object + description: Only returns maximum number of results (page size) + properties: + limit: + $ref: '#/components/schemas/limit' + nextFilter: + type: object + description: Only returns the next set of results + properties: + next: + $ref: '#/components/schemas/next' + idsFilter: + type: object + description: Only returns items that match the array of given ids + properties: + ids: + $ref: '#/components/schemas/ids' + collectionsFilter: + type: object + description: Only returns the collections specified + properties: + collections: + $ref: '#/components/schemas/collectionsArray' + datetime: + type: string + description: >- + Either a date-time or an interval, open or closed. Date and time + expressions adhere to RFC 3339. Open intervals are expressed using + double-dots. Examples: * A date-time: "2018-02-12T23:20:50Z" * A closed + interval: "2018-02-12T00:00:00Z/2018-03-18T12:31:12Z" * Open intervals: + "2018-02-12T00:00:00Z/.." or "../2018-03-18T12:31:12Z" Only features + that have a temporal property that intersects the value of `datetime` + are selected. If a feature has multiple temporal properties, it is the + decision of the server whether only a single temporal property is used + to determine the extent or all relevant temporal properties. + example: '2018-02-12T00:00:00Z/2018-03-18T12:31:12Z' + stac_version: + title: STAC version + type: string + example: 0.8.1 + stac_extensions: + title: STAC extensions + type: array + uniqueItems: true + items: + anyOf: + - title: Reference to a JSON Schema + type: string + format: uri + - title: Reference to a core extension + type: string + summaries: + description: >- + Summaries are either a unique set of all available values *or* + statistics. Statistics by default only specify the range (minimum and + maximum values), but can optionally be accompanied by additional + statistical values. The range can specify the potential range of values, + but it is recommended to be as precise as possible. The set of values + must contain at least one element and it is strongly recommended to list + all values. It is recommended to list as many properties as reasonable + so that consumers get a full overview of the Collection. Properties that + are covered by the Collection specification (e.g. `providers` and + `license`) may not be repeated in the summaries. + type: object + additionalProperties: + oneOf: + - type: array + title: Set of values + items: + description: A value of any type. + - type: object + title: Statistics + description: >- + By default, only ranges with a minimum and a maximum value can be + specified. Ranges can be specified for ordinal values only, which + means they need to have a rank order. Therefore, ranges can only + be specified for numbers and some special types of strings. + Examples: grades (A to F), dates or times. Implementors are free + to add other derived statistical values to the object, for example + `mean` or `stddev`. + required: + - min + - max + properties: + min: + anyOf: + - type: string + - type: number + max: + anyOf: + - type: string + - type: number + catalogDefinition: + type: object + required: + - stac_version + - id + - description + - links + properties: + stac_version: + $ref: '#/components/schemas/stac_version' + stac_extensions: + $ref: '#/components/schemas/stac_extensions' + id: + type: string + example: naip + title: + type: string + example: NAIP Imagery + description: + type: string + example: Catalog of NAIP Imagery. + summaries: + $ref: '#/components/schemas/summaries' + links: + type: array + items: + anyOf: + - $ref: '#/components/schemas/link' + - title: Link to search endpoint + description: >- + Link the search endpoint, which is **required** to be + specified if the API implements `/stac/search`. + type: object + required: + - href + - rel + properties: + href: + type: string + format: url + example: 'http://www.cool-sat.com/stac/search' + rel: + type: string + enum: + - search + type: + type: string + title: + type: string + itemCollection: + description: >- + A GeoJSON FeatureCollection augmented with foreign members that contain + values relevant to a STAC entity + type: object + required: + - features + - type + properties: + type: + type: string + enum: + - FeatureCollection + features: + type: array + items: + $ref: '#/components/schemas/item' + links: + $ref: '#/components/schemas/itemCollectionLinks' + 'search:metadata': + type: object + required: + - next + - returned + properties: + next: + type: string + nullable: true + limit: + type: integer + nullable: true + minimum: 0 + example: 5 + matched: + type: integer + minimum: 0 + example: 1 + returned: + type: integer + minimum: 0 + example: 1 + item: + description: >- + A GeoJSON Feature augmented with foreign members that contain values + relevant to a STAC entity + type: object + required: + - stac_version + - id + - type + - geometry + - bbox + - links + - properties + - assets + properties: + stac_version: + $ref: '#/components/schemas/stac_version' + stac_extensions: + $ref: '#/components/schemas/stac_extensions' + id: + $ref: '#/components/schemas/itemId' + bbox: + $ref: '#/components/schemas/bbox' + geometry: + $ref: 'https://geojson.org/schema/Geometry.json' + type: + $ref: '#/components/schemas/itemType' + properties: + $ref: '#/components/schemas/itemProperties' + links: + type: array + items: + $ref: '#/components/schemas/link' + assets: + $ref: '#/components/schemas/itemAssets' + example: + stac_version: 0.8.1 + stac_extensions: + - eo + - 'https://example.com/cs-extension/1.0/schema.json' + type: Feature + id: CS3-20160503_132131_05 + bbox: + - -122.59750209 + - 37.48803556 + - -122.2880486 + - 37.613537207 + geometry: + type: Polygon + coordinates: + - - - -122.308150179 + - 37.488035566 + - - -122.597502109 + - 37.538869539 + - - -122.576687533 + - 37.613537207 + - - -122.2880486 + - 37.562818007 + - - -122.308150179 + - 37.488035566 + properties: + datetime: '2016-05-03T13:22:30.040Z' + title: A CS3 item + license: PDDL-1.0 + providers: + - name: CoolSat + roles: + - producer + - licensor + url: 'https://cool-sat.com/' + 'eo:sun_azimuth': 168.7 + 'eo:cloud_cover': 0.12 + 'eo:off_nadir': 1.4 + 'eo:platform': coolsat2 + 'eo:instrument': cool_sensor_v1 + 'eo:bands': [] + 'eo:sun_elevation': 33.4 + 'eo:gsd': 0.512 + collection: CS3 + links: + - rel: self + href: 'http://cool-sat.com/collections/CS3/items/20160503_132130_04' + - rel: root + href: 'http://cool-sat.com/collections' + - rel: parent + href: 'http://cool-sat.com/collections/CS3' + - rel: collection + href: 'http://cool-sat.com/collections/CS3' + assets: + analytic: + href: >- + http://cool-sat.com/static-catalog/CS3/20160503_132130_04/analytic.tif + title: 4-Band Analytic + thumbnail: + href: >- + http://cool-sat.com/static-catalog/CS3/20160503_132130_04/thumbnail.png + title: Thumbnail + itemId: + type: string + example: path/to/example.tif + description: 'Provider identifier, a unique ID, potentially a link to a file.' + itemType: + type: string + description: The GeoJSON type + enum: + - Feature + itemAssets: + type: object + additionalProperties: + type: object + required: + - href + properties: + href: + type: string + format: url + description: Link to the asset object + example: >- + http://cool-sat.com/catalog/collections/cs/items/CS3-20160503_132130_04/thumb.png + title: + type: string + description: Displayed title + example: Thumbnail + type: + type: string + description: Media type of the asset + example: image/png + itemProperties: + type: object + required: + - datetime + description: provides the core metatdata fields plus extensions + properties: + datetime: + $ref: '#/components/schemas/datetime' + additionalProperties: + description: >- + Any additional properties added in via Item specification or + extensions. + itemCollectionLinks: + type: array + description: >- + An array of links. Can be used for pagination, e.g. by providing a link + with the `next` relation type. + items: + $ref: '#/components/schemas/link' + example: + - rel: next + href: >- + http://api.cool-sat.com/stac/search?next=ANsXtp9mrqN0yrKWhf-y2PUpHRLQb1GT-mtxNcXou8TwkXhi1Jbk + queryFilter: + type: object + description: Allows users to query properties for specific values + properties: + query: + $ref: '#/components/schemas/query' + query: + type: object + description: Define which properties to query and the operatations to apply + additionalProperties: + $ref: '#/components/schemas/queryProp' + example: + 'eo:cloud_cover': + lt: 50 + providers: + eq: Planet + published: + gt: '2018-02-12T00:00:00Z' + lte: '2018-03-18T12:31:12Z' + 'pl:item_type': + startsWith: PSScene + product: + in: + - foo + - bar + - baz + queryProp: + description: Apply query operations to a specific property + anyOf: + - description: >- + if the object doesn't contain any of the operators, it is equivalent + to using the equals operator + - type: object + description: Match using an operator + properties: + eq: + description: >- + Find items with a property that is equal to the specified value. + For strings, a case-insensitive comparison must be performed. + neq: + description: >- + Find items that *don't* contain the specified value. For + strings, a case-insensitive comparison must be performed. + gt: + type: number + description: >- + Find items with a property value greater than the specified + value. + lt: + type: number + description: Find items with a property value less than the specified value. + gte: + type: number + description: >- + Find items with a property value greater than or equal the + specified value. + lte: + type: number + description: >- + Find items with a property value greater than or equal the + specified value. + startsWith: + type: string + description: >- + Find items with a property that begins with the specified + string. A case-insensitive comparison must be performed. + endsWith: + type: string + description: >- + Find items with a property that ends with the specified string. + A case-insensitive comparison must be performed. + contains: + type: string + description: >- + Find items with a property that contains with the specified + string. A case-insensitive comparison must be performed. + in: + type: array + items: + type: string + description: >- + Find items with a property that matches one of the specified + strings. A case-insensitive comparison must be performed. + sortFilter: + type: object + description: Sort the results + properties: + sort: + $ref: '#/components/schemas/sort' + sort: + type: array + description: | + An array of objects containing a property name and sort direction. + minItems: 1 + items: + type: object + required: + - field + properties: + field: + type: string + direction: + type: string + default: asc + enum: + - asc + - desc + example: + - field: 'eo:cloud_cover' + - field: providers + direction: desc + fieldsFilter: + type: object + description: Determines the shape of the features in the response + properties: + fields: + $ref: '#/components/schemas/fields' + fields: + description: | + The include and exclude members specify an array of + property names that are either included or excluded + from the result, respectively. If both include and + exclude are specified, include takes precedence. + Values should include the full JSON path of the property. + type: object + properties: + include: + type: array + items: + type: string + exclude: + type: array + items: + type: string + example: + include: + - id + - 'properties.eo:cloud_cover' + exclude: + - geometry + - properties.datetime + responses: + LandingPage: + description: |- + The landing page provides links to the API definition + (link relations `service-desc` and `service-doc`), + the Conformance declaration (path `/conformance`, + link relation `conformance`), and the Feature + Collections (path `/collections`, link relation + `data`). + content: + application/json: + schema: + $ref: '#/components/schemas/landingPage' + example: + title: Buildings in Bonn + description: >- + Access to data about buildings in the city of Bonn via a Web API + that conforms to the OGC API Features specification. + links: + - href: 'http://data.example.org/' + rel: self + type: application/json + title: this document + - href: 'http://data.example.org/api' + rel: service-desc + type: application/vnd.oai.openapi+json;version=3.0 + title: the API definition + - href: 'http://data.example.org/api.html' + rel: service-doc + type: text/html + title: the API documentation + - href: 'http://data.example.org/conformance' + rel: conformance + type: application/json + title: OGC API conformance classes implemented by this server + - href: 'http://data.example.org/collections' + rel: data + type: application/json + title: Information about the feature collections + text/html: + schema: + type: string + ConformanceDeclaration: + description: |- + The URIs of all conformance classes supported by the server. + To support "generic" clients that want to access multiple + OGC API Features implementations - and not "just" a specific + API / server, the server declares the conformance + classes it implements and conforms to. + content: + application/json: + schema: + $ref: '#/components/schemas/confClasses' + example: + conformsTo: + - 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core' + - 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/oas30' + - 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/html' + - 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson' + text/html: + schema: + type: string + Collections: + description: >- + The feature collections shared by this API. The dataset is organized as + one or more feature collections. This resource provides information + about and access to the collections. The response contains the list of + collections. For each collection, a link to the items in the collection + (path `/collections/{collectionId}/items`, link relation `items`) as + well as key information about the collection. This information includes: + * A local identifier for the collection that is unique for the dataset; + * A list of coordinate reference systems (CRS) in which geometries may + be returned by the server. The first CRS is the default coordinate + reference system (the default is always WGS 84 with axis order + longitude/latitude); * An optional title and description for the + collection; * An optional extent that can be used to provide an + indication of the spatial and temporal extent of the collection - + typically derived from the data; * An optional indicator about the type + of the items in the collection (the default value, if the indicator is + not provided, is 'feature'). + content: + application/json: + schema: + $ref: '#/components/schemas/collections' + text/html: + schema: + type: string + Collection: + description: >- + Information about the feature collection with id `collectionId`. The + response contains a link to the items in the collection (path + `/collections/{collectionId}/items`, link relation `items`) as well as + key information about the collection. This information includes: * A + local identifier for the collection that is unique for the dataset; * A + list of coordinate reference systems (CRS) in which geometries may be + returned by the server. The first CRS is the default coordinate + reference system (the default is always WGS 84 with axis order + longitude/latitude); * An optional title and description for the + collection; * An optional extent that can be used to provide an + indication of the spatial and temporal extent of the collection - + typically derived from the data; * An optional indicator about the type + of the items in the collection (the default value, if the indicator is + not provided, is 'feature'). + content: + application/json: + schema: + $ref: '#/components/schemas/collection' + text/html: + schema: + type: string + Features: + description: >- + The response is a document consisting of features in the collection. The + features included in the response are determined by the server based on + the query parameters of the request. To support access to larger + collections without overloading the client, the API supports paged + access with links to the next page, if more features are selected that + the page size. The `bbox` and `datetime` parameter can be used to select + only a subset of the features in the collection (the features that are + in the bounding box or time interval). The `bbox` parameter matches all + features in the collection that are not associated with a location, too. + The `datetime` parameter matches all features in the collection that are + not associated with a time stamp or interval, too. The `limit` parameter + may be used to control the subset of the selected features that should + be returned in the response, the page size. Each page may include + information about the number of selected and returned features + (`numberMatched` and `numberReturned`) as well as links to support + paging (link relation `next`). + content: + application/geo+json: + schema: + $ref: '#/components/schemas/featureCollectionGeoJSON' + text/html: + schema: + type: string + Feature: + description: |- + fetch the feature with id `featureId` in the feature collection + with id `collectionId` + content: + application/geo+json: + schema: + $ref: '#/components/schemas/item' + text/html: + schema: + type: string + InvalidParameter: + description: A query parameter has an invalid value. + content: + application/json: + schema: + $ref: '#/components/schemas/exception' + text/html: + schema: + type: string + NotFound: + description: The requested URI was not found. + ServerError: + description: A server error occurred. + content: + application/json: + schema: + $ref: '#/components/schemas/exception' + text/html: + schema: + type: string +servers: + - url: 'http://dev.cool-sat.com' + description: Development server + - url: 'http://www.cool-sat.com' + description: Production server From b22ff607b16f790110a2762d85e2ad2ed2388394 Mon Sep 17 00:00:00 2001 From: Pete Shepley Date: Wed, 11 Dec 2019 09:42:52 -0500 Subject: [PATCH 04/10] Add serverless deployment --- .gitignore | 2 ++ ops/serverless.yml | 20 ++++++++++++ ops/settings.dev.yml | 0 package.json | 5 +-- packages/api/index.js | 52 +++++++++++++++---------------- packages/api/package.json | 3 +- packages/api/webpack.config.js | 30 +++++++++++------- packages/ingest/package.json | 3 +- packages/ingest/webpack.config.js | 27 +++++++++------- 9 files changed, 87 insertions(+), 55 deletions(-) create mode 100644 ops/serverless.yml create mode 100644 ops/settings.dev.yml diff --git a/.gitignore b/.gitignore index 24ca8c89..58e84a09 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ lerna-debug.log *.lerna_backup _book .idea/ +.DS_STORE +.serverless/ diff --git a/ops/serverless.yml b/ops/serverless.yml new file mode 100644 index 00000000..c67ded59 --- /dev/null +++ b/ops/serverless.yml @@ -0,0 +1,20 @@ +service: sat-api + +provider: + name: aws + runtime: nodejs12.x + stage: dev + region: us-east-1 + +package: + individually: true + +functions: + api: + handler: index.handler + package: + artifact: ../packages/api/dist/api.zip + ingest: + handler: index.handler + package: + artifact: ../packages/ingest/dist/ingest.zip diff --git a/ops/settings.dev.yml b/ops/settings.dev.yml new file mode 100644 index 00000000..e69de29b diff --git a/package.json b/package.json index 154308bb..14ff4ab4 100644 --- a/package.json +++ b/package.json @@ -23,5 +23,6 @@ "lerna": "^2.11.0", "shins": "^2.3.2-3", "widdershins": "^3.6.6" - } -} + }, + "name": "sat-api" +} \ No newline at end of file diff --git a/packages/api/index.js b/packages/api/index.js index fdd4d4b9..1afb63cc 100644 --- a/packages/api/index.js +++ b/packages/api/index.js @@ -1,11 +1,6 @@ -/* eslint-disable new-cap, no-lonely-if */ - -'use strict' - const satlib = require('@sat-utils/api-lib') -module.exports.handler = async (event) => { - // determine endpoint +function determineEndpoint(event) { let endpoint = process.env.SATAPI_URL if (typeof endpoint === 'undefined') { if ('X-Forwarded-Host' in event.headers) { @@ -17,21 +12,10 @@ module.exports.handler = async (event) => { } } } + return endpoint +} - const buildResponse = async (statusCode, result) => { - const response = { - statusCode, - headers: { - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', // Required for CORS support to work - 'Access-Control-Allow-Credentials': true - }, - body: result - } - return response - } - - // get payload +function buildRequest(event) { const method = event.httpMethod let query = {} if (method === 'POST' && event.body) { @@ -39,12 +23,26 @@ module.exports.handler = async (event) => { } else if (method === 'GET' && event.queryStringParameters) { query = event.queryStringParameters } - const result = await satlib.api.API(event.path, query, satlib.es, endpoint) - let returnResponse - if (result instanceof Error) { - returnResponse = buildResponse(404, result.message) - } else { - returnResponse = buildResponse(200, JSON.stringify(result)) + return query +} + +function buildResponse(statusCode, result) { + return { + statusCode, + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', // Required for CORS support to work + 'Access-Control-Allow-Credentials': true + }, + body: result } - return returnResponse +} + +module.exports.handler = async (event) => { + const endpoint = determineEndpoint(event) + const query = buildRequest(event) + const result = await satlib.api.API(event.path, query, satlib.es, endpoint) + return result instanceof Error ? + buildResponse(404, result.message) : + buildResponse(200, JSON.stringify(result)) } diff --git a/packages/api/package.json b/packages/api/package.json index f93f1903..fe448e16 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -34,6 +34,7 @@ "proxyquire": "^2.1.0", "sinon": "^7.1.1", "webpack": "~4.5.0", - "webpack-cli": "~2.0.14" + "webpack-cli": "~2.0.14", + "zip-webpack-plugin": "^3.0.0" } } diff --git a/packages/api/webpack.config.js b/packages/api/webpack.config.js index 0ca6a60f..12876427 100644 --- a/packages/api/webpack.config.js +++ b/packages/api/webpack.config.js @@ -1,12 +1,12 @@ +const path = require('path') +const ZipPlugin = require('zip-webpack-plugin') -const path = require('path'); +let mode = 'development' +let devtool = 'inline-source-map' -let mode = 'development'; -let devtool = 'inline-source-map'; - -if(process.env.PRODUCTION) { - mode = 'production', - devtool = false +if (process.env.PRODUCTION) { + mode = 'production' + devtool = false } module.exports = { @@ -18,10 +18,16 @@ module.exports = { path: path.resolve(__dirname, 'dist') }, externals: [ - 'aws-sdk', - 'electron', - {'formidable': 'url'} + 'aws-sdk' ], devtool, - target: 'node' -}; \ No newline at end of file + optimization: { + usedExports: true + }, + target: 'node', + plugins: [ + new ZipPlugin({ + filename: 'api.zip' + }) + ] +} diff --git a/packages/ingest/package.json b/packages/ingest/package.json index db94d377..5b2a0e8c 100644 --- a/packages/ingest/package.json +++ b/packages/ingest/package.json @@ -38,6 +38,7 @@ "proxyquire": "^2.1.0", "sinon": "^7.1.1", "webpack": "~4.5.0", - "webpack-cli": "~2.0.14" + "webpack-cli": "~2.0.14", + "zip-webpack-plugin": "^3.0.0" } } diff --git a/packages/ingest/webpack.config.js b/packages/ingest/webpack.config.js index 0ca6a60f..b06fde72 100644 --- a/packages/ingest/webpack.config.js +++ b/packages/ingest/webpack.config.js @@ -1,12 +1,12 @@ +const path = require('path') +const ZipPlugin = require('zip-webpack-plugin') -const path = require('path'); +let mode = 'development' +let devtool = 'inline-source-map' -let mode = 'development'; -let devtool = 'inline-source-map'; - -if(process.env.PRODUCTION) { - mode = 'production', - devtool = false +if (process.env.PRODUCTION) { + mode = 'production' + devtool = false } module.exports = { @@ -18,10 +18,13 @@ module.exports = { path: path.resolve(__dirname, 'dist') }, externals: [ - 'aws-sdk', - 'electron', - {'formidable': 'url'} + 'aws-sdk' ], devtool, - target: 'node' -}; \ No newline at end of file + target: 'node', + plugins: [ + new ZipPlugin({ + filename: 'ingest.zip' + }) + ] +} From e71afe6cfe480dae41d88d96acf7358e71894461 Mon Sep 17 00:00:00 2001 From: Matthew Hanson Date: Wed, 18 Dec 2019 14:26:19 -0500 Subject: [PATCH 05/10] reorg serverless configs --- .nvmrc | 2 +- ops/serverless.yml | 20 ---------- ops/settings.dev.yml | 0 package.json | 6 ++- packages/api-lib/libs/es.js | 16 +++++--- packages/api-lib/libs/logger.js | 4 +- serverless.yml | 65 +++++++++++++++++++++++++++++++++ 7 files changed, 84 insertions(+), 29 deletions(-) delete mode 100644 ops/serverless.yml delete mode 100644 ops/settings.dev.yml create mode 100644 serverless.yml diff --git a/.nvmrc b/.nvmrc index 22ec1e64..87e3933a 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -8.10 +12.13 diff --git a/ops/serverless.yml b/ops/serverless.yml deleted file mode 100644 index c67ded59..00000000 --- a/ops/serverless.yml +++ /dev/null @@ -1,20 +0,0 @@ -service: sat-api - -provider: - name: aws - runtime: nodejs12.x - stage: dev - region: us-east-1 - -package: - individually: true - -functions: - api: - handler: index.handler - package: - artifact: ../packages/api/dist/api.zip - ingest: - handler: index.handler - package: - artifact: ../packages/ingest/dist/ingest.zip diff --git a/ops/settings.dev.yml b/ops/settings.dev.yml deleted file mode 100644 index e69de29b..00000000 diff --git a/package.json b/package.json index 14ff4ab4..64dc3104 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "test": "lerna run test", "update": "lerna publish --skip-git --skip-npm", "eslint": "eslint packages/* --ext .js", + "deploy": "sls deploy", "build-api-docs": "yarn widdershins --search false --language_tabs 'nodejs:NodeJS' 'python:Python' --summary ./packages/api-lib/api-spec.yaml -o ./docs/api.md & yarn shins --inline --logo ./docs/images/logo.png -o ./docs/index.html ./docs/api.md" }, "devDependencies": { @@ -22,7 +23,10 @@ "eslint-plugin-react": "^7.7.0", "lerna": "^2.11.0", "shins": "^2.3.2-3", - "widdershins": "^3.6.6" + "widdershins": "^3.6.6", + "serverless": "^1.53.0", + "serverless-step-functions": "^2.11.0", + "serverless-pseudo-parameters": "^2.5.0" }, "name": "sat-api" } \ No newline at end of file diff --git a/packages/api-lib/libs/es.js b/packages/api-lib/libs/es.js index 2f0b99ab..e926650b 100644 --- a/packages/api-lib/libs/es.js +++ b/packages/api-lib/libs/es.js @@ -14,14 +14,15 @@ searching records, and managing the indexes. It looks for the ES_HOST environmen variable which is the URL to the elasticsearch host */ -// Connect to an Elasticsearch cluster +// Connect to an Elasticsearch instance async function connect() { let esConfig - let client - + logger.info('connecting') // use local client if (!process.env.ES_HOST) { - client = new elasticsearch.Client({ host: 'localhost:9200' }) + esConfig = { + host: 'localhost:9200' + } } else { await new Promise((resolve, reject) => AWS.config.getCredentials((err) => { if (err) return reject(err) @@ -42,11 +43,16 @@ async function connect() { // Note that this doesn't abort the query. requestTimeout: 120000 // milliseconds } - client = new elasticsearch.Client(esConfig) } + logger.debug(`Elasticsearch config: ${JSON.stringify(esConfig)}`) + const client = new elasticsearch.Client(esConfig) + + logger.info(`Client`) + await new Promise((resolve, reject) => client.ping({ requestTimeout: 1000 }, (err) => { + logger.info(`err: ${err}`) if (err) { reject('Unable to connect to elasticsearch') } else { diff --git a/packages/api-lib/libs/logger.js b/packages/api-lib/libs/logger.js index af1177b9..1d6495cb 100644 --- a/packages/api-lib/libs/logger.js +++ b/packages/api-lib/libs/logger.js @@ -1,7 +1,7 @@ const winston = require('winston') -const logger = new (winston.Logger)({ - level: process.env.LOG_LEVEL || 'info', +const logger = winston.createLogger({ + level: process.env.LOG_LEVEL || 'debug', transports: [ new (winston.transports.Console)({ timestamp: true }) ] diff --git a/serverless.yml b/serverless.yml new file mode 100644 index 00000000..c81b8e66 --- /dev/null +++ b/serverless.yml @@ -0,0 +1,65 @@ +service: stac-api + +provider: + name: aws + runtime: nodejs12.x + stage: alpha + region: us-west-2 + environment: + LOG_LEVEL: DEBUG + ES_HOST: + Fn::GetAtt: [ElasticSearchInstance, DomainEndpoint] +# iamRoleStatements: +# - Effect: "Allow" +# Resource: "*" +# Action: +# - "sns:*" + +package: + individually: true + +functions: + api: + handler: index.handler + package: + artifact: packages/api/dist/api.zip + events: + - http: ANY {proxy+} + ingest: + handler: index.handler + package: + artifact: packages/ingest/dist/ingest.zip + events: + - sqs: + arn: + Fn::GetAtt: [ingestQueue, Arn] + #events: + # - sns: + # topicName: ${self:service}-${self:provider.stage}-ingest-queue + # displayName: STAC Item ingest queue + +resources: + Resources: +# IngestSNS: +# Type: AWS::SNS::Subscription + ingestQueue: + Type: AWS::SQS::Queue + Properties: + DelaySeconds: 1 + QueueName: ${self:service}-${self:provider.stage}-ingest-queue + ElasticSearchInstance: + Type: AWS::Elasticsearch::Domain + Properties: + EBSOptions: + EBSEnabled: true + VolumeType: gp2 + VolumeSize: 35 + ElasticsearchClusterConfig: + InstanceType: t2.small.elasticsearch + InstanceCount: 3 + DedicatedMasterEnabled: false + ZoneAwarenessEnabled: false + ElasticsearchVersion: 6.8 + +plugins: + - serverless-pseudo-parameters \ No newline at end of file From d9919316c75a60c0d518bdd3c2e359fd06c01e58 Mon Sep 17 00:00:00 2001 From: Matthew Hanson Date: Wed, 18 Dec 2019 17:13:50 -0500 Subject: [PATCH 06/10] update logging --- .../libs/ElasticSearchWriteableStream.js | 2 +- packages/api-lib/libs/api.js | 3 +-- packages/api-lib/libs/es.js | 9 +++----- packages/api-lib/libs/logger.js | 22 ++++++++++++++++++- packages/api-lib/package.json | 3 ++- packages/ingest/index.js | 6 ++--- serverless.yml | 12 +++++----- 7 files changed, 37 insertions(+), 20 deletions(-) diff --git a/packages/api-lib/libs/ElasticSearchWriteableStream.js b/packages/api-lib/libs/ElasticSearchWriteableStream.js index eaf2607c..e04e106a 100644 --- a/packages/api-lib/libs/ElasticSearchWriteableStream.js +++ b/packages/api-lib/libs/ElasticSearchWriteableStream.js @@ -1,5 +1,5 @@ const stream = require('stream') -const logger = require('./logger') +const logger = console //require('./logger') class ElasticSearchWritableStream extends stream.Writable { constructor(config, options) { diff --git a/packages/api-lib/libs/api.js b/packages/api-lib/libs/api.js index 5c08a5c5..ac21ac31 100644 --- a/packages/api-lib/libs/api.js +++ b/packages/api-lib/libs/api.js @@ -1,9 +1,8 @@ const gjv = require('geojson-validation') const extent = require('@mapbox/extent') -const logger = require('./logger') const fs = require('fs') const yaml = require('js-yaml') - +const logger = console //require('./logger') // max number of collections to retrieve const COLLECTION_LIMIT = process.env.SATAPI_COLLECTION_LIMIT || 100 diff --git a/packages/api-lib/libs/es.js b/packages/api-lib/libs/es.js index e926650b..a90d95ff 100644 --- a/packages/api-lib/libs/es.js +++ b/packages/api-lib/libs/es.js @@ -5,7 +5,7 @@ const httpAwsEs = require('http-aws-es') const elasticsearch = require('elasticsearch') const through2 = require('through2') const ElasticsearchWritableStream = require('./ElasticSearchWriteableStream') -const logger = require('./logger') +const logger = console //require('./logger') let _esClient /* @@ -17,7 +17,7 @@ variable which is the URL to the elasticsearch host // Connect to an Elasticsearch instance async function connect() { let esConfig - logger.info('connecting') + // use local client if (!process.env.ES_HOST) { esConfig = { @@ -48,13 +48,10 @@ async function connect() { logger.debug(`Elasticsearch config: ${JSON.stringify(esConfig)}`) const client = new elasticsearch.Client(esConfig) - logger.info(`Client`) - await new Promise((resolve, reject) => client.ping({ requestTimeout: 1000 }, (err) => { - logger.info(`err: ${err}`) if (err) { - reject('Unable to connect to elasticsearch') + reject(`Unable to connect to elasticsearch: ${err}`) } else { resolve() } diff --git a/packages/api-lib/libs/logger.js b/packages/api-lib/libs/logger.js index 1d6495cb..29aa81b6 100644 --- a/packages/api-lib/libs/logger.js +++ b/packages/api-lib/libs/logger.js @@ -1,10 +1,30 @@ const winston = require('winston') +const WinstonCloudWatch = require('winston-cloudwatch') + const logger = winston.createLogger({ level: process.env.LOG_LEVEL || 'debug', + format: winston.format.combine( + winston.format.timestamp(), + winston.format.colorize(), + winston.format.printf((info) => `[${info.timestamp}] ${info.level}: ${info.message}`) + ), transports: [ - new (winston.transports.Console)({ timestamp: true }) +// new winston.transports.Console({ +// format: winston.format.simple(), +// level: process.env.LOG_LEVEL || 'debug' +// }), + new WinstonCloudWatch({ + logGroupName: 'testing', + logStreamName: 'first' + }) ] }) +logger.stream = { + write: (info) => { + logger.info(info) + } +} + module.exports = logger diff --git a/packages/api-lib/package.json b/packages/api-lib/package.json index 11735cb9..95d34387 100644 --- a/packages/api-lib/package.json +++ b/packages/api-lib/package.json @@ -39,7 +39,8 @@ "request-promise-native": "^1.0.5", "through2": "^3.0.1", "uuid": "^3.3.2", - "winston": "^2.2.0" + "winston": "^3.2.0", + "winston-cloudwatch": "^2.3.0" }, "devDependencies": { "ava": "^0.16.0", diff --git a/packages/ingest/index.js b/packages/ingest/index.js index 7aa55710..721c588d 100644 --- a/packages/ingest/index.js +++ b/packages/ingest/index.js @@ -1,11 +1,11 @@ 'use strict' -const AWS = require('aws-sdk') const satlib = require('@sat-utils/api-lib') +const logger = console module.exports.handler = async function handler(event) { - console.log(`Ingest Event: ${JSON.stringify(event)}`) + logger.info(`Ingest Event: ${JSON.stringify(event)}`) try { if (event.Records && (event.Records[0].EventSource === 'aws:sns')) { // event is SNS message of updated file on s3 @@ -24,7 +24,7 @@ module.exports.handler = async function handler(event) { } } = s3Record const url = `https://${bucketName}.s3.amazonaws.com/${key}` - console.log(`Ingesting catalog file ${url}`) + logger.log(`Ingesting catalog file ${url}`) const recursive = false return satlib.ingest.ingest(url, satlib.es, recursive) }) diff --git a/serverless.yml b/serverless.yml index c81b8e66..73da2f13 100644 --- a/serverless.yml +++ b/serverless.yml @@ -9,11 +9,10 @@ provider: LOG_LEVEL: DEBUG ES_HOST: Fn::GetAtt: [ElasticSearchInstance, DomainEndpoint] -# iamRoleStatements: -# - Effect: "Allow" -# Resource: "*" -# Action: -# - "sns:*" + iamRoleStatements: + - Effect: "Allow" + Resource: "arn:aws:es:#{AWS::Region}:#{AWS::AccountId}:domain/*" + Action: "es:*" package: individually: true @@ -27,6 +26,7 @@ functions: - http: ANY {proxy+} ingest: handler: index.handler + timeout: 15 package: artifact: packages/ingest/dist/ingest.zip events: @@ -36,7 +36,7 @@ functions: #events: # - sns: # topicName: ${self:service}-${self:provider.stage}-ingest-queue - # displayName: STAC Item ingest queue + # displayName: STAC Item ingest topic resources: Resources: From 06643a079457d4825d1a3a49b8a0f55c1d83ec97 Mon Sep 17 00:00:00 2001 From: Matthew Hanson Date: Wed, 18 Dec 2019 17:21:45 -0500 Subject: [PATCH 07/10] update serverless config --- serverless.yml | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/serverless.yml b/serverless.yml index 73da2f13..7036cade 100644 --- a/serverless.yml +++ b/serverless.yml @@ -22,17 +22,26 @@ functions: handler: index.handler package: artifact: packages/api/dist/api.zip + environment: + STAC_ID: "stac-api" + STAC_TITLE: "STAC API" + STAC_DESCRIPTION: "STAC API" + STAC_VERSION: 0.8.1 events: + - http: ANY / - http: ANY {proxy+} ingest: handler: index.handler - timeout: 15 + timeout: 900 package: artifact: packages/ingest/dist/ingest.zip events: - - sqs: - arn: - Fn::GetAtt: [ingestQueue, Arn] + - sns: + topicName: ${self:service}-${self:provider.stage}-queue + displayName: Ingest STAC Item + # - sqs: + # arn: + # Fn::GetAtt: [ingestQueue, Arn] #events: # - sns: # topicName: ${self:service}-${self:provider.stage}-ingest-queue @@ -40,13 +49,11 @@ functions: resources: Resources: -# IngestSNS: -# Type: AWS::SNS::Subscription - ingestQueue: - Type: AWS::SQS::Queue - Properties: - DelaySeconds: 1 - QueueName: ${self:service}-${self:provider.stage}-ingest-queue +# ingestQueue: +# Type: AWS::SQS::Queue +# Properties: +# DelaySeconds: 1 +# QueueName: ${self:service}-${self:provider.stage}-ingest-queue ElasticSearchInstance: Type: AWS::Elasticsearch::Domain Properties: From 91fa2b159dff555b58c904d08490e34fe3db5ca6 Mon Sep 17 00:00:00 2001 From: Matthew Hanson Date: Thu, 19 Dec 2019 00:12:00 -0500 Subject: [PATCH 08/10] include api.yaml in package --- package.json | 8 +- packages/api-lib/api-definition.yaml | 1954 -------------------------- packages/api-lib/api-spec.yaml | 940 ------------- packages/api-lib/libs/api.js | 7 +- packages/api-lib/libs/ingest.js | 8 +- packages/api-lib/libs/logger.js | 16 +- packages/api-lib/package.json | 5 +- packages/{api-lib => api}/api.yaml | 0 packages/api/package.json | 7 +- packages/api/webpack.config.js | 7 + 10 files changed, 27 insertions(+), 2925 deletions(-) delete mode 100644 packages/api-lib/api-definition.yaml delete mode 100644 packages/api-lib/api-spec.yaml rename packages/{api-lib => api}/api.yaml (100%) diff --git a/package.json b/package.json index 64dc3104..3b87d494 100644 --- a/package.json +++ b/package.json @@ -22,11 +22,11 @@ "eslint-plugin-jsx-a11y": "^6.0.3", "eslint-plugin-react": "^7.7.0", "lerna": "^2.11.0", - "shins": "^2.3.2-3", - "widdershins": "^3.6.6", "serverless": "^1.53.0", + "serverless-pseudo-parameters": "^2.5.0", "serverless-step-functions": "^2.11.0", - "serverless-pseudo-parameters": "^2.5.0" + "shins": "^2.3.2-3", + "widdershins": "^3.6.6" }, "name": "sat-api" -} \ No newline at end of file +} diff --git a/packages/api-lib/api-definition.yaml b/packages/api-lib/api-definition.yaml deleted file mode 100644 index ea66e6a9..00000000 --- a/packages/api-lib/api-definition.yaml +++ /dev/null @@ -1,1954 +0,0 @@ -openapi: 3.0.1 -info: - title: The SpatioTemporal Asset Catalog API + Extensions - version: 0.8.0 - license: - name: Apache License 2.0 - url: 'http://www.apache.org/licenses/LICENSE-2.0' - description: >- - This is an OpenAPI definition of the core SpatioTemporal Asset Catalog API - specification. Any service that implements this endpoint to allow search of - spatiotemporal assets can be considered a STAC API. The endpoint is also - available as an OpenAPI fragment that can be integrated with other OpenAPI - definitions, and is designed to slot seamlessly into a WFS 3 API definition. - contact: - name: STAC Specification - url: 'http://stacspec.org' -tags: - - name: Capabilities - description: essential characteristics of this API - - name: Data - description: access to data (features) - - name: STAC - description: Extension to WFS3 Core to support STAC metadata model and search API - - name: Transaction Extension - description: >- - STAC-specific operations to add, remove, and edit items within WFS3 - collections. -paths: - /: - get: - tags: - - Capabilities - summary: landing page - description: |- - The landing page provides links to the API definition, the conformance - statements and to the feature collections in this dataset. - operationId: getLandingPage - responses: - '200': - $ref: '#/components/responses/LandingPage' - '500': - $ref: '#/components/responses/ServerError' - /conformance: - get: - tags: - - Capabilities - summary: information about specifications that this API conforms to - description: |- - A list of all conformance classes specified in a standard that the - server conforms to. - operationId: getConformanceDeclaration - responses: - '200': - $ref: '#/components/responses/ConformanceDeclaration' - '500': - $ref: '#/components/responses/ServerError' - /collections: - get: - tags: - - Capabilities - summary: the feature collections in the dataset - operationId: getCollections - responses: - '200': - $ref: '#/components/responses/Collections' - '500': - $ref: '#/components/responses/ServerError' - '/collections/{collectionId}': - get: - tags: - - Capabilities - summary: describe the feature collection with id `collectionId` - operationId: describeCollection - parameters: - - $ref: '#/components/parameters/collectionId' - responses: - '200': - $ref: '#/components/responses/Collection' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/ServerError' - '/collections/{collectionId}/items': - get: - tags: - - Data - summary: fetch features - description: |- - Fetch features of the feature collection with id `collectionId`. - - Every feature in a dataset belongs to a collection. A dataset may - consist of multiple feature collections. A feature collection is often a - collection of features of a similar type, based on a common schema. - - Use content negotiation to request HTML or GeoJSON. - operationId: getFeatures - parameters: - - $ref: '#/components/parameters/collectionId' - - $ref: '#/components/parameters/limit' - - $ref: '#/components/parameters/bbox' - - $ref: '#/components/parameters/datetime' - responses: - '200': - $ref: '#/components/responses/Features' - '400': - $ref: '#/components/responses/InvalidParameter' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/ServerError' - post: - summary: add a new feature to a collection - description: create a new feature in a specific collection - operationId: postFeature - tags: - - Transaction Extension - parameters: - - $ref: '#/components/parameters/collectionId' - requestBody: - content: - application/json: - schema: - oneOf: - - $ref: '#/components/schemas/item' - - $ref: '#/components/schemas/itemCollection' - responses: - '201': - description: Status of the create request. - headers: - Location: - description: A link to the item - schema: - type: string - format: url - ETag: - schema: - type: string - description: A string to ensure the item has not been modified - content: - application/geo+json: - schema: - type: string - text/html: - schema: - type: string - '400': - $ref: '#/components/responses/BadRequest' - 5XX: - $ref: '#/components/responses/InternalServerError' - default: - description: An error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - text/html: - schema: - type: string - '/collections/{collectionId}/items/{featureId}': - get: - tags: - - Data - summary: fetch a single feature - description: |- - Fetch the feature with id `featureId` in the feature collection - with id `collectionId`. - - Use content negotiation to request HTML or GeoJSON. - operationId: getFeature - parameters: - - $ref: '#/components/parameters/collectionId' - - $ref: '#/components/parameters/featureId' - responses: - '200': - $ref: '#/components/responses/Feature' - headers: - ETag: - schema: - type: string - description: A string to ensure the item has not been modified - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/ServerError' - put: - summary: update an existing feature by Id with a complete item definition - description: >- - Use this method to update an existing feature. Requires the entire - GeoJSON description be submitted. - operationId: putFeature - tags: - - Transaction Extension - parameters: - - $ref: '#/components/parameters/collectionId' - - $ref: '#/components/parameters/featureId' - - $ref: '#/components/parameters/IfMatch' - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/item' - responses: - '200': - description: Status of the update request. - headers: - ETag: - schema: - type: string - description: A string to ensure the item has not been modified - content: - text/html: - schema: - type: string - application/json: - schema: - type: string - '400': - $ref: '#/components/responses/BadRequest' - '404': - $ref: '#/components/responses/NotFound' - 5XX: - $ref: '#/components/responses/InternalServerError' - default: - description: An error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - text/html: - schema: - type: string - patch: - summary: update an existing feature by Id with a partial item definition - description: >- - Use this method to update an existing feature. Requires a GeoJSON - fragement (containing the fields to be updated) be submitted. - operationId: patchFeature - tags: - - Transaction Extension - parameters: - - $ref: '#/components/parameters/collectionId' - - $ref: '#/components/parameters/featureId' - - $ref: '#/components/parameters/IfMatchOptional' - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/partialItem' - responses: - '200': - description: Status of the update request. - headers: - ETag: - schema: - type: string - description: A string to ensure the item has not been modified - content: - text/html: - schema: - type: string - application/json: - schema: - type: string - '400': - $ref: '#/components/responses/BadRequest' - '404': - $ref: '#/components/responses/NotFound' - 5XX: - $ref: '#/components/responses/InternalServerError' - default: - description: An error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - text/html: - schema: - type: string - delete: - summary: delete an existing feature by Id - description: Use this method to delete an existing feature. - operationId: deleteFeature - tags: - - Transaction Extension - parameters: - - $ref: '#/components/parameters/collectionId' - - $ref: '#/components/parameters/featureId' - - $ref: '#/components/parameters/IfMatch' - responses: - '204': - description: Status of the delete request. - '400': - $ref: '#/components/responses/BadRequest' - '404': - $ref: '#/components/responses/NotFound' - 5XX: - $ref: '#/components/responses/InternalServerError' - default: - description: An error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - text/html: - schema: - type: string - /stac: - get: - summary: Return the root catalog or collection. - description: >- - Returns the root STAC Catalog or STAC Collection that is the entry point - for users to browse with STAC Browser or for search engines to crawl. - This can either return a single STAC Collection or more commonly a STAC - catalog that usually lists sub-catalogs of STAC Collections, i.e. a - simple catalog that lists all collections available through the API. - tags: - - STAC - responses: - '200': - description: A catalog JSON definition. Used as an entry point for a crawler. - content: - application/json: - schema: - $ref: '#/components/schemas/catalogDefinition' - /stac/search: - get: - summary: Search STAC items with simple filtering. - description: >- - Retrieve Items matching filters. Intended as a shorthand API for simple - queries. - - - This method is optional, but you MUST implement `POST /stac/search` if - you want to implement this method. - operationId: getSearchSTAC - tags: - - STAC - parameters: - - $ref: '#/components/parameters/bbox' - - $ref: '#/components/parameters/datetime' - - $ref: '#/components/parameters/limit' - - $ref: '#/components/parameters/next' - - $ref: '#/components/parameters/ids' - - $ref: '#/components/parameters/collectionsArray' - - $ref: '#/components/parameters/query' - - $ref: '#/components/parameters/sort' - - $ref: '#/components/parameters/fields' - responses: - '200': - description: A feature collection. - content: - application/geo+json: - schema: - $ref: '#/components/schemas/itemCollection' - text/html: - schema: - type: string - default: - description: An error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - text/html: - schema: - type: string - post: - summary: Search STAC items with full-featured filtering. - description: >- - retrieve items matching filters. Intended as the standard, full-featured - query API. - - - This method is mandatory to implement if `GET /stac/search` is - implemented. If this endpoint is implemented on a server, it is required - to add a link with `rel` set to `search` to the `links` array in `GET - /stac` that refers to this endpoint. - operationId: postSearchSTAC - tags: - - STAC - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/searchBody' - responses: - '200': - description: A feature collection. - content: - application/geo+json: - schema: - $ref: '#/components/schemas/itemCollection' - text/html: - schema: - type: string - default: - description: An error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - text/html: - schema: - type: string -components: - parameters: - collectionId: - name: collectionId - in: path - description: local identifier of a collection - required: true - schema: - type: string - featureId: - name: featureId - in: path - description: local identifier of a feature - required: true - schema: - type: string - limit: - name: limit - in: query - description: The maximum number of results to return (page size). Defaults to 10 - required: false - schema: - $ref: '#/components/schemas/limit' - style: form - explode: false - next: - name: next - in: query - description: >- - The token to retrieve the next set of results, e.g., offset, page, - continuation token - required: false - schema: - $ref: '#/components/schemas/next' - style: form - ids: - name: ids - in: query - description: > - Array of Item ids to return. All other filter parameters that further - restrict the number of - - search results (except `next` and `limit`) are ignored - required: false - schema: - $ref: '#/components/schemas/ids' - explode: false - collectionsArray: - name: collections - in: query - description: | - Array of Collection IDs to include in the search for items. - Only Items in one of the provided Collections will be searched - required: false - schema: - $ref: '#/components/schemas/collectionsArray' - explode: false - bbox: - name: bbox - in: query - description: | - Only features that have a geometry that intersects the bounding box are - selected. The bounding box is provided as four or six numbers, - depending on whether the coordinate reference system includes a - vertical axis (elevation or depth): - - * Lower left corner, coordinate axis 1 - * Lower left corner, coordinate axis 2 - * Lower left corner, coordinate axis 3 (optional) - * Upper right corner, coordinate axis 1 - * Upper right corner, coordinate axis 2 - * Upper right corner, coordinate axis 3 (optional) - - The coordinate reference system of the values is WGS84 - longitude/latitude (http://www.opengis.net/def/crs/OGC/1.3/CRS84) unless - a different coordinate reference system is specified in the parameter - `bbox-crs`. - - For WGS84 longitude/latitude the values are in most cases the sequence - of minimum longitude, minimum latitude, maximum longitude and maximum - latitude. However, in cases where the box spans the antimeridian the - first value (west-most box edge) is larger than the third value - (east-most box edge). - - - If a feature has multiple spatial geometry properties, it is the - decision of the server whether only a single spatial geometry property - is used to determine the extent or all relevant geometries. - required: false - schema: - $ref: '#/components/schemas/bbox' - style: form - explode: false - datetime: - name: datetime - in: query - description: >- - Either a date-time or an interval, open or closed. Date and time - expressions - - adhere to RFC 3339. Open intervals are expressed using double-dots. - - - Examples: - - - * A date-time: "2018-02-12T23:20:50Z" - - * A closed interval: "2018-02-12T00:00:00Z/2018-03-18T12:31:12Z" - - * Open intervals: "2018-02-12T00:00:00Z/.." or "../2018-03-18T12:31:12Z" - - - Only features that have a temporal property that intersects the value of - - `datetime` are selected. - - - If a feature has multiple temporal properties, it is the decision of the - - server whether only a single temporal property is used to determine - - the extent or all relevant temporal properties. - schema: - $ref: '#/components/schemas/datetime' - required: false - explode: false - style: form - query: - name: query - in: query - description: >- - query for properties in items. Use the JSON form of the queryFilter used - in POST. - required: false - schema: - type: string - sort: - name: sort - in: query - description: Allows sorting results by the specified properties - required: false - schema: - $ref: '#/components/schemas/sort' - fields: - name: fields - in: query - description: Determines the shape of the features in the response - required: false - schema: - $ref: '#/components/schemas/fields' - style: form - explode: false - IfMatch: - name: If-Match - in: header - description: Only take the action if the ETag of the item still matches - required: true - schema: - type: string - IfMatchOptional: - name: If-Match - in: header - description: Only take the action if the ETag of the item still matches - required: false - schema: - type: string - schemas: - collection: - type: object - required: - - id - - links - properties: - id: - description: 'identifier of the collection used, for example, in URIs' - type: string - example: address - title: - description: human readable title of the collection - type: string - example: address - description: - description: a description of the features in the collection - type: string - example: An address. - links: - type: array - items: - $ref: '#/components/schemas/link' - example: - - href: 'http://data.example.com/buildings' - rel: item - - href: 'http://example.com/concepts/buildings.html' - rel: describedBy - type: text/html - extent: - $ref: '#/components/schemas/extent' - itemType: - description: >- - indicator about the type of the items in the collection (the default - value is 'feature'). - type: string - default: feature - crs: - description: the list of coordinate reference systems supported by the service - type: array - items: - type: string - default: - - 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' - example: - - 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' - - 'http://www.opengis.net/def/crs/EPSG/0/4326' - collections: - type: object - required: - - links - - collections - properties: - links: - type: array - items: - $ref: '#/components/schemas/link' - collections: - type: array - items: - $ref: '#/components/schemas/collection' - confClasses: - type: object - required: - - conformsTo - properties: - conformsTo: - type: array - items: - type: string - exception: - type: object - description: >- - Information about the exception: an error code plus an optional - description. - properties: - code: - type: string - description: - type: string - required: - - code - extent: - type: object - description: >- - The extent of the features in the collection. In the Core only spatial - and temporal - - extents are specified. Extensions may add additional members to - represent other - - extents, for example, thermal or pressure ranges. - properties: - spatial: - type: object - properties: - bbox: - description: >- - One or more bounding boxes that describe the spatial extent of - the dataset. - - In the Core only a single bounding box is supported. Extensions - may support - - additional areas. If multiple areas are provided, the union of - the bounding - - boxes describes the spatial extent. - type: array - minItems: 1 - items: - description: >- - West, south, east, north edges of the bounding box. The - coordinates - - are in the coordinate reference system specified in `crs`. By - default - - this is WGS 84 longitude/latitude. - type: array - minItems: 4 - maxItems: 6 - items: - type: number - example: - - -180 - - -90 - - 180 - - 90 - crs: - description: >- - Coordinate reference system of the coordinates in the spatial - extent - - (property `bbox`). The default reference system is WGS 84 - longitude/latitude. - - In the Core this is the only supported coordinate reference - system. - - Extensions may support additional coordinate reference systems - and add - - additional enum values. - type: string - enum: - - 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' - default: 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' - temporal: - description: The temporal extent of the features in the collection. - type: object - properties: - interval: - description: >- - One or more time intervals that describe the temporal extent of - the dataset. - - The value `null` is supported and indicates an open time - intervall. - - In the Core only a single time interval is supported. Extensions - may support - - multiple intervals. If multiple intervals are provided, the - union of the - - intervals describes the temporal extent. - type: array - minItems: 1 - items: - description: >- - Begin and end times of the time interval. The timestamps - - are in the coordinate reference system specified in `trs`. By - default - - this is the Gregorian calendar. - type: array - minItems: 2 - maxItems: 2 - items: - type: string - format: date-time - nullable: true - example: - - '2011-11-11T12:22:11Z' - - null - trs: - description: >- - Coordinate reference system of the coordinates in the temporal - extent - - (property `interval`). The default reference system is the - Gregorian calendar. - - In the Core this is the only supported temporal reference - system. - - Extensions may support additional temporal reference systems and - add - - additional enum values. - type: string - enum: - - 'http://www.opengis.net/def/uom/ISO-8601/0/Gregorian' - default: 'http://www.opengis.net/def/uom/ISO-8601/0/Gregorian' - featureCollectionGeoJSON: - type: object - required: - - type - - features - properties: - type: - type: string - enum: - - FeatureCollection - features: - type: array - items: - $ref: '#/components/schemas/featureGeoJSON' - links: - type: array - items: - $ref: '#/components/schemas/link' - timeStamp: - type: string - format: date-time - numberMatched: - type: integer - minimum: 0 - numberReturned: - type: integer - minimum: 0 - featureGeoJSON: - type: object - required: - - type - - geometry - - properties - properties: - type: - type: string - enum: - - Feature - geometry: - $ref: '#/components/schemas/geometryGeoJSON' - properties: - type: object - nullable: true - id: - oneOf: - - type: string - - type: integer - links: - type: array - items: - $ref: '#/components/schemas/link' - geometryGeoJSON: - oneOf: - - $ref: '#/components/schemas/pointGeoJSON' - - $ref: '#/components/schemas/multipointGeoJSON' - - $ref: '#/components/schemas/linestringGeoJSON' - - $ref: '#/components/schemas/multilinestringGeoJSON' - - $ref: '#/components/schemas/polygonGeoJSON' - - $ref: '#/components/schemas/multipolygonGeoJSON' - - $ref: '#/components/schemas/geometrycollectionGeoJSON' - geometrycollectionGeoJSON: - type: object - required: - - type - - geometries - properties: - type: - type: string - enum: - - GeometryCollection - geometries: - type: array - items: - $ref: '#/components/schemas/geometryGeoJSON' - landingPage: - type: object - required: - - links - properties: - title: - type: string - example: Buildings in Bonn - description: - type: string - example: >- - Access to data about buildings in the city of Bonn via a Web API - that conforms to the OGC API Features specification. - links: - type: array - items: - $ref: '#/components/schemas/link' - linestringGeoJSON: - type: object - required: - - type - - coordinates - properties: - type: - type: string - enum: - - LineString - coordinates: - type: array - minItems: 2 - items: - type: array - minItems: 2 - items: - type: number - link: - type: object - properties: - href: - type: string - example: 'http://www.geoserver.example/stac/naip/child/catalog.json' - format: url - rel: - type: string - example: child - type: - type: string - example: application/json - hreflang: - type: string - example: en - title: - type: string - example: NAIP Child Catalog - length: - type: integer - title: Link - description: A generic link. - required: - - href - - rel - multilinestringGeoJSON: - type: object - required: - - type - - coordinates - properties: - type: - type: string - enum: - - MultiLineString - coordinates: - type: array - items: - type: array - minItems: 2 - items: - type: array - minItems: 2 - items: - type: number - multipointGeoJSON: - type: object - required: - - type - - coordinates - properties: - type: - type: string - enum: - - MultiPoint - coordinates: - type: array - items: - type: array - minItems: 2 - items: - type: number - multipolygonGeoJSON: - type: object - required: - - type - - coordinates - properties: - type: - type: string - enum: - - MultiPolygon - coordinates: - type: array - items: - type: array - items: - type: array - minItems: 4 - items: - type: array - minItems: 2 - items: - type: number - pointGeoJSON: - type: object - required: - - type - - coordinates - properties: - type: - type: string - enum: - - Point - coordinates: - type: array - minItems: 2 - items: - type: number - polygonGeoJSON: - type: object - required: - - type - - coordinates - properties: - type: - type: string - enum: - - Polygon - coordinates: - type: array - items: - type: array - minItems: 4 - items: - type: array - minItems: 2 - items: - type: number - searchBody: - description: The search criteria - type: object - allOf: - - $ref: '#/components/schemas/bboxFilter' - - $ref: '#/components/schemas/datetimeFilter' - - $ref: '#/components/schemas/intersectsFilter' - - $ref: '#/components/schemas/nextFilter' - - $ref: '#/components/schemas/collectionsFilter' - - $ref: '#/components/schemas/idsFilter' - - $ref: '#/components/schemas/limitFilter' - - $ref: '#/components/schemas/queryFilter' - - $ref: '#/components/schemas/sortFilter' - - $ref: '#/components/schemas/fieldsFilter' - next: - type: string - description: >- - The token to retrieve the next set of results, e.g., offset, page, - continuation token - default: null - limit: - type: integer - example: 10 - description: The maximum number of results to return (page size). Defaults to 10 - bbox: - description: | - Only features that have a geometry that intersects the bounding box are - selected. The bounding box is provided as four or six numbers, - depending on whether the coordinate reference system includes a - vertical axis (elevation or depth): - - * Lower left corner, coordinate axis 1 - * Lower left corner, coordinate axis 2 - * Lower left corner, coordinate axis 3 (optional) - * Upper right corner, coordinate axis 1 - * Upper right corner, coordinate axis 2 - * Upper right corner, coordinate axis 3 (optional) - - The coordinate reference system of the values is WGS84 - longitude/latitude (http://www.opengis.net/def/crs/OGC/1.3/CRS84) unless - a different coordinate reference system is specified in the parameter - `bbox-crs`. - - For WGS84 longitude/latitude the values are in most cases the sequence - of minimum longitude, minimum latitude, maximum longitude and maximum - latitude. However, in cases where the box spans the antimeridian the - first value (west-most box edge) is larger than the third value - (east-most box edge). - - - If a feature has multiple spatial geometry properties, it is the - decision of the server whether only a single spatial geometry property - is used to determine the extent or all relevant geometries. - type: array - minItems: 4 - maxItems: 6 - items: - type: number - example: - - -110 - - 39.5 - - -105 - - 40.5 - bboxFilter: - type: object - description: Only return items that intersect the provided bounding box. - properties: - bbox: - $ref: '#/components/schemas/bbox' - collectionsArray: - type: array - description: | - Array of Collection IDs to include in the search for items. - Only Items in one of the provided Collections will be searched - items: - type: string - ids: - type: array - description: > - Array of Item ids to return. All other filter parameters that further - restrict the number of - - search results (except `next` and `limit`) are ignored - items: - type: string - datetimeFilter: - description: An object representing a date+time based filter. - type: object - properties: - datetime: - $ref: '#/components/schemas/datetime' - intersectsFilter: - type: object - description: Only returns items that intersect with the provided polygon. - properties: - intersects: - $ref: 'https://geojson.org/schema/Geometry.json' - limitFilter: - type: object - description: Only returns maximum number of results (page size) - properties: - limit: - $ref: '#/components/schemas/limit' - nextFilter: - type: object - description: Only returns the next set of results - properties: - next: - $ref: '#/components/schemas/next' - idsFilter: - type: object - description: Only returns items that match the array of given ids - properties: - ids: - $ref: '#/components/schemas/ids' - collectionsFilter: - type: object - description: Only returns the collections specified - properties: - collections: - $ref: '#/components/schemas/collectionsArray' - datetime: - type: string - description: >- - Either a date-time or an interval, open or closed. Date and time - expressions - - adhere to RFC 3339. Open intervals are expressed using double-dots. - - - Examples: - - - * A date-time: "2018-02-12T23:20:50Z" - - * A closed interval: "2018-02-12T00:00:00Z/2018-03-18T12:31:12Z" - - * Open intervals: "2018-02-12T00:00:00Z/.." or "../2018-03-18T12:31:12Z" - - - Only features that have a temporal property that intersects the value of - - `datetime` are selected. - - - If a feature has multiple temporal properties, it is the decision of the - - server whether only a single temporal property is used to determine - - the extent or all relevant temporal properties. - example: '2018-02-12T00:00:00Z/2018-03-18T12:31:12Z' - stac_version: - title: STAC version - type: string - example: 0.8.0 - stac_extensions: - title: STAC extensions - type: array - uniqueItems: true - items: - anyOf: - - title: Reference to a JSON Schema - type: string - format: uri - - title: Reference to a core extension - type: string - catalogDefinition: - type: object - required: - - stac_version - - id - - description - - links - properties: - stac_version: - $ref: '#/components/schemas/stac_version' - stac_extensions: - $ref: '#/components/schemas/stac_extensions' - id: - type: string - example: naip - title: - type: string - example: NAIP Imagery - description: - type: string - example: Catalog of NAIP Imagery. - links: - type: array - items: - anyOf: - - $ref: '#/components/schemas/link' - - title: Link to search endpoint - description: >- - Link the search endpoint, which is **required** to be - specified if the API implements `/stac/search`. - type: object - required: - - href - - rel - properties: - href: - type: string - format: url - example: 'http://www.cool-sat.com/stac/search' - rel: - type: string - enum: - - search - type: - type: string - title: - type: string - itemCollection: - description: >- - A GeoJSON FeatureCollection augmented with foreign members that contain - values relevant to a STAC entity - type: object - required: - - features - - type - properties: - type: - type: string - enum: - - FeatureCollection - features: - type: array - items: - $ref: '#/components/schemas/item' - links: - $ref: '#/components/schemas/itemCollectionLinks' - 'search:metadata': - type: object - required: - - next - - returned - properties: - next: - type: string - nullable: true - limit: - type: integer - nullable: true - minimum: 0 - matched: - type: integer - minimum: 0 - returned: - type: integer - minimum: 0 - item: - description: >- - A GeoJSON Feature augmented with foreign members that contain values - relevant to a STAC entity - type: object - required: - - stac_version - - id - - type - - geometry - - bbox - - links - - properties - - assets - properties: - stac_version: - $ref: '#/components/schemas/stac_version' - stac_extensions: - $ref: '#/components/schemas/stac_extensions' - id: - $ref: '#/components/schemas/itemId' - bbox: - $ref: '#/components/schemas/bbox' - geometry: - $ref: 'https://geojson.org/schema/Geometry.json' - type: - $ref: '#/components/schemas/itemType' - properties: - $ref: '#/components/schemas/itemProperties' - links: - type: array - items: - $ref: '#/components/schemas/link' - assets: - $ref: '#/components/schemas/itemAssets' - example: - stac_version: 0.8.0 - type: Feature - id: CS3-20160503_132130_04 - bbox: - - -122.59750209 - - 37.48803556 - - -122.2880486 - - 37.613537207 - geometry: - type: Polygon - coordinates: - - - - -122.308150179 - - 37.488035566 - - - -122.597502109 - - 37.538869539 - - - -122.576687533 - - 37.613537207 - - - -122.2880486 - - 37.562818007 - - - -122.308150179 - - 37.488035566 - properties: - datetime: '2016-05-03T13:21:30.040Z' - links: - - rel: self - href: >- - http://cool-sat.com/catalog/collections/cs/items/CS3-20160503_132130_04.json - assets: - analytic: - title: 4-Band Analytic - href: >- - http://cool-sat.com/catalog/collections/cs/items/CS3-20160503_132130_04/analytic.tif - thumbnail: - title: Thumbnail - href: >- - http://cool-sat.com/catalog/collections/cs/items/CS3-20160503_132130_04/thumb.png - type: image/png - itemId: - type: string - example: path/to/example.tif - description: 'Provider identifier, a unique ID, potentially a link to a file.' - itemType: - type: string - description: The GeoJSON type - enum: - - Feature - itemAssets: - type: object - additionalProperties: - type: object - required: - - href - properties: - href: - type: string - format: url - description: Link to the asset object - example: >- - http://cool-sat.com/catalog/collections/cs/items/CS3-20160503_132130_04/thumb.png - title: - type: string - description: Displayed title - example: Thumbnail - type: - type: string - description: Media type of the asset - example: image/png - itemProperties: - type: object - required: - - datetime - description: provides the core metatdata fields plus extensions - properties: - datetime: - $ref: '#/components/schemas/datetime' - additionalProperties: - description: >- - Any additional properties added in via Item specification or - extensions. - itemCollectionLinks: - type: array - description: >- - An array of links. Can be used for pagination, e.g. by providing a link - with the `next` relation type. - items: - $ref: '#/components/schemas/link' - example: - - rel: next - href: >- - http://api.cool-sat.com/stac/search?next=ANsXtp9mrqN0yrKWhf-y2PUpHRLQb1GT-mtxNcXou8TwkXhi1Jbk - queryFilter: - type: object - description: Allows users to query properties for specific values - properties: - query: - $ref: '#/components/schemas/query' - query: - type: object - description: Define which properties to query and the operatations to apply - additionalProperties: - $ref: '#/components/schemas/queryProp' - example: - 'eo:cloud_cover': - lt: 50 - providers: - eq: Planet - published: - gt: '2018-02-12T00:00:00Z' - lte: '2018-03-18T12:31:12Z' - 'pl:item_type': - startsWith: PSScene - product: - in: - - foo - - bar - - baz - queryProp: - description: Apply query operations to a specific property - anyOf: - - description: >- - if the object doesn't contain any of the operators, it is equivalent - to using the equals operator - - type: object - description: Match using an operator - properties: - eq: - description: >- - Find items with a property that is equal to the specified value. - For strings, a case-insensitive comparison must be performed. - neq: - description: >- - Find items that *don't* contain the specified value. For - strings, a case-insensitive comparison must be performed. - gt: - type: number - description: >- - Find items with a property value greater than the specified - value. - lt: - type: number - description: Find items with a property value less than the specified value. - gte: - type: number - description: >- - Find items with a property value greater than or equal the - specified value. - lte: - type: number - description: >- - Find items with a property value greater than or equal the - specified value. - startsWith: - type: string - description: >- - Find items with a property that begins with the specified - string. A case-insensitive comparison must be performed. - endsWith: - type: string - description: >- - Find items with a property that ends with the specified string. - A case-insensitive comparison must be performed. - contains: - type: string - description: >- - Find items with a property that contains with the specified - string. A case-insensitive comparison must be performed. - in: - type: array - items: - type: string - description: >- - Find items with a property that matches one of the specified - strings. A case-insensitive comparison must be performed. - sortFilter: - type: object - description: Sort the results - properties: - sort: - $ref: '#/components/schemas/sort' - sort: - type: array - description: | - An array of objects containing a property name and sort direction. - minItems: 1 - items: - type: object - required: - - field - properties: - field: - type: string - direction: - type: string - default: asc - enum: - - asc - - desc - example: - - field: 'eo:cloud_cover' - - field: providers - direction: desc - fieldsFilter: - type: object - description: Determines the shape of the features in the response - properties: - fields: - $ref: '#/components/schemas/fields' - fields: - description: | - The include and exclude members specify an array of - property names that are either included or excluded - from the result, respectively. If both include and - exclude are specified, include takes precedence. - Values should include the full JSON path of the property. - type: object - properties: - include: - type: array - items: - type: string - exclude: - type: array - items: - type: string - example: - include: - - id - - 'properties.eo:cloud_cover' - exclude: - - geometry - - properties.datetime - partialItem: - type: object - properties: - stac_version: - $ref: '#/components/schemas/stac_version' - stac_extensions: - $ref: '#/components/schemas/stac_extensions' - id: - $ref: '#/components/schemas/itemId' - bbox: - $ref: '#/components/schemas/bbox' - geometry: - $ref: 'https://geojson.org/schema/Geometry.json' - type: - $ref: '#/components/schemas/itemType' - properties: - $ref: '#/components/schemas/partialItemProperties' - links: - type: array - items: - $ref: '#/components/schemas/link' - assets: - $ref: '#/components/schemas/itemAssets' - example: - assets: - analytic: - title: 1-Band Analytic - href: >- - http://cool-sat.com/catalog/collections/cs/items/CS3-201605XX_132130_04/analytic-1.tif - partialItemProperties: - type: object - description: allows for partial collections of metadata fields - additionalProperties: true - properties: - datetime: - $ref: '#/components/schemas/datetime' - responses: - LandingPage: - description: |- - The landing page provides links to the API definition - (link relations `service-desc` and `service-doc`), - the Conformance declaration (path `/conformance`, - link relation `conformance`), and the Feature - Collections (path `/collections`, link relation - `data`). - content: - application/json: - schema: - $ref: '#/components/schemas/landingPage' - example: - title: Buildings in Bonn - description: >- - Access to data about buildings in the city of Bonn via a Web API - that conforms to the OGC API Features specification. - links: - - href: 'http://data.example.org/' - rel: self - type: application/json - title: this document - - href: 'http://data.example.org/api' - rel: service-desc - type: application/vnd.oai.openapi+json;version=3.0 - title: the API definition - - href: 'http://data.example.org/api.html' - rel: service-doc - type: text/html - title: the API documentation - - href: 'http://data.example.org/conformance' - rel: conformance - type: application/json - title: OGC API conformance classes implemented by this server - - href: 'http://data.example.org/collections' - rel: data - type: application/json - title: Information about the feature collections - text/html: - schema: - type: string - ConformanceDeclaration: - description: |- - The URIs of all conformance classes supported by the server. - - To support "generic" clients that want to access multiple - OGC API Features implementations - and not "just" a specific - API / server, the server declares the conformance - classes it implements and conforms to. - content: - application/json: - schema: - $ref: '#/components/schemas/confClasses' - example: - conformsTo: - - 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core' - - 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/oas30' - - 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/html' - - 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson' - text/html: - schema: - type: string - Collections: - description: >- - The feature collections shared by this API. - - - The dataset is organized as one or more feature collections. This - resource - - provides information about and access to the collections. - - - The response contains the list of collections. For each collection, a - link - - to the items in the collection (path - `/collections/{collectionId}/items`, - - link relation `items`) as well as key information about the collection. - - This information includes: - - - * A local identifier for the collection that is unique for the dataset; - - * A list of coordinate reference systems (CRS) in which geometries may - be returned by the server. The first CRS is the default coordinate - reference system (the default is always WGS 84 with axis order - longitude/latitude); - - * An optional title and description for the collection; - - * An optional extent that can be used to provide an indication of the - spatial and temporal extent of the collection - typically derived from - the data; - - * An optional indicator about the type of the items in the collection - (the default value, if the indicator is not provided, is 'feature'). - content: - application/json: - schema: - $ref: '#/components/schemas/collections' - example: - links: - - href: 'http://data.example.org/collections.json' - rel: self - type: application/json - title: this document - - href: 'http://data.example.org/collections.html' - rel: alternate - type: text/html - title: this document as HTML - - href: 'http://schemas.example.org/1.0/buildings.xsd' - rel: describedBy - type: application/xml - title: GML application schema for Acme Corporation building data - - href: 'http://download.example.org/buildings.gpkg' - rel: enclosure - type: application/geopackage+sqlite3 - title: Bulk download (GeoPackage) - length: 472546 - collections: - - id: buildings - title: Buildings - description: Buildings in the city of Bonn. - extent: - spatial: - bbox: - - - 7.01 - - 50.63 - - 7.22 - - 50.78 - temporal: - interval: - - - '2010-02-15T12:34:56Z' - - null - links: - - href: 'http://data.example.org/collections/buildings/items' - rel: items - type: application/geo+json - title: Buildings - - href: 'http://data.example.org/collections/buildings/items.html' - rel: items - type: text/html - title: Buildings - - href: 'https://creativecommons.org/publicdomain/zero/1.0/' - rel: license - type: text/html - title: CC0-1.0 - - href: 'https://creativecommons.org/publicdomain/zero/1.0/rdf' - rel: license - type: application/rdf+xml - title: CC0-1.0 - text/html: - schema: - type: string - Collection: - description: >- - Information about the feature collection with id `collectionId`. - - - The response contains a linkto the items in the collection - - (path `/collections/{collectionId}/items`,link relation `items`) - - as well as key information about the collection. This information - - includes: - - - * A local identifier for the collection that is unique for the dataset; - - * A list of coordinate reference systems (CRS) in which geometries may - be returned by the server. The first CRS is the default coordinate - reference system (the default is always WGS 84 with axis order - longitude/latitude); - - * An optional title and description for the collection; - - * An optional extent that can be used to provide an indication of the - spatial and temporal extent of the collection - typically derived from - the data; - - * An optional indicator about the type of the items in the collection - (the default value, if the indicator is not provided, is 'feature'). - content: - application/json: - schema: - $ref: '#/components/schemas/collection' - example: - id: buildings - title: Buildings - description: Buildings in the city of Bonn. - extent: - spatial: - bbox: - - - 7.01 - - 50.63 - - 7.22 - - 50.78 - temporal: - interval: - - - '2010-02-15T12:34:56Z' - - null - links: - - href: 'http://data.example.org/collections/buildings/items' - rel: items - type: application/geo+json - title: Buildings - - href: 'http://data.example.org/collections/buildings/items.html' - rel: items - type: text/html - title: Buildings - - href: 'https://creativecommons.org/publicdomain/zero/1.0/' - rel: license - type: text/html - title: CC0-1.0 - - href: 'https://creativecommons.org/publicdomain/zero/1.0/rdf' - rel: license - type: application/rdf+xml - title: CC0-1.0 - text/html: - schema: - type: string - Features: - description: >- - The response is a document consisting of features in the collection. - - The features included in the response are determined by the server - - based on the query parameters of the request. To support access to - - larger collections without overloading the client, the API supports - - paged access with links to the next page, if more features are selected - - that the page size. - - - The `bbox` and `datetime` parameter can be used to select only a - - subset of the features in the collection (the features that are in the - - bounding box or time interval). The `bbox` parameter matches all - features - - in the collection that are not associated with a location, too. The - - `datetime` parameter matches all features in the collection that are - - not associated with a time stamp or interval, too. - - - The `limit` parameter may be used to control the subset of the - - selected features that should be returned in the response, the page - size. - - Each page may include information about the number of selected and - - returned features (`numberMatched` and `numberReturned`) as well as - - links to support paging (link relation `next`). - content: - application/geo+json: - schema: - $ref: '#/components/schemas/featureCollectionGeoJSON' - example: - type: FeatureCollection - links: - - href: 'http://data.example.com/collections/buildings/items.json' - rel: self - type: application/geo+json - title: this document - - href: 'http://data.example.com/collections/buildings/items.html' - rel: alternate - type: text/html - title: this document as HTML - - href: >- - http://data.example.com/collections/buildings/items.json&offset=10&limit=2 - rel: next - type: application/geo+json - title: next page - timeStamp: '2018-04-03T14:52:23Z' - numberMatched: 123 - numberReturned: 2 - features: - - type: Feature - id: '123' - geometry: - type: Polygon - coordinates: - - ... - properties: - function: residential - floors: '2' - lastUpdate: '2015-08-01T12:34:56Z' - - type: Feature - id: '132' - geometry: - type: Polygon - coordinates: - - ... - properties: - function: public use - floors: '10' - lastUpdate: '2013-12-03T10:15:37Z' - text/html: - schema: - type: string - Feature: - description: |- - fetch the feature with id `featureId` in the feature collection - with id `collectionId` - content: - application/geo+json: - schema: - $ref: '#/components/schemas/featureGeoJSON' - example: - type: Feature - links: - - href: 'http://data.example.com/id/building/123' - rel: canonical - title: canonical URI of the building - - href: 'http://data.example.com/collections/buildings/items/123.json' - rel: self - type: application/geo+json - title: this document - - href: 'http://data.example.com/collections/buildings/items/123.html' - rel: alternate - type: text/html - title: this document as HTML - - href: 'http://data.example.com/collections/buildings' - rel: collection - type: application/geo+json - title: the collection document - id: '123' - geometry: - type: Polygon - coordinates: - - ... - properties: - function: residential - floors: '2' - lastUpdate: '2015-08-01T12:34:56Z' - text/html: - schema: - type: string - InvalidParameter: - description: A query parameter has an invalid value. - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - text/html: - schema: - type: string - NotFound: - description: The specified resource was not found - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - ServerError: - description: A server error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - text/html: - schema: - type: string - BadRequest: - description: The request was malformed or semantically invalid - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - InternalServerError: - description: >- - The request was syntactically and semantically valid, but an error - occurred while trying to act upon it - content: - application/json: - schema: - $ref: '#/components/schemas/exception' -servers: - - url: 'http://dev.cool-sat.com' - description: Development server - - url: 'http://www.cool-sat.com' - description: Production server - diff --git a/packages/api-lib/api-spec.yaml b/packages/api-lib/api-spec.yaml deleted file mode 100644 index 1e05f386..00000000 --- a/packages/api-lib/api-spec.yaml +++ /dev/null @@ -1,940 +0,0 @@ -openapi: 3.0.1 -info: - title: The SAT-API - version: 0.2.0 - description: >- - Sat-api is a STAC compliant web API for searching and serving metadata for - geospatial data (including but not limited to satellite imagery). - Development Seed runs an instance of sat-api for the Landsat-8 - and Sentinel-2 imagery that is hosted on AWS. - contact: - name: Development Seed - email: info@developmentseed.org - url: 'https://developmentseed.org/contacts/' - license: - name: MIT License - url: 'https://github.com/sat-utils/sat-api/blob/master/LICENSE' -servers: - - url: 'https://sat-api.developmentseed.org/' - description: Production server - - url: 'https://sat-api-dev.developmentseed.org/' - description: Development server -paths: - /stac: - get: - summary: Return the root catalog or collection. - description: >- - Returns the root STAC Catalog or STAC Collection that is the entry point - for users to browse with STAC Browser or for search engines to crawl. - This can either return a single STAC Collection or more commonly a STAC - catalog that usually lists sub-catalogs of STAC Collections, i.e. a - simple catalog that lists all collections available through the API. - tags: - - STAC - responses: - '200': - description: A catalog json definition. Used as an entry point for a crawler. - content: - application/json: - schema: - $ref: '#/components/schemas/catalogDefinition' - - /stac/search: - get: - summary: Search STAC items by simple filtering. - description: >- - Retrieve Items matching filters. Intended as a shorthand API for simple - queries. - operationId: getSearchSTAC - tags: - - STAC - parameters: - - $ref: '#/components/parameters/bbox' - - $ref: '#/components/parameters/time' - - $ref: '#/components/parameters/limit' - - $ref: '#/components/parameters/query' - - $ref: '#/components/parameters/sort' - - $ref: '#/components/parameters/fields' - responses: - '200': - description: A feature collection. - content: - application/geo+json: - schema: - $ref: '#/components/schemas/itemCollection' - default: - description: An error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - - post: - summary: Search STAC items by full-featured filtering. - description: >- - retrieve items matching filters. Intended as the standard, full-featured - query API. This method is mandatory. - operationId: postSearchSTAC - tags: - - STAC - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/searchBody' - responses: - '200': - description: A feature collection. - content: - application/geo+json: - schema: - $ref: '#/components/schemas/itemCollection' - text/html: - schema: - type: string - default: - description: An error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - text/html: - schema: - type: string - /: - get: - summary: landing page of this API - description: >- - The landing page provides links to the API definition, the Conformance - statements and the metadata about the feature data in this dataset. - operationId: getLandingPage - tags: - - Capabilities - responses: - '200': - description: links to the API capabilities - content: - application/json: - schema: - $ref: '#/components/schemas/root' - text/html: - schema: - type: string - - /collections: - get: - summary: describe the feature collections in the dataset - operationId: describeCollections - tags: - - Capabilities - responses: - '200': - description: Metdata about the feature collections shared by this API. - content: - application/json: - schema: - $ref: '#/components/schemas/content' - - '/collections/{collectionId}': - get: - summary: 'describe the {collectionId} feature collection' - operationId: describeCollection - tags: - - Capabilities - parameters: - - $ref: '#/components/parameters/collectionId' - responses: - '200': - description: 'Metadata about the {collectionId} collection shared by this API.' - content: - application/json: - schema: - $ref: '#/components/schemas/collectionInfo' - default: - description: An error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - - '/collections/{collectionId}/items': - get: - summary: 'retrieve features of feature collection {collectionId}' - description: >- - Every feature in a dataset belongs to a collection. A dataset may - consist of multiple feature collections. A feature collection is often a - collection of features of a similar type, based on a common schema.\ - - Use content negotiation to request HTML or GeoJSON. - operationId: getFeatures - tags: - - Features - parameters: - - $ref: '#/components/parameters/collectionId' - - $ref: '#/components/parameters/limit' - - $ref: '#/components/parameters/bbox' - - $ref: '#/components/parameters/time' - - $ref: '#/components/parameters/query' - - $ref: '#/components/parameters/sort' - responses: - '200': - description: >- - Information about the feature collection plus the first features - matching the selection parameters. - content: - application/geo+json: - schema: - $ref: '#/components/schemas/itemCollection' - default: - description: An error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - - '/collections/{collectionId}/items/{featureId}': - get: - summary: retrieve a feature; use content negotiation to request HTML or GeoJSON - operationId: getFeature - tags: - - Features - parameters: - - $ref: '#/components/parameters/collectionId' - - $ref: '#/components/parameters/featureId' - responses: - '200': - description: A feature. - content: - application/geo+json: - schema: - $ref: '#/components/schemas/item' - default: - description: An error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/exception' - -components: - parameters: - limit: - name: limit - in: query - description: | - The optional limit parameter limits the number of items that are - presented in the response document. - - Only items are counted that are on the first level of the collection in - the response document. Nested objects contained within the explicitly - requested items shall not be counted. - - * Minimum = 1 - * Maximum = 10000 - * Default = 10 - required: false - schema: - type: integer - minimum: 1 - maximum: 10000 - default: 10 - style: form - explode: false - bbox: - name: bbox - in: query - description: | - Only features that have a geometry that intersects the bounding box are - selected. The bounding box is provided as four or six numbers, - depending on whether the coordinate reference system includes a - vertical axis (elevation or depth): - - * Lower left corner, coordinate axis 1 - * Lower left corner, coordinate axis 2 - * Lower left corner, coordinate axis 3 (optional) - * Upper right corner, coordinate axis 1 - * Upper right corner, coordinate axis 2 - * Upper right corner, coordinate axis 3 (optional) - - The coordinate reference system of the values is WGS84 - longitude/latitude (http://www.opengis.net/def/crs/OGC/1.3/CRS84) unless - a different coordinate reference system is specified in the parameter - `bbox-crs`. - - For WGS84 longitude/latitude the values are in most cases the sequence - of minimum longitude, minimum latitude, maximum longitude and maximum - latitude. However, in cases where the box spans the antimeridian the - first value (west-most box edge) is larger than the third value - (east-most box edge). - - - If a feature has multiple spatial geometry properties, it is the - decision of the server whether only a single spatial geometry property - is used to determine the extent or all relevant geometries. - required: false - schema: - type: array - minItems: 4 - maxItems: 6 - items: - type: number - style: form - explode: false - time: - name: time - in: query - description: > - Either a date-time or a period string that adheres to RFC3339. Examples: - - * A date-time: "2018-02-12T23:20:50Z" - * A period: "2018-02-12T00:00:00Z/2018-03-18T12:31:12Z" or "2018-02-12T00:00:00Z/P1M6DT12H31M12S" - - Only features that have a temporal property that intersects the value - of `time` are selected. If a feature has multiple temporal properties, it - is the decision of the server whether only a single temporal property is - used to determine the extent or all relevant temporal properties. - required: false - schema: - type: string - style: form - explode: false - collectionId: - name: collectionId - in: path - required: true - description: Identifier (name) of a specific collection - schema: - type: string - featureId: - name: featureId - in: path - description: Local identifier of a specific feature - required: true - schema: - type: string - query: - name: query - in: query - description: >- - query for properties in items. Use the JSON form of the queryFilter used - in POST. - required: false - schema: - type: string - sort: - name: sort - in: query - description: Allows sorting results by the specified properties - required: false - schema: - $ref: '#/components/schemas/sort' - fields: - name: fields - in: query - description: Determines the shape of the features in the response - required: false - schema: - $ref: '#/components/schemas/fields' - style: form - explode: false - schemas: - exception: - type: object - required: - - code - properties: - code: - type: string - description: - type: string - links: - type: array - items: - $ref: '#/components/schemas/link' - link: - type: object - required: - - href - - rel - additionalProperties: true - properties: - href: - type: string - format: url - example: 'http://www.geoserver.example/stac/naip/child/catalog.json' - rel: - type: string - example: child - type: - type: string - example: application/json - title: - type: string - example: NAIP Child Catalog - searchBody: - description: The search criteria - type: object - allOf: - - $ref: '#/components/schemas/bboxFilter' - - $ref: '#/components/schemas/timeFilter' - - $ref: '#/components/schemas/intersectsFilter' - - $ref: '#/components/schemas/queryFilter' - - $ref: '#/components/schemas/sortFilter' - bbox: - description: | - Only features that have a geometry that intersects the bounding box are - selected. The bounding box is provided as four or six numbers, - depending on whether the coordinate reference system includes a - vertical axis (elevation or depth): - - * Lower left corner, coordinate axis 1 - * Lower left corner, coordinate axis 2 - * Lower left corner, coordinate axis 3 (optional) - * Upper right corner, coordinate axis 1 - * Upper right corner, coordinate axis 2 - * Upper right corner, coordinate axis 3 (optional) - - The coordinate reference system of the values is WGS84 - longitude/latitude (http://www.opengis.net/def/crs/OGC/1.3/CRS84) unless - a different coordinate reference system is specified in the parameter - `bbox-crs`. - - For WGS84 longitude/latitude the values are in most cases the sequence - of minimum longitude, minimum latitude, maximum longitude and maximum - latitude. However, in cases where the box spans the antimeridian the - first value (west-most box edge) is larger than the third value - (east-most box edge). - - - If a feature has multiple spatial geometry properties, it is the - decision of the server whether only a single spatial geometry property - is used to determine the extent or all relevant geometries. - type: array - minItems: 4 - maxItems: 6 - items: - type: number - example: - - -110 - - 39.5 - - -105 - - 40.5 - bboxFilter: - type: object - description: Only return items that intersect the provided bounding box. - properties: - bbox: - $ref: '#/components/schemas/bbox' - timeFilter: - description: An object representing a time based filter. - type: object - properties: - time: - $ref: '#/components/schemas/time' - intersectsFilter: - type: object - description: Only returns items that intersect with the provided polygon. - properties: - intersects: - $ref: 'http://geojson.org/schema/Geometry.json' - time: - type: string - description: > - Either a date-time or a period string that adheres to RFC 3339. - Examples: - - * A date-time: "2018-02-12T23:20:50Z" - * A period: "2018-02-12T00:00:00Z/2018-03-18T12:31:12Z" or "2018-02-12T00:00:00Z/P1M6DT12H31M12S" - - Only features that have a temporal property that intersects the value of - `time` are selected. - - If a feature has multiple temporal properties, it is the decision of the - server whether only a single temporal property is used to determine the - extent or all relevant temporal properties. - example: '2018-02-12T00:00:00Z/2018-03-18T12:31:12Z' - catalogDefinition: - type: object - required: - - stac_version - - id - - description - - links - additionalProperties: true - properties: - stac_version: - type: string - example: 0.6.0 - id: - type: string - example: naip - title: - type: string - example: NAIP Imagery - description: - type: string - example: Catalog of NAIP Imagery. - links: - $ref: '#/components/schemas/links' - itemCollection: - type: object - required: - - features - - type - properties: - type: - type: string - enum: - - FeatureCollection - features: - type: array - items: - $ref: '#/components/schemas/item' - links: - $ref: '#/components/schemas/itemCollectionLinks' - item: - type: object - required: - - id - - type - - geometry - - bbox - - links - - properties - - assets - properties: - id: - $ref: '#/components/schemas/itemId' - bbox: - $ref: '#/components/schemas/bbox' - geometry: - $ref: 'http://geojson.org/schema/Geometry.json' - type: - $ref: '#/components/schemas/itemType' - properties: - $ref: '#/components/schemas/itemProperties' - links: - $ref: '#/components/schemas/links' - assets: - $ref: '#/components/schemas/itemAssets' - example: - type: Feature - id: CS3-20160503_132130_04 - bbox: - - -122.59750209 - - 37.48803556 - - -122.2880486 - - 37.613537207 - geometry: - type: Polygon - coordinates: - - - - -122.308150179 - - 37.488035566 - - - -122.597502109 - - 37.538869539 - - - -122.576687533 - - 37.613537207 - - - -122.2880486 - - 37.562818007 - - - -122.308150179 - - 37.488035566 - properties: - datetime: '2016-05-03T13:21:30.040Z' - links: - - rel: self - href: >- - http://https://sat-api.developmentseed.org/collections/landsat-8-l1/items/LC80100102015050LGN00.json - assets: - analytic: - title: 4-Band Analytic - href: >- - http://cool-sat.com/LC80100102015050LGN00/band4.tiff - type: image/tiff - thumbnail: - title: Thumbnail - href: >- - http://cool-sat.com/LC80100102015050LGN00/thumb.png - type: image/png - itemId: - type: string - example: path/to/example.tif - description: 'Provider identifier, a unique ID, potentially a link to a file.' - itemType: - type: string - description: The GeoJSON type - enum: - - Feature - itemAssets: - type: object - additionalProperties: - type: object - required: - - href - properties: - href: - type: string - format: url - description: Link to the asset object - example: >- - http://cool-sat.com/LC80100102015050LGN00/thumb.png - title: - type: string - description: Displayed title - example: Thumbnail - type: - type: string - description: Media type of the asset - example: image/png - itemProperties: - type: object - required: - - datetime - description: provides the core metatdata fields plus extensions - properties: - datetime: - $ref: '#/components/schemas/time' - additionalProperties: - description: Any additional properties added in via extensions. - itemCollectionLinks: - type: array - description: >- - An array of links. Can be used for pagination, e.g. by providing a link - with the `next` relation type. - items: - $ref: '#/components/schemas/link' - example: - - rel: next - href: >- - http://sat-api.developmentseed.org/collections/landsat-8-l1/items/gasd312fsaeg - root: - type: object - required: - - links - properties: - links: - type: array - items: - $ref: '#/components/schemas/link' - example: - - href: 'http://sat-api.developmentseed.org' - rel: self - type: application/json - title: this document - - href: 'http://sat-api.developmentseed.org/api' - rel: service - type: application/json - title: this document - - href: 'http://sat-api.developmentseed.org/collections' - rel: data - type: application/json - title: Metadata about the feature collections - req-classes: - type: object - required: - - conformsTo - properties: - conformsTo: - type: array - items: - type: string - example: - - 'http://www.opengis.net/spec/wfs-1/3.0/req/core' - - 'http://www.opengis.net/spec/wfs-1/3.0/req/oas30' - - 'http://www.opengis.net/spec/wfs-1/3.0/req/html' - - 'http://www.opengis.net/spec/wfs-1/3.0/req/geojson' - content: - type: object - required: - - links - - collections - properties: - links: - type: array - items: - $ref: '#/components/schemas/link' - example: - - href: 'http://data.example.org/collections.json' - rel: self - type: application/json - title: this document - - href: 'http://data.example.org/collections.html' - rel: alternate - type: text/html - title: this document as HTML - - href: 'http://schemas.example.org/1.0/foobar.xsd' - rel: describedBy - type: application/xml - title: XML schema for Acme Corporation data - collections: - type: array - items: - $ref: '#/components/schemas/collectionInfo' - collectionInfo: - type: object - required: - - name - - links - - stac_version - - id - - description - - license - - extent - properties: - name: - description: 'identifier of the collection used, for example, in URIs' - type: string - example: buildings - title: - description: human readable title of the collection - type: string - example: Buildings - description: - description: a description of the features in the collection - type: string - example: Buildings in the city of Bonn. - links: - type: array - items: - $ref: '#/components/schemas/link' - example: - - href: 'http://data.example.org/collections/buildings/items' - rel: item - type: application/geo+json - title: Buildings - - href: 'http://example.org/concepts/building.html' - rel: describedBy - type: text/html - title: Feature catalogue for buildings - extent: - $ref: '#/components/schemas/extent' - crs: - description: >- - The coordinate reference systems in which geometries may be - retrieved. Coordinate reference systems are identified by a URI. The - first coordinate reference system is the coordinate reference system - that is used by default. This is always - "http://www.opengis.net/def/crs/OGC/1.3/CRS84", i.e. WGS84 - longitude/latitude. - type: array - items: - type: string - default: - - 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' - stac_version: - type: string - example: 0.6.0 - id: - description: 'identifier of the collection used, for example, in URIs' - type: string - example: buildings - keywords: - title: Keywords - type: array - items: - type: string - example: - - buildings - - properties - - constructions - version: - title: Collection Version - type: string - example: 1 - license: - title: Collection License Name - type: string - example: Apache-2.0 - providers: - type: array - items: - properties: - name: - title: Organization name - type: string - example: Big Building Corp - description: - title: Provider description - type: string - example: No further processing applied. - roles: - title: Organization roles - type: array - items: - type: string - enum: - - producer - - licensor - - processor - - host - example: - - producer - - licensor - url: - title: Homepage - description: >- - Homepage on which the provider describes the dataset and - publishes contact information. - type: string - format: url - example: 'http://www.big-building.com' - queryFilter: - type: object - description: Allows users to query properties for specific values - properties: - query: - $ref: '#/components/schemas/query' - query: - type: object - description: Define which properties to query and the operatations to apply - additionalProperties: - $ref: '#/components/schemas/queryProp' - example: - 'eo:cloud_cover': - lt: 50 - queryProp: - description: Apply query operations to a specific property - anyOf: - - description: >- - if the object doesn't contain any of the operators, it is equivalent - to using the equals operator - - type: object - description: Match using an operator - properties: - eq: - description: >- - Find items with a property that is equal to the specified value. - For strings, a case-insensitive comparison must be performed. - gt: - type: number - description: >- - Find items with a property value greater than the specified - value. - lt: - type: number - description: Find items with a property value less than the specified value. - gte: - type: number - description: >- - Find items with a property value greater than or equal the - specified value. - lte: - type: number - description: >- - Find items with a property value greater than or equal the - specified value. - sortFilter: - type: object - description: Sort the results - properties: - sort: - $ref: '#/components/schemas/sort' - sort: - type: array - description: | - An array of objects containing a property name and sort direction. - minItems: 1 - items: - type: object - required: - - field - properties: - field: - type: string - direction: - type: string - default: asc - enum: - - asc - - desc - example: - - field: 'eo:cloud_cover' - direction: desc - extent: - type: object - properties: - crs: - description: >- - Coordinate reference system of the coordinates in the spatial extent - (property `spatial`). In the Core, only WGS84 longitude/latitude is - supported. Extensions may support additional coordinate reference - systems. - type: string - enum: - - 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' - default: 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' - spatial: - description: >- - West, south, east, north edges of the spatial extent. The minimum - and maximum values apply to the coordinate reference system WGS84 - longitude/latitude that is supported in the Core. If, for example, a - projected coordinate reference system is used, the minimum and - maximum values need to be adjusted. - type: array - minItems: 4 - maxItems: 6 - items: - type: number - example: - - -180 - - -90 - - 180 - - 90 - trs: - description: >- - Temporal reference system of the coordinates in the temporal extent - (property `temporal`). In the Core, only the Gregorian calendar is - supported. Extensions may support additional temporal reference - systems. - type: string - enum: - - 'http://www.opengis.net/def/uom/ISO-8601/0/Gregorian' - default: 'http://www.opengis.net/def/uom/ISO-8601/0/Gregorian' - temporal: - description: Begin and end times of the temporal extent. - type: array - minItems: 2 - maxItems: 2 - items: - type: string - format: dateTime - example: - - '2011-11-11T12:22:11Z' - - '2012-11-24T12:32:43Z' - fieldsFilter: - type: object - description: Determines the shape of the features in the response - properties: - fields: - $ref: '#/components/schemas/fields' - fields: - description: > - The geometry member determines whether the geometry is populated or is - null. The - - include and exclude members specify an array of property names that are - either - - included or excluded from the result, respectively. If both include and - exclude - - are specified, include takes precedence. - - id and links are required feature properties and cannot be excluded. - type: object - properties: - geometry: - type: boolean - include: - type: array - items: - type: string - example: - - 'eo:cloud_cover' - exclude: - type: array - items: - type: string - example: - - 'eo:sun_azimuth' -tags: - - name: STAC - description: Extension to WFS3 Core to support STAC metadata model and search API diff --git a/packages/api-lib/libs/api.js b/packages/api-lib/libs/api.js index ac21ac31..0589b6b7 100644 --- a/packages/api-lib/libs/api.js +++ b/packages/api-lib/libs/api.js @@ -1,7 +1,6 @@ const gjv = require('geojson-validation') const extent = require('@mapbox/extent') -const fs = require('fs') -const yaml = require('js-yaml') +const yaml = require('require-yml') const logger = console //require('./logger') // max number of collections to retrieve @@ -374,7 +373,9 @@ const getRoot = async function (endpoint = '') { const getAPI = async function () { - return yaml.safeLoad(fs.readFileSync('../api-definition.yaml', 'utf8')) + const spec = yaml.safeLoad(fs.readFileSync('./api.yaml', 'utf8')) + console.log(spec) + return spec } diff --git a/packages/api-lib/libs/ingest.js b/packages/api-lib/libs/ingest.js index 8a05396f..95cbeb6f 100644 --- a/packages/api-lib/libs/ingest.js +++ b/packages/api-lib/libs/ingest.js @@ -7,8 +7,7 @@ const isUrl = require('is-url') const MemoryStream = require('memorystream') const { Readable } = require('readable-stream') const pump = require('pump') -const uuid = require('uuid/v4') -const logger = require('./logger') +const logger = console //require('./logger') const limiter = new Bottleneck({ maxConcurrent: 500 @@ -150,8 +149,7 @@ async function ingest(url, backend, recursive = true, collectionsOnly = false) { await backend.prepare('collections') await backend.prepare('items') const { toEs, esStream } = await backend.stream() - const ingestJobId = uuid() - logger.info(`${ingestJobId} Started`) + logger.info(`Job Started for ${url}`) const promise = new Promise((resolve, reject) => { pump( duplexStream, @@ -162,7 +160,7 @@ async function ingest(url, backend, recursive = true, collectionsOnly = false) { logger.error(error) reject(error) } else { - logger.info(`${ingestJobId} Completed`) + logger.info(`Job completed for ${url}`) resolve(true) } } diff --git a/packages/api-lib/libs/logger.js b/packages/api-lib/libs/logger.js index 29aa81b6..bf344793 100644 --- a/packages/api-lib/libs/logger.js +++ b/packages/api-lib/libs/logger.js @@ -1,5 +1,4 @@ const winston = require('winston') -const WinstonCloudWatch = require('winston-cloudwatch') const logger = winston.createLogger({ @@ -10,21 +9,12 @@ const logger = winston.createLogger({ winston.format.printf((info) => `[${info.timestamp}] ${info.level}: ${info.message}`) ), transports: [ -// new winston.transports.Console({ -// format: winston.format.simple(), -// level: process.env.LOG_LEVEL || 'debug' -// }), - new WinstonCloudWatch({ - logGroupName: 'testing', - logStreamName: 'first' + new winston.transports.Console({ + format: winston.format.simple(), + level: process.env.LOG_LEVEL || 'debug' }) ] }) -logger.stream = { - write: (info) => { - logger.info(info) - } -} module.exports = logger diff --git a/packages/api-lib/package.json b/packages/api-lib/package.json index 95d34387..5de2f0e2 100644 --- a/packages/api-lib/package.json +++ b/packages/api-lib/package.json @@ -37,10 +37,9 @@ "pump": "^3.0.0", "request": "^2.88.0", "request-promise-native": "^1.0.5", + "require-yml": "^1.3.2", "through2": "^3.0.1", - "uuid": "^3.3.2", - "winston": "^3.2.0", - "winston-cloudwatch": "^2.3.0" + "winston": "^3.2.0" }, "devDependencies": { "ava": "^0.16.0", diff --git a/packages/api-lib/api.yaml b/packages/api/api.yaml similarity index 100% rename from packages/api-lib/api.yaml rename to packages/api/api.yaml diff --git a/packages/api/package.json b/packages/api/package.json index fe448e16..64d77927 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -33,8 +33,9 @@ "aws-event-mocks": "0.0.0", "proxyquire": "^2.1.0", "sinon": "^7.1.1", - "webpack": "~4.5.0", - "webpack-cli": "~2.0.14", - "zip-webpack-plugin": "^3.0.0" + "webpack": "~4.41", + "webpack-cli": "~3.3", + "zip-webpack-plugin": "^3.0.0", + "copy-webpack-plugin": "^5.1.1" } } diff --git a/packages/api/webpack.config.js b/packages/api/webpack.config.js index 12876427..0c4e39bf 100644 --- a/packages/api/webpack.config.js +++ b/packages/api/webpack.config.js @@ -1,5 +1,6 @@ const path = require('path') const ZipPlugin = require('zip-webpack-plugin') +const CopyPlugin = require('copy-webpack-plugin') let mode = 'development' let devtool = 'inline-source-map' @@ -26,6 +27,12 @@ module.exports = { }, target: 'node', plugins: [ + new CopyPlugin([ + { + from: 'api.yaml', + to: 'api.yaml' + } + ]), new ZipPlugin({ filename: 'api.zip' }) From dc7e25a61a42f721e3c6bb143c9c9aa8fb49c46a Mon Sep 17 00:00:00 2001 From: Matthew Hanson Date: Thu, 19 Dec 2019 00:18:51 -0500 Subject: [PATCH 09/10] fix api spec response --- packages/api-lib/libs/api.js | 4 ++-- packages/api-lib/package.json | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/api-lib/libs/api.js b/packages/api-lib/libs/api.js index 0589b6b7..80fbb316 100644 --- a/packages/api-lib/libs/api.js +++ b/packages/api-lib/libs/api.js @@ -1,6 +1,7 @@ const gjv = require('geojson-validation') const extent = require('@mapbox/extent') -const yaml = require('require-yml') +const yaml = require('js-yaml') +const fs = require('fs') const logger = console //require('./logger') // max number of collections to retrieve @@ -374,7 +375,6 @@ const getRoot = async function (endpoint = '') { const getAPI = async function () { const spec = yaml.safeLoad(fs.readFileSync('./api.yaml', 'utf8')) - console.log(spec) return spec } diff --git a/packages/api-lib/package.json b/packages/api-lib/package.json index 5de2f0e2..e9dec8da 100644 --- a/packages/api-lib/package.json +++ b/packages/api-lib/package.json @@ -37,7 +37,6 @@ "pump": "^3.0.0", "request": "^2.88.0", "request-promise-native": "^1.0.5", - "require-yml": "^1.3.2", "through2": "^3.0.1", "winston": "^3.2.0" }, From df9d3789af33f78ba3accf267aa52b3686af3b10 Mon Sep 17 00:00:00 2001 From: Matthew Hanson Date: Thu, 19 Dec 2019 00:54:41 -0500 Subject: [PATCH 10/10] combine root and /stac endpoints --- packages/api-lib/libs/api.js | 83 ++++++++++++++---------------------- 1 file changed, 33 insertions(+), 50 deletions(-) diff --git a/packages/api-lib/libs/api.js b/packages/api-lib/libs/api.js index 80fbb316..f04992cc 100644 --- a/packages/api-lib/libs/api.js +++ b/packages/api-lib/libs/api.js @@ -240,18 +240,6 @@ const collectionsToCatalogLinks = function (results, endpoint) { href: `${endpoint}/collections/${id}` } }) - catalog.links.push({ - rel: 'self', - href: `${endpoint}/stac` - }) - catalog.links.push({ - rel: 'search', - href: `${endpoint}/stac/search` - }) - catalog.links.push({ - rel: 'service', - href: process.env.STAC_DOCS_URL - }) return catalog } @@ -337,18 +325,27 @@ const searchItems = async function (collectionId, queryParameters, backend, endp } -const getRoot = async function (endpoint = '') { - const stac_version = process.env.STAC_VERSION - const stac_id = process.env.STAC_ID - const stac_title = process.env.STAC_TITLE - const stac_description = process.env.STAC_DESCRIPTION - const catalog = { - stac_version: stac_version, - id: stac_id, - title: stac_title, - description: stac_description, - links: [] +const getAPI = async function () { + const spec = yaml.safeLoad(fs.readFileSync('./api.yaml', 'utf8')) + return spec +} + + +const getConformance = async function () { + const conformance = { + conformsTo: [ + 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core', + 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/html', + 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson' + ] } + return conformance +} + + +const getCatalog = async function (backend, endpoint = '') { + const { results } = await backend.search({}, 'collections', 1, COLLECTION_LIMIT) + const catalog = collectionsToCatalogLinks(results, endpoint) catalog.links.push({ rel: 'service-desc', type: 'application/vnd.oai.openapi+json;version=3.0', @@ -360,7 +357,7 @@ const getRoot = async function (endpoint = '') { href: `${endpoint}/conformance` }) catalog.links.push({ - rel: 'data', + rel: 'children', type: 'application/json', href: `${endpoint}/collections` }) @@ -369,31 +366,18 @@ const getRoot = async function (endpoint = '') { type: 'application/json', href: `${endpoint}/` }) - return catalog -} - - -const getAPI = async function () { - const spec = yaml.safeLoad(fs.readFileSync('./api.yaml', 'utf8')) - return spec -} - - -const getConformance = async function () { - const conformance = { - conformsTo: [ - 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core', - 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/html', - 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson' - ] + catalog.links.push({ + rel: 'search', + type: 'application/json', + href: `${endpoint}/stac/search` + }) + if (process.env.STAC_DOCS_URL) { + catalog.links.push({ + rel: 'docs', + href: process.env.STAC_DOCS_URL + }) } - return conformance -} - - -const getCatalog = async function (backend, endpoint = '') { - const { results } = await backend.search({}, 'collections', 1, COLLECTION_LIMIT) - return collectionsToCatalogLinks(results, endpoint) + return catalog } @@ -461,7 +445,7 @@ const API = async function ( // API Root if (root) { - apiResponse = await getRoot(endpoint) + apiResponse = await getCatalog(backend, endpoint) } // API Definition if (api) { @@ -505,7 +489,6 @@ const API = async function ( } module.exports = { - getRoot, getAPI, getConformance, getCatalog,