diff --git a/ingest-app/src/cmr/ingest/config.clj b/ingest-app/src/cmr/ingest/config.clj index 6b6a040125..63a88345f0 100644 --- a/ingest-app/src/cmr/ingest/config.clj +++ b/ingest-app/src/cmr/ingest/config.clj @@ -29,7 +29,7 @@ (defconfig service-umm-version "Defines the latest service umm version accepted by ingest - it's the latest official version. This environment variable needs to be manually set when newer UMM version becomes official" - {:default "1.3.2"}) + {:default "1.3.3"}) (defconfig tool-umm-version "Defines the latest tool umm version accepted by ingest - it's the latest official version. diff --git a/system-int-test/test/cmr/system_int_test/search/service/service_search_test.clj b/system-int-test/test/cmr/system_int_test/search/service/service_search_test.clj index d15b60772f..58cdfde8db 100644 --- a/system-int-test/test/cmr/system_int_test/search/service/service_search_test.clj +++ b/system-int-test/test/cmr/system_int_test/search/service/service_search_test.clj @@ -534,8 +534,8 @@ {:accept (mime-types/with-version mime-types/umm-json umm-version/current-service-version)} "explicit UMM JSON version through suffix" - "1.3.2" - {:url-extension "umm_json_v1_3_2"}))) + "1.3.3" + {:url-extension "umm_json_v1_3_3"}))) (testing "Searching with non-existent UMM JSON version" (are3 [options] diff --git a/umm-spec-lib/resources/example-data/umm-json/service/v1.3.2/Service_v1.3.2-from-v1.3.3.json b/umm-spec-lib/resources/example-data/umm-json/service/v1.3.2/Service_v1.3.2-from-v1.3.3.json new file mode 100644 index 0000000000..cd148aefaa --- /dev/null +++ b/umm-spec-lib/resources/example-data/umm-json/service/v1.3.2/Service_v1.3.2-from-v1.3.3.json @@ -0,0 +1,222 @@ +{ + "Name": "AIRX3STD.006_to_130", + "LongName": "AIRS/Aqua L3 Daily Standard Physical Retrieval (AIRS+AMSU) 1 degree x 1 degree V006.", + "Description": "Access the AIRS/Aqua Level 3 daily standard physical retrieval product (Without HSB) through OPeNDAP", + "Type": "EGI - No Processing", + "Version": "1.9", + "VersionDescription": "This is a description of version 1.9.", + "LastUpdatedDate": "2020-05-10T00:00:00Z", + "AccessConstraints": "None", + "UseConstraints": { + "LicenseURL": "http://www.someurl.com", + "LicenseText": "None" }, + "URL": { + "Description": "OPeNDAP Service for AIRX3STD.006", + "URLValue": "https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/" + }, + "ServiceKeywords": [{ + "ServiceCategory":"DATA MANAGEMENT/DATA HANDLING", + "ServiceTopic":"TRANSFORMATION/REPROJECTION" + }], + "ServiceOrganizations": [{ + "Roles": ["SERVICE PROVIDER"], + "ShortName": "NASA/GESDISC", + "LongName": "GES DISC SERVICE HELP DESK SUPPORT GROUP" + }, { + "Roles": ["SERVICE PROVIDER"], + "ShortName": "NASA/GESDISC-2", + "LongName": "GES DISC SERVICE HELP DESK SUPPORT GROUP 2", + "OnlineResource": { + "Linkage": "https://daacscenter.org", + "Name": "HOME PAGE", + "Description": "Test the description." + } + }], + "ContactGroups": [{ + "Roles": ["SCIENCE CONTACT"], + "ContactInformation": { + "ContactMechanisms": [{ + "Type": "Email", + "Value": "gsfc-help-disc at lists.nasa.gov" + }, { + "Type": "Telephone", + "Value": "301-614-9999" + }], + "Addresses": [{ + "StreetAddresses": [ + "Goddard Earth Sciences Data and Information Systems, Attn: User , NASA Goddard Space Flight Center, Code 610.2" + ], + "City": "Greenbelt", + "StateProvince": "MD", + "Country": "USA", + "PostalCode": "20771" + }] + }, + "GroupName": "Main Level Group Name 1" + }, { + "Roles": ["TECHNICAL CONTACT"], + "ContactInformation": { + "OnlineResources": [{ + "Linkage": "https://someurl1.org", + "Protocol": "https", + "ApplicationProfile": "Some Application", + "Name": "Some Site", + "Description": "The description of someurl1.", + "Function": "information" + }, { + "Linkage": "https://someurl2.org", + "Protocol": "https", + "ApplicationProfile": "Some Application 2", + "Name": "Some Site 2", + "Description": "The description of someurl2.", + "Function": "information" + }], + "ContactMechanisms": [{ + "Type": "Email", + "Value": "gsfc-help-disc at lists.nasa.gov" + }, { + "Type": "Telephone", + "Value": "301-614-9999" + }], + "Addresses": [{ + "StreetAddresses": [ + "Goddard Earth Sciences Data and Information Systems, Attn: User , NASA Goddard Space Flight Center, Code 610.2" + ], + "City": "Greenbelt", + "StateProvince": "MD", + "Country": "USA", + "PostalCode": "20771" + }] + }, + "GroupName": "Main Level Group Name 2" + }], + "ContactPersons": [{ + "Roles": ["SERVICE PROVIDER"], + "ContactInformation": { + "OnlineResources": [{ + "Linkage": "https://someurl3.org", + "Protocol": "https", + "ApplicationProfile": "Some Application 3", + "Name": "Some Site", + "Description": "The description of someurl3.", + "Function": "information" + }], + "ContactMechanisms": [{ + "Type": "Email", + "Value": "gsfc-help-disc at lists.nasa.gov" + }, { + "Type": "Telephone", + "Value": "301-614-9999" + }], + "Addresses": [{ + "StreetAddresses": [ + "Goddard Earth Sciences Data and Information Systems, Attn: User , NASA Goddard Space Flight Center, Code 610.2" + ], + "City": "Greenbelt", + "StateProvince": "MD", + "Country": "USA", + "PostalCode": "20771" + }] + }, + "FirstName": "FirstName Main Level", + "MiddleName": " ", + "LastName": "LastName Main Level" + }, { + "Roles": ["SERVICE PROVIDER"], + "ContactInformation": { + "ContactMechanisms": [{ + "Type": "Email", + "Value": "gsfc-help-disc at lists.nasa.gov" + }, { + "Type": "Telephone", + "Value": "301-614-9999" + }], + "Addresses": [{ + "StreetAddresses": [ + "Goddard Earth Sciences Data and Information Systems, Attn: User , NASA Goddard Space Flight Center, Code 610.2" + ], + "City": "Greenbelt", + "StateProvince": "MD", + "Country": "USA", + "PostalCode": "20771" + }] + }, + "FirstName": "FirstName Service Org", + "MiddleName": "Service Org MiddleName", + "LastName": "LastName Service Org" + }], + "ServiceOptions": { + "SubsetTypes": ["Spatial","Variable"], + "SupportedInputProjections": [{ + "ProjectionName":"Geographic", + "ProjectionAuthority":"4326" + }], + "SupportedInputFormats": ["HDF4"], + "SupportedOutputProjections": [{ + "ProjectionName":"Geographic", + "ProjectionAuthority":"ep" + }], + "SupportedOutputFormats": ["HDF4","NETCDF-3","NETCDF-4","BINARY","ASCII", "ZARR"], + "SupportedReformattings": [{ + "SupportedInputFormat": "HDF5", + "SupportedOutputFormats": ["GEOTIFFFLOAT32","GEOTIFFINT16"] + }] + }, + "OperationMetadata": [{ + "OperationName":"SPATIAL_SUBSETTING", + "DistributedComputingPlatform":["XML","HTTPS"], + "OperationDescription":"Access the AIRS/Aqua Level 3 daily standard physical retrieval product (Without HSB) through OPeNDAP", + "InvocationName":"GES DISC OPeNDAP Service for AIRX3STD.006", + "ConnectPoint": { + "ResourceName":"AIRX3STD.006", + "ResourceLinkage": "https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/", + "ResourceDescription":"AIRS/Aqua L3 Daily Standard Physical Retrieval (AIRS+AMSU) 1 degree x 1 degree V006." + }, + "CoupledResource": { + "ScopedName":"AIRX3STD.006", + "DataResourceDOI":"https://doi.org/10.5067/Aqua/AIRS/DATA303", + "CouplingType":"TIGHT", + "DataResource": { + "DataResourceIdentifier":"Aqua_AIRS_Level3/AIRX3STD.006", + "DataResourceSourceType":"Collection", + "DataResourceSpatialType":"BOUNDING_BOX", + "DataResourceSpatialExtent": { + "SpatialBoundingBox": { + "CRSIdentifier":"EPSG:4326", + "WestBoundingCoordinate":-180.00, + "SouthBoundingCoordinate":-90.0, + "EastBoundingCoordinate":180.0, + "NorthBoundingCoordinate":90.0 + } + }, + "SpatialResolution":1, + "SpatialResolutionUnit":"KM", + "DataResourceTemporalType":"TIME_STAMP", + "DataResourceTemporalExtent": { + "DataResourceTimePoints": [{ + "TimeFormat":"%Y%M%D", + "TimeValue":"2009-01-08", + "Description":"Time stamp of the granule within the collection" + }] + }, + "TemporalResolution":1, + "TemporalResolutionUnit":"DAY" + } + } + }, { + "OperationName": "GetTile", + "CoupledResource": { + "DataResource": { + "DataResourceSpatialExtent": { + "SpatialBoundingBox": { + "CRSIdentifier":"Other", + "WestBoundingCoordinate":-180.00, + "SouthBoundingCoordinate":-90.0, + "EastBoundingCoordinate":180.0, + "NorthBoundingCoordinate":90.0 + } + } + } + } + }] +} diff --git a/umm-spec-lib/resources/example-data/umm-json/service/v1.3.3/Service_v1.3.3-to-v1.3.2.json b/umm-spec-lib/resources/example-data/umm-json/service/v1.3.3/Service_v1.3.3-to-v1.3.2.json new file mode 100644 index 0000000000..eed74d3eb3 --- /dev/null +++ b/umm-spec-lib/resources/example-data/umm-json/service/v1.3.3/Service_v1.3.3-to-v1.3.2.json @@ -0,0 +1,225 @@ +{ + "Name": "AIRX3STD.006_to_130", + "LongName": "AIRS/Aqua L3 Daily Standard Physical Retrieval (AIRS+AMSU) 1 degree x 1 degree V006.", + "Description": "Access the AIRS/Aqua Level 3 daily standard physical retrieval product (Without HSB) through OPeNDAP", + "Type": "EGI - No Processing", + "Version": "1.9", + "VersionDescription": "This is a description of version 1.9.", + "LastUpdatedDate": "2020-05-10T00:00:00Z", + "AccessConstraints": "None", + "UseConstraints": { + "LicenseURL": "http://www.someurl.com", + "LicenseText": "None" }, + "URL": { + "Description": "OPeNDAP Service for AIRX3STD.006", + "URLValue": "https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/" + }, + "ServiceKeywords": [{ + "ServiceCategory":"DATA MANAGEMENT/DATA HANDLING", + "ServiceTopic":"TRANSFORMATION/REPROJECTION" + }], + "ServiceOrganizations": [{ + "Roles": ["SERVICE PROVIDER"], + "ShortName": "NASA/GESDISC", + "LongName": "GES DISC SERVICE HELP DESK SUPPORT GROUP" + }, { + "Roles": ["SERVICE PROVIDER"], + "ShortName": "NASA/GESDISC-2", + "LongName": "GES DISC SERVICE HELP DESK SUPPORT GROUP 2", + "OnlineResource": { + "Linkage": "https://daacscenter.org", + "Name": "HOME PAGE", + "Description": "Test the description." + } + }], + "ContactGroups": [{ + "Roles": ["SCIENCE CONTACT"], + "ContactInformation": { + "ContactMechanisms": [{ + "Type": "Email", + "Value": "gsfc-help-disc at lists.nasa.gov" + }, { + "Type": "Telephone", + "Value": "301-614-9999" + }], + "Addresses": [{ + "StreetAddresses": [ + "Goddard Earth Sciences Data and Information Systems, Attn: User , NASA Goddard Space Flight Center, Code 610.2" + ], + "City": "Greenbelt", + "StateProvince": "MD", + "Country": "USA", + "PostalCode": "20771" + }] + }, + "GroupName": "Main Level Group Name 1" + }, { + "Roles": ["TECHNICAL CONTACT"], + "ContactInformation": { + "OnlineResources": [{ + "Linkage": "https://someurl1.org", + "Protocol": "https", + "ApplicationProfile": "Some Application", + "Name": "Some Site", + "Description": "The description of someurl1.", + "Function": "information" + }, { + "Linkage": "https://someurl2.org", + "Protocol": "https", + "ApplicationProfile": "Some Application 2", + "Name": "Some Site 2", + "Description": "The description of someurl2.", + "Function": "information" + }], + "ContactMechanisms": [{ + "Type": "Email", + "Value": "gsfc-help-disc at lists.nasa.gov" + }, { + "Type": "Telephone", + "Value": "301-614-9999" + }], + "Addresses": [{ + "StreetAddresses": [ + "Goddard Earth Sciences Data and Information Systems, Attn: User , NASA Goddard Space Flight Center, Code 610.2" + ], + "City": "Greenbelt", + "StateProvince": "MD", + "Country": "USA", + "PostalCode": "20771" + }] + }, + "GroupName": "Main Level Group Name 2" + }], + "ContactPersons": [{ + "Roles": ["SERVICE PROVIDER"], + "ContactInformation": { + "OnlineResources": [{ + "Linkage": "https://someurl3.org", + "Protocol": "https", + "ApplicationProfile": "Some Application 3", + "Name": "Some Site", + "Description": "The description of someurl3.", + "Function": "information" + }], + "ContactMechanisms": [{ + "Type": "Email", + "Value": "gsfc-help-disc at lists.nasa.gov" + }, { + "Type": "Telephone", + "Value": "301-614-9999" + }], + "Addresses": [{ + "StreetAddresses": [ + "Goddard Earth Sciences Data and Information Systems, Attn: User , NASA Goddard Space Flight Center, Code 610.2" + ], + "City": "Greenbelt", + "StateProvince": "MD", + "Country": "USA", + "PostalCode": "20771" + }] + }, + "FirstName": "FirstName Main Level", + "MiddleName": " ", + "LastName": "LastName Main Level" + }, { + "Roles": ["SERVICE PROVIDER"], + "ContactInformation": { + "ContactMechanisms": [{ + "Type": "Email", + "Value": "gsfc-help-disc at lists.nasa.gov" + }, { + "Type": "Telephone", + "Value": "301-614-9999" + }], + "Addresses": [{ + "StreetAddresses": [ + "Goddard Earth Sciences Data and Information Systems, Attn: User , NASA Goddard Space Flight Center, Code 610.2" + ], + "City": "Greenbelt", + "StateProvince": "MD", + "Country": "USA", + "PostalCode": "20771" + }] + }, + "FirstName": "FirstName Service Org", + "MiddleName": "Service Org MiddleName", + "LastName": "LastName Service Org" + }], + "ServiceOptions": { + "SubsetTypes": ["Spatial","Variable"], + "SupportedInputProjections": [{ + "ProjectionName":"Geographic", + "ProjectionAuthority":"4326" + }], + "SupportedInputFormats": ["HDF4", "Shapefile"], + "SupportedOutputProjections": [{ + "ProjectionName":"Geographic", + "ProjectionAuthority":"ep" + }], + "SupportedOutputFormats": ["HDF4","NETCDF-3","NETCDF-4","BINARY","ASCII", "ZARR", "GeoJSON"], + "SupportedReformattings": [{ + "SupportedInputFormat": "HDF5", + "SupportedOutputFormats": ["GEOTIFFFLOAT32","GEOTIFFINT16", "COG"] + }, { + "SupportedInputFormat": "WKT", + "SupportedOutputFormats": ["GEOTIFFFLOAT32","GEOTIFFINT16"] + }] + }, + "OperationMetadata": [{ + "OperationName":"SPATIAL_SUBSETTING", + "DistributedComputingPlatform":["XML","HTTPS"], + "OperationDescription":"Access the AIRS/Aqua Level 3 daily standard physical retrieval product (Without HSB) through OPeNDAP", + "InvocationName":"GES DISC OPeNDAP Service for AIRX3STD.006", + "ConnectPoint": { + "ResourceName":"AIRX3STD.006", + "ResourceLinkage": "https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/", + "ResourceDescription":"AIRS/Aqua L3 Daily Standard Physical Retrieval (AIRS+AMSU) 1 degree x 1 degree V006." + }, + "CoupledResource": { + "ScopedName":"AIRX3STD.006", + "DataResourceDOI":"https://doi.org/10.5067/Aqua/AIRS/DATA303", + "CouplingType":"TIGHT", + "DataResource": { + "DataResourceIdentifier":"Aqua_AIRS_Level3/AIRX3STD.006", + "DataResourceSourceType":"Collection", + "DataResourceSpatialType":"BOUNDING_BOX", + "DataResourceSpatialExtent": { + "SpatialBoundingBox": { + "CRSIdentifier":"EPSG:4326", + "WestBoundingCoordinate":-180.00, + "SouthBoundingCoordinate":-90.0, + "EastBoundingCoordinate":180.0, + "NorthBoundingCoordinate":90.0 + } + }, + "SpatialResolution":1, + "SpatialResolutionUnit":"KM", + "DataResourceTemporalType":"TIME_STAMP", + "DataResourceTemporalExtent": { + "DataResourceTimePoints": [{ + "TimeFormat":"%Y%M%D", + "TimeValue":"2009-01-08", + "Description":"Time stamp of the granule within the collection" + }] + }, + "TemporalResolution":1, + "TemporalResolutionUnit":"DAY" + } + } + }, { + "OperationName": "GetTile", + "CoupledResource": { + "DataResource": { + "DataResourceSpatialExtent": { + "SpatialBoundingBox": { + "CRSIdentifier":"Other", + "WestBoundingCoordinate":-180.00, + "SouthBoundingCoordinate":-90.0, + "EastBoundingCoordinate":180.0, + "NorthBoundingCoordinate":90.0 + } + } + } + } + }] +} diff --git a/umm-spec-lib/resources/json-schemas/service/umm/v1.3.3/umm-s-json-schema.json b/umm-spec-lib/resources/json-schemas/service/umm/v1.3.3/umm-s-json-schema.json new file mode 100644 index 0000000000..ced97b4847 --- /dev/null +++ b/umm-spec-lib/resources/json-schemas/service/umm/v1.3.3/umm-s-json-schema.json @@ -0,0 +1,1104 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "UMM-S", + "type": "object", + "additionalProperties": false, + "properties": { + "Name": { + "description": "The name of the service, software, or tool.", + "type": "string", + "minLength": 1, + "maxLength": 85 + }, + "LongName": { + "description": "The long name of the service, software, or tool.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "Type": { + "description": "The type of the service, software, or tool.", + "$ref": "#/definitions/ServiceTypeEnum" + }, + "Version": { + "description": "The edition or version of the service.", + "type": "string", + "minLength": 1, + "maxLength": 20 + }, + "VersionDescription": { + "description": "This field provides users with information on what changes were included in the most recent version.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "LastUpdatedDate": { + "description": "This element describes the latest date when the service was most recently pushed to production for support and maintenance. ", + "format": "date-time", + "type": "string" + }, + "URL": { + "description": "This element contains important information about the universal resource locator (URL) for the service.", + "$ref": "#/definitions/URLType" + }, + "Description": { + "description": "A brief description of the service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "ServiceKeywords": { + "description": "Allows for the specification of Earth Science Service keywords that are representative of the service, software, or tool being described. The controlled vocabulary for Service Keywords is maintained in the Keyword Management System (KMS).", + "type": "array", + "items": { + "$ref": "#/definitions/ServiceKeywordType" + }, + "minItems": 1 + }, + "ServiceOrganizations": { + "description": "The service provider, or organization, or institution responsible for developing, archiving, and/or distributing the service, software, or tool.", + "type": "array", + "items": { + "$ref": "#/definitions/ServiceOrganizationType" + }, + "minItems": 1 + }, + "ContactGroups": { + "description": "This is the contact groups of the service.", + "type": "array", + "items": { + "$ref": "#/definitions/ContactGroupType" + } + }, + "ContactPersons": { + "description": "This is the contact persons of the service.", + "type": "array", + "items": { + "$ref": "#/definitions/ContactPersonType" + } + }, + "ServiceQuality": { + "description": "Information about the quality of the service, software, or tool, or any quality assurance procedures followed in development.", + "$ref": "#/definitions/ServiceQualityType" + }, + "AccessConstraints": { + "description": "Information about any constraints for accessing the service, software, or tool.", + "$ref": "#/definitions/AccessConstraintsType" + }, + "UseConstraints": { + "description": "Information on how the item (service, software, or tool) may or may not be used after access is granted. This includes any special restrictions, legal prerequisites, terms and conditions, and/or limitations on using the item. Providers may request acknowledgement of the item from users and claim no responsibility for quality and completeness.", + "$ref": "#/definitions/UseConstraintsType" + }, + "AncillaryKeywords": { + "description": "Words or phrases to further describe the service, software, or tool.", + "type": "array", + "items": { + "$ref": "#/definitions/AncillaryKeywordsType" + }, + "minItems": 0 + }, + "ServiceOptions": { + "description": "This element contains important information about the Unique Resource Locator for the service.", + "$ref": "#/definitions/ServiceOptionsType" + }, + "OperationMetadata": { + "description": "This class describes the signature of the operational metadata provided by the service.", + "type": "array", + "items": { + "$ref": "#/definitions/OperationMetadataType" + }, + "minItems": 0 + } + }, + "required": [ + "Name", + "LongName", + "Type", + "Version", + "URL", + "Description", + "ServiceKeywords", + "ServiceOrganizations" + ], + + "definitions": { + "ServiceOptionsType": { + "type": "object", + "additionalProperties": false, + "description": "This object describes service options, data transformations and output formats.", + "properties": { + "SubsetTypes": { + "description": "This element is used to identify the list of supported subsetting requests.", + "type": "array", + "items": { + "$ref": "#/definitions/SubsetTypeEnum" + }, + "minItems": 0 + }, + "VariableAggregationSupportedMethods": { + "description": "This element is used to identify the list of supported methods of variable aggregation.", + "type": "array", + "items": { + "$ref": "#/definitions/VariableAggregationTypeEnum" + }, + "minItems": 0 + }, + "SupportedInputProjections": { + "description": "This element is used to identify the list of supported input projections types.", + "type": "array", + "items": { + "$ref": "#/definitions/SupportedProjectionType" + }, + "minItems": 0 + }, + "SupportedOutputProjections": { + "description": "This element is used to identify the list of supported output projections types.", + "type": "array", + "items": { + "$ref": "#/definitions/SupportedProjectionType" + }, + "minItems": 0 + }, + "InterpolationTypes": { + "description": "This element is used to identify the list of supported interpolation types.", + "type": "array", + "items": { + "$ref": "#/definitions/InterpolationTypeEnum" + }, + "minItems": 0 + }, + "SupportedInputFormats": { + "description": "The project element describes the list of input format names supported by the service.", + "type": "array", + "items": { + "$ref": "#/definitions/SupportedFormatTypeEnum" + }, + "minItems": 0 + }, + "SupportedOutputFormats": { + "description": "The project element describes the list of output format names supported by the service.", + "type": "array", + "items": { + "$ref": "#/definitions/SupportedFormatTypeEnum" + }, + "minItems": 0 + }, + "SupportedReformattings": { + "description": "The project element describes the list of format name combinations which explicitly state which re-formatting options are available. These are entered as pairs of values, e.g. if NetCDF-3 -> NetCDF-4 is a valid supported reformatting, these two values would be entered as a pair.", + "type": "array", + "items": { + "$ref": "#/definitions/SupportedReformattingsPairType" + }, + "minItems": 1 + }, + "MaxGranules": { + "description": "This field indicates the maximum number of granules which this service can process with one request.", + "type": "number" + } + } + }, + "SupportedReformattingsPairType": { + "type": "object", + "additionalProperties": false, + "description": "This object describes the supported reformatting pairs, e.g. NetCDF4 -> [COG]. For every input there is 1 or more outputs.", + "properties": { + "SupportedInputFormat": { + "description": "This element is used to identify the name of the supported input format in the pair.", + "$ref": "#/definitions/SupportedFormatTypeEnum" + }, + "SupportedOutputFormats": { + "description": "This element is used to identify the name of all supported output formats for the provided input format.", + "type": "array", + "items": { + "$ref": "#/definitions/SupportedFormatTypeEnum" + }, + "minItems": 1 + } + }, + "required": ["SupportedInputFormat", "SupportedOutputFormats"] + }, + "SupportedProjectionType": { + "type": "object", + "additionalProperties": false, + "description": "This element is used to identify the input projection type of the variable.", + "properties": { + "ProjectionName": { + "description": "This element is used to identify the list of supported projection types.", + "type": "string", + "enum": ["Geographic", "Military Grid Reference", "MODIS Sinusoidal System", "Sinusoidal", "World Mollweide", "Mercator", "Space Oblique Mercator", "Transverse Mercator", "Universal Transverse Mercator", "UTM Northern Hemisphere", "UTM Southern Hemisphere", "State Plane Coordinates", "Albers Equal-Area Conic", "Lambert Conic Conformal", "Lambert Equal Area", "Lambert Azimuthal Equal Area", "Cylindrical", "Cylindrical Equal Area", "Polar Stereographic", "EASE-Grid", "EASE-Grid 2.0", "WGS 84 / UPS North (N,E)", "WGS84 - World Geodetic System 1984", "NSIDC EASE-Grid North", "NSIDC EASE-Grid Global", "NSIDC Sea Ice Polar Stereographic North", "WGS 84 / NSIDC Sea Ice Polar Stereographic North", "NSIDC EASE Grid North and South (Lambert EA)", "WGS 84 / North Pole LAEA Bering Sea", "WGS 84 / North Pole LAEA Alaska", "WGS 84 / North Pole LAEA Canada", "WGS 84 / North Pole LAEA Atlantic", "WGS 84 / North Pole LAEA Europe", "WGS 84 / North Pole LAEA Russia", "WGS 84 / NSIDC EASE-Grid North", "WGS 84 / NSIDC EASE-Grid Global", "WGS 84 / UTM zone 24N", "Spherical Mercator", "WGS 84 / Pseudo-Mercator -- Spherical Mercator, Google Maps, OpenStreetMap, Bing, ArcGIS, ESRI", "Google Maps Global Mercator -- Spherical Mercator", "WGS 84 / Antarctic Polar Stereographic", "NSIDC EASE-Grid South", "NSIDC Sea Ice Polar Stereographic South", "WGS 84 / NSIDC EASE-Grid South", "WGS 84 / NSIDC Sea Ice Polar Stereographic South", "WGS 84 / UPS South (N,E)", "NSIDC EASE Grid Global", "EASE Grid 2.0 N. Polar", "Plate Carree", "WELD Albers Equal Area", "Canadian Albers Equal Area Conic", "NAD83 / UTM zone 17N"] + }, + "ProjectionLatitudeOfCenter": { + "description": "This element is used to identify the origin of the x-coordinates at the center of the projection.", + "type": "number" + }, + "ProjectionLongitudeOfCenter": { + "description": "This element is used to identify the origin of the y-coordinates at the center of the projection.", + "type": "number" + }, + "ProjectionFalseEasting": { + "description": "This element is used to identify the linear value applied to the origin of the y-coordinates. False easting and northing values are usually applied to ensure that all the x and y values are positive.", + "type": "number" + }, + "ProjectionFalseNorthing": { + "description": "This element is used to identify the linear value applied to the origin of the x-coordinates. False easting and northing values are usually applied to ensure that all the x and y values are positive.", + "type": "number" + }, + "ProjectionAuthority": { + "description": "This element is used to identify the authority, expressed as the authority code, for the list of supported projection types.", + "type": "string" + }, + "ProjectionUnit": { + "description": "This element is used to identify the projection unit of measurement.", + "type": "string", + "enum": ["Meters", "Degrees"] + }, + "ProjectionDatumName": { + "description": "This element is used to identify the projection datum name.", + "type": "string", + "enum": ["North American Datum (NAD) 1927", "North American Datum (NAD) 1983", "World Geodetic System (WGS) 1984"] + } + } + }, + "SubsetTypeEnum": { + "description": "This element is used to identify the subset type of the variable.", + "type": "string", + "enum": ["Spatial", "Temporal", "Variable"] + }, + "VariableAggregationTypeEnum": { + "description": "This element is used to identify the list of supported methods of variable aggregation.", + "type": "string", + "enum": ["AVG", "COUNT", "SUM", "MIN", "MAX", "VAR", "ANOMOLY"] + }, + "InterpolationTypeEnum": { + "description": "This element is used to identify the interpolation type of the variable.", + "type": "string", + "enum": ["Bilinear Interpolation", "Bicubic Interpolation", "Distance-weighted average resampling", "Nearest Neighbor"] + }, + "SupportedFormatTypeEnum": { + "description": "This element contains a list of file formats supported by the service.", + "type": "string", + "enum": ["HDF4", "HDF5", "HDF-EOS", "HDF-EOS2", "HDF-EOS5", "NETCDF-3", "NETCDF-4", "GEOTIFF", "GEOTIFFINT16", "GEOTIFFFLOAT32", "XML", "ASCII", "BINARY", "ICARTT", "PNG", "JPEG", "GIF", "TIFF", "XLSX", "JSON", "CSV", "KML", "PNG24", "BMP", "ZARR", "Shapefile", "GeoJSON", "COG", "WKT"] + }, + "URLType": { + "type": "object", + "additionalProperties": false, + "description": "Represents the Internet site where you can directly access the back-end service.", + "properties": { + "Description": { + "description": "Description of the web page at this URL.", + "type": "string", + "minLength": 1, + "maxLength": 4000 + }, + "URLValue": { + "description": "The URL for the relevant web page (e.g., the URL of the responsible organization's home page, the URL of the collection landing page, the URL of the download site for the collection).", + "type": "string", + "minLength": 1, + "maxLength": 1024 + } + }, + "required": ["URLValue"] + }, + "OnlineResourceType": { + "type": "object", + "additionalProperties": false, + "description": "Describes the online resource pertaining to the data.", + "properties": { + "Linkage": { + "description": "The URL of the website related to the online resource.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "Protocol": { + "description": "The protocol of the linkage for the online resource, such as https, svn, ftp, etc.", + "type": "string", + "minLength": 1, + "maxLength": 80 + }, + "ApplicationProfile": { + "description": "The application profile holds the name of the application that can service the data. For example if the URL points to a word document, then the applicationProfile is MS-Word.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "Name": { + "description": "The name of the online resource.", + "type": "string", + "minLength": 1, + "maxLength": 80 + }, + "Description": { + "description": "The description of the online resource.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "Function": { + "description": "The function of the online resource. In ISO where this class originated the valid values are: download, information, offlineAccess, order, and search.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + } + }, + "required": ["Linkage", "Name", "Description"] + }, + "ServiceKeywordType": { + "type": "object", + "additionalProperties": false, + "description": "Enables specification of Earth science service keywords related to the service. The Earth Science Service keywords are chosen from a controlled keyword hierarchy maintained in the Keyword Management System (KMS).", + "properties": { + "ServiceCategory": { + "$ref": "#/definitions/KeywordStringType" + }, + "ServiceTopic": { + "$ref": "#/definitions/KeywordStringType" + }, + "ServiceTerm": { + "$ref": "#/definitions/KeywordStringType" + }, + "ServiceSpecificTerm": { + "$ref": "#/definitions/KeywordStringType" + } + }, + "required": ["ServiceCategory", "ServiceTopic"] + }, + "KeywordStringType": { + "type": "string", + "minLength": 1, + "maxLength": 80, + "pattern": "[\\w\\-&'()\\[\\]/.\"#$%\\^@!*+=,][\\w\\-&'()\\[\\]/.\"#$%\\^@!*+=, ]{1,79}" + }, + "ServiceOrganizationType": { + "type": "object", + "additionalProperties": false, + "description": "Defines a service organization which is either an organization or institution responsible for distributing, archiving, or processing the data via a service, etc.", + "properties": { + "Roles": { + "description": "This is the roles of the service organization.", + "type": "array", + "items": { + "$ref": "#/definitions/ServiceOrganizationRoleEnum" + }, + "minItems": 1 + }, + "ShortName": { + "description": "This is the short name of the service organization.", + "$ref": "#/definitions/ServiceOrganizationShortNameType" + }, + "LongName": { + "description": "This is the long name of the service organization.", + "$ref": "#/definitions/LongNameType" + }, + "OnlineResource": { + "description": "This is the URL of the service organization.", + "$ref": "#/definitions/OnlineResourceType" + } + }, + "required": ["Roles", "ShortName"] + }, + "ContactGroupType": { + "type": "object", + "additionalProperties": false, + "properties": { + "Roles": { + "description": "This is the roles of the service contact.", + "type": "array", + "items": { + "$ref": "#/definitions/ServiceContactRoleEnum" + }, + "minItems": 1 + }, + "ContactInformation": { + "description": "This is the contact information of the service contact.", + "$ref": "#/definitions/ContactInformationType" + }, + "GroupName": { + "description": "This is the contact group name.", + "type": "string", + "minLength": 1, + "maxLength": 255 + } + }, + "required": ["Roles", "GroupName"] + }, + "ContactPersonType": { + "type": "object", + "properties": { + "Roles": { + "description": "This is the roles of the service contact.", + "type": "array", + "items": { + "$ref": "#/definitions/ServiceOrganizationRoleEnum" + }, + "minItems": 1 + }, + "ContactInformation": { + "description": "This is the contact information of the service contact.", + "$ref": "#/definitions/ContactInformationType" + }, + "FirstName": { + "description": "First name of the individual.", + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "MiddleName": { + "description": "Middle name of the individual.", + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "LastName": { + "description": "Last name of the individual.", + "type": "string", + "minLength": 1, + "maxLength": 255 + } + }, + "required": ["Roles", "LastName"] + }, + "ContactInformationType": { + "type": "object", + "additionalProperties": false, + "description": "Defines the contact information of a service organization or service contact.", + "properties": { + "OnlineResources": { + "description": "A URL associated with the contact, e.g., the home page for the service provider which is responsible for the service.", + "type": "array", + "items": { + "$ref": "#/definitions/OnlineResourceType" + }, + "minItems": 1 + }, + "ServiceHours": { + "description": "Time period when the contact answers questions or provides services.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "ContactInstruction": { + "description": "Supplemental instructions on how or when to contact the responsible party.", + "type": "string", + "minLength": 1, + "maxLength": 2048 + }, + "ContactMechanisms": { + "description": "Mechanisms of contacting.", + "type": "array", + "items": { + "$ref": "#/definitions/ContactMechanismType" + } + }, + "Addresses": { + "description": "Contact addresses.", + "type": "array", + "items": { + "$ref": "#/definitions/AddressType" + } + } + } + }, + "ContactMechanismType": { + "type": "object", + "additionalProperties": false, + "description": "Method for contacting the service contact. A contact can be available via phone, email, Facebook, or Twitter.", + "properties": { + "Type": { + "description": "This is the method type for contacting the responsible party - phone, email, Facebook, or Twitter.", + "$ref": "#/definitions/ContactMechanismTypeEnum" + }, + "Value": { + "description": "This is the contact phone number, email address, Facebook address, or Twitter handle associated with the contact method.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + } + }, + "required": ["Type", "Value"] + }, + "ServiceOrganizationShortNameType": { + "description": "The unique name of the service organization.", + "type": "string", + "minLength": 1, + "maxLength": 85, + "pattern": "[\\w\\-&'()\\[\\]/.\"#$%\\^@!*+=,][\\w\\-&'()\\[\\]/.\"#$%\\^@!*+=, ]{1,84}" + }, + "ServiceOrganizationRoleEnum": { + "description": "Defines the possible values of a service provider role.", + "type": "string", + "enum": ["SERVICE PROVIDER", "DEVELOPER", "PUBLISHER", "AUTHOR", "ORIGINATOR"] + }, + "LongNameType": { + "description": "The expanded or long name related to the short name.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "ServiceTypeEnum": { + "description": "This element is used to identify the type of the service.", + "type": "string", + "enum": ["OPeNDAP", "THREDDS", "WEB SERVICES", "ESI", "ECHO ORDERS", "WCS", "WMS", "WMTS", "EGI - No Processing", "SOFTWARE PACKAGE", "TOOL", "WEB PORTAL", "International Web Portal", "MODEL", "NOT PROVIDED"] + }, + "ServiceQualityType": { + "type": "object", + "additionalProperties": false, + "description": "This object describes service quality, composed of the quality flag, the quality flagging system, traceability and lineage.", + "properties": { + "QualityFlag": { + "description": "The quality flag for the service.", + "$ref": "#/definitions/QualityFlagEnum" + }, + "Traceability": { + "description": "The quality traceability of the service.", + "type": "string", + "minLength": 1, + "maxLength": 100 + }, + "Lineage": { + "description": "The quality lineage of the service.", + "type": "string", + "minLength": 1, + "maxLength": 4000 + } + }, + "required": ["QualityFlag"] + }, + "QualityFlagEnum": { + "description": "Defines the possible quality flags.", + "type": "string", + "enum": ["Available", "Unavailable", "Reviewed", "Not Reviewed", "Other"] + }, + "AccessConstraintsType": { + "description": "Information about any constraints for accessing the service, software, or tool.", + "type": "string", + "minLength": 1, + "maxLength": 4000 + }, + "UseConstraintsType": { + "type": "object", + "additionalProperties": false, + "description": "Information on how the item (service, software, or tool) may or may not be used after access is granted. This includes any special restrictions, legal prerequisites, terms and conditions, and/or limitations on using the item. Providers may request acknowledgement of the item from users and claim no responsibility for quality and completeness.", + "properties": { + "LicenseURL": { + "description": "The web address of the license associated with the service.", + "type": "string", + "minLength": 0, + "maxLength": 1024 + }, + "LicenseText": { + "description": "The text of the license associated with the service.", + "type": "string", + "minLength": 0, + "maxLength": 20000 + } + } + }, + "AncillaryKeywordsType": { + "description": "Words or phrases to further describe the service, software, or tool.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "ServiceContactRoleEnum": { + "description": "Defines the possible values of a service provider role.", + "type": "string", + "enum": ["SERVICE PROVIDER CONTACT", "TECHNICAL CONTACT", "SCIENCE CONTACT", "INVESTIGATOR", "SOFTWARE AUTHOR", "TOOL AUTHOR", "USER SERVICES", "SCIENCE SOFTWARE DEVELOPMENT", "SERVICE PROVIDER"] + }, + "ContactMechanismTypeEnum": { + "description": "Defines the possible contact mechanism types.", + "type": "string", + "enum": ["Direct Line", "Email", "Facebook", "Fax", "Mobile", "Modem", "Primary", "TDD/TTY Phone", "Telephone", "Twitter", "U.S. toll free", "Other"] + }, + "AddressType": { + "type": "object", + "additionalProperties": false, + "description": "This entity contains the physical address details for the contact.", + "properties": { + "StreetAddresses": { + "description": "An address line for the street address, used for mailing or physical addresses of organizations or individuals who serve as contacts for the service.", + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "minItems": 0 + }, + "City": { + "description": "The city portion of the physical address.", + "type": "string", + "minLength": 1, + "maxLength": 100 + }, + "StateProvince": { + "description": "The state or province portion of the physical address.", + "type": "string", + "minLength": 1, + "maxLength": 100 + }, + "Country": { + "description": "The country of the physical address.", + "type": "string", + "minLength": 1, + "maxLength": 100 + }, + "PostalCode": { + "description": "The zip or other postal code portion of the physical address.", + "type": "string", + "minLength": 1, + "maxLength": 20 + } + } + }, + "OperationMetadataType": { + "type": "object", + "additionalProperties": false, + "description": "This class describes the signature of the operational metadata provided by the service.", + "properties": { + "OperationName": { + "description": "This element contains the name of the operation(s) made possible via this service.", + "type": "string", + "enum": ["GetCapabilities", "DescribeCoverage", "GetCoverage", "GetMap", "GetLegendGraphic", "GetTile", "GetFeatureInfo", "DescribeFeatureType", "GetPropertyValue", "GetFeature", "GetFeatureWithLock", "LockFeature", "Transaction", "CreateStoredQuery", "DropStoredQuery", "ListStoredQueries", "DescribeStoredQueries", "SPATIAL_SUBSETTING", "TEMPORAL_SUBSETTING", "VARIABLE_SUBSETTING", "VARIABLE_AGGREGATION" ] + }, + "DistributedComputingPlatform": { + "description": "This element contains the distributed computing platform (protocol) for the operation(s) made possible via this service.", + "type": "array", + "items": { + "$ref": "#/definitions/DistributedComputingPlatformTypeEnum" + }, + "minItems": 1 + }, + "OperationDescription": { + "description": "This element contains the description of the operation(s) made possible via this service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "InvocationName": { + "description": "This element contains the name of the invocation of the operation(s) made possible via this service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "ConnectPoint": { + "description": "This element contains the URL of the invocation of the operation(s) made possible via this service.", + "$ref": "#/definitions/ConnectPointType" + }, + "OperationChainedMetadata": { + "description": "This element contains the name of the chained operation(s) made possible via this service.", + "$ref": "#/definitions/OperationChainedMetadataType" + }, + "CoupledResource": { + "description": "This element contains important information about the resource(s) coupled to this service.", + "$ref": "#/definitions/CoupledResourceType" + }, + "Parameters": { + "description": "This element contains important information about the parameter associated with the resource(s) coupled to this service.", + "type": "array", + "items": { + "$ref": "#/definitions/ParameterType" + }, + "minItems": 0 + } + } + }, + "ConnectPointType": { + "type": "object", + "additionalProperties": false, + "description": "This element contains the URL of the invocation of the operation(s) made possible via this service.", + "properties": { + "ResourceName": { + "description": "This element contains the name of the resource(s) coupled to this service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "ResourceLinkage": { + "description": "This element contains the URL of the resource(s) coupled to this service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "ResourceDescription": { + "description": "This element contains the description of the resource(s) coupled to this service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + } + }, + "required": ["ResourceLinkage"] + }, + "OperationChainedMetadataType": { + "type": "object", + "additionalProperties": false, + "description": "This element contains the name of the chained operation(s) made possible via this service.", + "properties": { + "OperationChainName": { + "description": "TThis element contains the name of the operation chain made possible via this service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "OperationChainDescription": { + "description": "This element contains the description of the operation chain made possible via this service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + } + }, + "required": ["OperationChainName"] + }, + "CoupledResourceType": { + "type": "object", + "additionalProperties": false, + "description": "This element contains the name of the chained operation(s) made possible via this service.", + "properties": { + "ScopedName": { + "description": "This element contains the name of the resource(s) coupled to this service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "DataResourceDOI": { + "description": "This element contains the DOI for the resource(s) coupled to this service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "DataResource": { + "description": "This element contains the data identification and scope for the resource(s) coupled to this service.", + "$ref": "#/definitions/DataResourceType" + }, + "CouplingType": { + "description": "This element contains the coupling type for the resource(s) coupled to this service.", + "$ref": "#/definitions/CouplingTypeEnum" + } + } + }, + "DataResourceType": { + "type": "object", + "additionalProperties": false, + "description": "The DataResource class describes the layers, feature types or coverages available from the service.", + "properties": { + "DataResourceIdentifier": { + "description": "The identifier of the layer, feature type or coverage available from the service.", + "type": "string", + "minLength": 1, + "maxLength": 100 + }, + "DataResourceSourceType": { + "description": "The resource type of the layer, feature type or coverage available from the service.", + "type": "string", + "enum": ["Map", "Variable", "Granule", "Collection", "Virtual"] + }, + "DataResourceSpatialExtent": { + "description": "The spatial extent of the coverage available from the service. These are coordinate pairs which describe either the point, line string, or polygon representing the spatial extent. The bounding box is described by the west, south, east and north ordinates", + "$ref": "#/definitions/DataResourceSpatialExtentType" + }, + "DataResourceSpatialType": { + "description": "The spatial extent of the layer, feature type or coverage available from the service.", + "$ref": "#/definitions/DataResourceSpatialTypeEnum" + }, + "SpatialResolution": { + "description": "The spatial resolution of the layer, feature type or coverage available from the service.", + "type": "number" + }, + "SpatialResolutionUnit": { + "description": "The unit of the spatial resolution of the layer, feature type or coverage available from the service.", + "type": "string", + "enum": ["Meters", "KM", "Degrees", "Degrees_North", "Degrees_East"] + }, + "DataResourceTemporalExtent": { + "description": "The temporal extent of the layer, feature type or coverage available from the service.", + "$ref": "#/definitions/DataResourceTemporalExtentType" + }, + "DataResourceTemporalType": { + "description": "The temporal extent of the layer, feature type or coverage available from the service.", + "$ref": "#/definitions/DataResourceTemporalTypeEnum" + }, + "TemporalResolution": { + "description": "TThe temporal resolution of the layer, feature type or coverage available from the service.", + "type": "number" + }, + "TemporalResolutionUnit": { + "description": "The unit of the temporal resolution of the layer, feature type or coverage available from the service.", + "type": "string", + "enum": ["DAY", "TWICE_PER_DAY", "WEEK", "MONTH", "YEAR"] + }, + "RelativePath": { + "description": "Path relative to the root URL for the layer, feature type or coverage service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + } + } + }, + "ParameterType": { + "type": "object", + "additionalProperties": false, + "description": "This element contains important information about the parameter associated with the resource(s) coupled to this service.", + "properties": { + "ParameterName": { + "description": "This element contains the name of the parameter associated with the resource(s) coupled to this service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "ParameterDirection": { + "description": "This element contains the direction of the parameter associated with the resource(s) coupled to this service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "ParameterDescription": { + "description": "This element contains the description of the parameter associated with the resource(s) coupled to this service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "ParameterOptionality": { + "description": "This element contains the optionality of the parameter associated with the resource(s) coupled to this service", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "ParameterRepeatability": { + "description": "This element contains the repeatability of the parameter associated with the resource(s) coupled to this service.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + } + }, + "required": ["ParameterName", "ParameterDescription", "ParameterDirection", "ParameterOptionality", "ParameterRepeatability"] + }, + "CoordinatesType": { + "type": "object", + "additionalProperties": false, + "description": "The coordinates consist of a latitude and longitude.", + "properties": { + "Latitude": { + "description": "The latitude of the point.", + "type": "number" + }, + "Longitude": { + "description": "The longitude of the point.", + "type": "number" + } + }, + "required": ["Latitude", "Longitude"] + }, + "LineStringType": { + "type": "object", + "additionalProperties": false, + "description": "The line string consists of two points: a start point and an end ppint.", + "properties": { + "StartPoint": { + "description": "The start point of the line string.", + "$ref": "#/definitions/CoordinatesType" + }, + "EndPoint": { + "description": "The end point of the line string.", + "$ref": "#/definitions/CoordinatesType" + } + }, + "required": ["StartPoint", "EndPoint"] + }, + "SpatialBoundingBoxType": { + "type": "object", + "additionalProperties": false, + "description": "The bounding box consists of west bounding, south bounding, east bounding and north bounding coordinates and the CRS identifier.", + "properties": { + "CRSIdentifier": { + "description": "The CRS identifier of the bounding box.", + "$ref": "#/definitions/CRSIdentifierTypeEnum" + }, + "WestBoundingCoordinate": { + "description": "The west bounding coordinate of the bounding box.", + "type": "number" + }, + "SouthBoundingCoordinate": { + "description": "The south bounding coordinate of the bounding box.", + "type": "number" + }, + "EastBoundingCoordinate": { + "description": "The east bounding coordinate of the bounding box.", + "type": "number" + }, + "NorthBoundingCoordinate": { + "description": "The north bounding coordinate of the bounding box.", + "type": "number" + } + }, + "required": ["CRSIdentifier", "WestBoundingCoordinate", "SouthBoundingCoordinate", "EastBoundingCoordinate", "NorthBoundingCoordinate"] + }, + "GeneralGridType": { + "type": "object", + "additionalProperties": false, + "description": "The general grid consists of a CRS Identifier and an Axis.", + "properties": { + "CRSIdentifier": { + "description": "The CRS identifier (srsName) of the general grid.", + "$ref": "#/definitions/CRSIdentifierTypeEnum" + }, + "Axis": { + "description": "The grid axis identifiers, all distinct within a grid.", + "type": "array", + "items": { + "$ref": "#/definitions/AxisType" + }, + "minItems": 1 + } + }, + "required": ["CRSIdentifier", "Axis"] + }, + "AxisType": { + "type": "object", + "additionalProperties": false, + "description": "The axis consists of an extent and grid information.", + "properties": { + "AxisLabel": { + "description": "The axis label of the general grid.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "GridResolution": { + "description": "The resolution of the general grid.", + "type": "number" + }, + "Extent": { + "description": "The extent of the general grid.", + "$ref": "#/definitions/ExtentType" + } + }, + "required": ["AxisLabel", "Extent"] + }, + "ExtentType": { + "type": "object", + "additionalProperties": false, + "description": "The extent consists of .", + "properties": { + "ExtentLabel": { + "description": "The label of the extent.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + }, + "LowerBound": { + "description": "The lowest value along this grid axis.", + "type": "number" + }, + "UpperBound": { + "description": "The highest value along this grid axis.", + "type": "number" + }, + "UOMLabel": { + "description": "The unit of measure in which values along this axis are expressed.", + "type": "string", + "minLength": 1, + "maxLength": 1024 + } + }, + "required": ["LowerBound", "UpperBound", "UOMLabel"] + }, + "DataResourceSpatialExtentType": { + "type": "object", + "properties": { + "SpatialPoints": { + "description": "The spatial extent of the layer, feature type or coverage described by a point.", + "type": "array", + "items": { + "$ref": "#/definitions/CoordinatesType" + }, + "minItems": 0 + }, + "SpatialLineStrings": { + "description": "The spatial extent of the layer, feature type or coverage described by a line string.", + "type": "array", + "items": { + "$ref": "#/definitions/LineStringType" + }, + "minItems": 0 + }, + "SpatialBoundingBox": { + "description": "The spatial extent of the layer, feature type or coverage described by a bounding box.", + "$ref": "#/definitions/SpatialBoundingBoxType" + }, + "GeneralGrid": { + "description": "The spatial extent of the layer, feature type or coverage described by a general grid.", + "$ref": "#/definitions/GeneralGridType" + }, + "SpatialPolygons": { + "description": "The spatial extent of the layer, feature type or coverage described by a polygon.", + "type": "array", + "items": { + "$ref": "#/definitions/CoordinatesType" + }, + "minItems": 0 + } + } + }, + "DataResourceTemporalExtentType": { + "type": "object", + "properties": { + "DataResourceTimePoints": { + "description": "Points in time representing the temporal extent of the layer or coverage.", + "type": "array", + "items": { + "$ref": "#/definitions/TimePointsType" + }, + "minItems": 1 + } + } + }, + "TimePointsType": { + "type": "object", + "properties": { + "TimeFormat": { + "description": "Time format representing time point of the temporal extent.", + "type": "string", + "minLength": 1, + "maxLength": 80 + }, + "TimeValue": { + "description": "Time value of the time point of temporal extent.", + "type": "string", + "minLength": 1, + "maxLength": 80 + }, + "Description": { + "description": "Description of the time value of the temporal extent.", + "type": "string", + "minLength": 1, + "maxLength": 80 + } + } + }, + "DataResourceSpatialTypeEnum": { + "description": "The spatial extent of the layer, feature type or coverage available from the service. These are coordinate pairs which describe either the point, line string, boundingbox, general grid, or polygon representing the spatial extent.", + "type": "string", + "enum": ["SPATIAL_POINT", "SPATIAL_LINE_STRING", "BOUNDING_BOX", "SPATIAL_POLYGON", "GENERAL_GRID"] + }, + "CRSIdentifierTypeEnum": { + "description": "The CRS Identifier of the spatial extent, expressed as a code.", + "type": "string", + "enum": ["EPSG:4326", "EPSG:3395", "EPSG:3785", "EPSG:9807", "EPSG:2000.63", "EPSG:2163", "EPSG:3408", "EPSG:3410", "EPSG:6931", "EPSG:6933", "EPSG:3411", "EPSG:9822", "EPSG:54003", "EPSG:54004", "EPSG:54008", "EPSG:54009", "EPSG:26917", "EPSG:900913", "Other"] + }, + "DataResourceTemporalTypeEnum": { + "description": "The temporal extent of the layer, feature type or coverage available from the service.", + "type": "string", + "enum": ["TIME_STAMP", "TIME_RANGE", "TIME_SERIES", "TIME_AVERAGE"] + }, + "CouplingTypeEnum": { + "description": "This element contains the coupling type for the resource(s) coupled to this service. Examples are: 'LOOSE' - this is where a variety of data sources (which are not specified precisely) are used to generate the resource, 'MIXED' - this is where a combination of well-cited data sources are used to generate the resource, 'TIGHT - this is where a single well-cited data source is used to generate the resource.", + "type": "string", + "enum": ["LOOSE", "MIXED", "TIGHT"] + }, + "DistributedComputingPlatformTypeEnum": { + "description": "This element contains the distributed computing platform (protocol) for the operation(s) made possible via this service.", + "type": "string", + "enum": ["XML", "CORBA", "JAVA", "COM", "SQL", "SOAP", "Z3950", "HTTP", "HTTPS", "FTP", "WEBSERVICES"] + } + } +} diff --git a/umm-spec-lib/resources/json-schemas/service/umm/v1.3.3/umm-s-search-results-json-schema.json b/umm-spec-lib/resources/json-schemas/service/umm/v1.3.3/umm-s-search-results-json-schema.json new file mode 100644 index 0000000000..b72e6fb550 --- /dev/null +++ b/umm-spec-lib/resources/json-schemas/service/umm/v1.3.3/umm-s-search-results-json-schema.json @@ -0,0 +1,112 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "definitions": { + "ItemType": { + "type": "object", + "additionalProperties": false, + "description": "Represents a single item found in search results. It contains some metadata about the item found along with the UMM representing the item. umm won't be present if the item represents a tombstone.", + "properties": { + "meta": { + "$ref": "#/definitions/MetaType" + }, + "umm": { + "$ref": "umm-s-json-schema.json" + } + }, + "required": ["meta"] + }, + "MetaType": { + "type": "object", + "additionalProperties": false, + "description": "CMR level metadata about the item found. This represents data not found in the actual metadata.", + "properties": { + "provider-id": { + "description": "The identity of the provider in the CMR", + "type": "string", + "minLength": 1, + "pattern": "[A-Z0-9_]+" + }, + "concept-type": { + "description": "The type of item found.", + "type": "string", + "enum": ["service"] + }, + "native-id": { + "description": "The id used by the provider to identify this item during ingest.", + "type": "string", + "minLength": 1 + }, + "concept-id": { + "description": "The concept id of the item found.", + "type": "string", + "minLength": 4, + "pattern": "[A-Z]+\\d+-[A-Z0-9_]+" + }, + "revision-id": { + "description": "A number >= 1 that indicates which revision of the item.", + "type": "number" + }, + "revision-date": { + "description": "The date this revision was created. This would be the creation or update date of the item in the CMR.", + "format": "date-time", + "type": "string" + }, + "user-id": { + "description": "The id of the user who created this item revision.", + "type": "string", + "minLength": 1 + }, + "deleted": { + "description": "Indicates if the item represents a tombstone", + "type": "boolean" + }, + "format": { + "description": "The mime type of the original metadata", + "type": "string", + "minLength": 1 + } + }, + "required": ["provider-id", "concept-type", "native-id", "concept-id", "revision-id", "revision-date"] + }, + "ConceptRevisionType": { + "type": "object", + "additionalProperties": false, + "description": "Concept id and revision id.", + "properties": { + "concept-id": { + "description": "The concept id of the item found.", + "type": "string", + "minLength": 4, + "pattern": "[A-Z]+\\d+-[A-Z0-9_]+" + }, + "revision-id": { + "description": "A number >= 1 that indicates which revision of the item.", + "type": "number" + } + }, + "required": ["concept-id"] + } + }, + "title": "UMM Search Results", + "type": "object", + "additionalProperties": false, + "properties": { + "hits": { + "description": "The total number of items that matched the search.", + "type": "number" + }, + "took": { + "description": "How long the search took in milliseconds from the time the CMR received the request until it had generated the response. This does not include network traffic time to send the request or return the response.", + "type": "number" + }, + "items": { + "description": "The list of items matching the result in this page.", + "type": "array", + "items": { + "$ref": "#/definitions/ItemType" + }, + "minItems": 0 + } + }, + "required": ["hits", "took", "items"] +} diff --git a/umm-spec-lib/src/cmr/umm_spec/migration/service_service_options.clj b/umm-spec-lib/src/cmr/umm_spec/migration/service_service_options.clj new file mode 100644 index 0000000000..ff265cd8ee --- /dev/null +++ b/umm-spec-lib/src/cmr/umm_spec/migration/service_service_options.clj @@ -0,0 +1,230 @@ +(ns cmr.umm-spec.migration.service-service-options + "Contains functions for migrating between versions of the UMM Service schema + for service options." + (:require + [clojure.set :as set])) + +(defn- duplicate-supported-projections + "Duplicate the SupportedProjections in v1.1 ServiceOptions to SupportedInputProjections + and SupportedOutputProjections in v1.2 ServiceOptions when migrate from 1.1 to 1.2." + [service-options] + (-> service-options + (assoc :SupportedInputProjections (seq (map #(hash-map :ProjectionName %) + (:SupportedProjections service-options)))) + (assoc :SupportedOutputProjections (seq (map #(hash-map :ProjectionName %) + (:SupportedProjections service-options)))) + (dissoc :SupportedProjections))) + +(defn- duplicate-supported-formats + "Duplicate the SupportedFormats in v1.1 ServiceOptions to SupportedInputFormats + and SupportedOutputFormats in v1.2 ServiceOptions when migrate from 1.1 to 1.2." + [service-options] + (-> service-options + (assoc :SupportedInputFormats (:SupportedFormats service-options)) + (assoc :SupportedOutputFormats (:SupportedFormats service-options)) + (dissoc :SupportedFormats))) + +(def v1-1-supported-formats-enum->v1-2-supported-formats-enum + "Defines SupportedFormats ENUM changes from v1.1 to v1.2" + {"HDF4" "HDF4" + "HDF5" "HDF5" + "HDF-EOS4" "HDF-EOS2" + "HDF-EOS5" "HDF-EOS5" + "netCDF-3" "NETCDF-3" + "netCDF-4" "NETCDF-4" + "Binary" "BINARY" + "ASCII" "ASCII" + "PNG" "PNG" + "JPEG" "JPEG" + "GeoTIFF" "GEOTIFF" + "image/png" "PNG" + "image/tiff" "TIFF" + "image/gif" "GIF" + "image/png; mode=24bit" "PNG24" + "image/jpeg" "JPEG" + "image/vnd.wap.wbmp" "BMP"}) + +(def v1-2-supported-formats-enum->v1-1-supported-formats-enum + "Defines SupportedFormats ENUM changes from v1.2 to v1.1" + (-> v1-1-supported-formats-enum->v1-2-supported-formats-enum + set/map-invert + (assoc "HDF-EOS" "HDF-EOS5"))) + +(defn- supported-Formats-1-1->1-2 + "Migrate SupportedFormats from vector of 1.1 enums to vector of 1.2 enums." + [supported-formats] + (let [supported-formats (->> supported-formats + (map #(get v1-1-supported-formats-enum->v1-2-supported-formats-enum %)) + (remove nil?))] + (when (seq supported-formats) + (vec supported-formats)))) + +(defn- v1-1-supported-formats->v1-2-supported-formats + "Migrate v1.1 supported formats in ServiceOptions to v1.2" + [service-options] + (-> service-options + (update :SupportedFormats supported-Formats-1-1->1-2) + duplicate-supported-formats)) + +(defn- revert-supported-projections + "Revert the SupportedInputProjections and SupportedOutputProjections in v1.2 ServiceOptions + to SupportedProjections in v1.1 ServiceOptions when migrate from 1.2 to 1.1." + [service-options] + (-> service-options + (assoc :SupportedProjections (seq (map :ProjectionName + (:SupportedInputProjections service-options)))) + (dissoc :SupportedInputProjections :SupportedOutputProjections))) + +(defn- supported-Formats-1-2->1-1 + "Migrate SupportedFormats from vector of 1.2 enums to vector of 1.1 enums." + [supported-formats] + (let [supported-formats (->> supported-formats + (map #(get v1-2-supported-formats-enum->v1-1-supported-formats-enum %)) + (remove nil?))] + (when (seq supported-formats) + (vec supported-formats)))) + +(defn- revert-supported-formats + "Revert the SupportedInputFormats and SupportedOutputFormats in v1.2 ServiceOptions + to SupportedFormats in v1.1 ServiceOptions when migrate from 1.2 to 1.1." + [service-options] + (-> service-options + (assoc :SupportedFormats (:SupportedInputFormats service-options)) + (dissoc :SupportedInputFormats :SupportedOutputFormats))) + +(defn- v1-2-supported-formats->v1-1-supported-formats + "Migrate v1.2 supported formats in ServiceOptions to v1.1" + [service-options] + (-> service-options + revert-supported-formats + (update :SupportedFormats supported-Formats-1-2->1-1))) + +(defn v1-1-service-options->v1-2-service-options + "Migrate v1.1 ServiceOptions to v1.2" + [service-options] + (-> service-options + duplicate-supported-projections + v1-1-supported-formats->v1-2-supported-formats)) + +(defn v1-2-service-options->v1-1-service-options + "Migrate v1.2 ServiceOptions to v1.1" + [service-options] + (-> service-options + revert-supported-projections + v1-2-supported-formats->v1-1-supported-formats + (dissoc :VariableAggregationSupportedMethods :MaxGranules))) + +(def CRSIdentifierTypeEnum-service-1_2 + "These are the valid enum values in UMM-S 1.2. These are used to migrate ServiceOptions + SupportedInputProjections/SupportedOutputProjections ProjectionAuthority string in version 1.3 to 1.2." + ["4326", "3395", "3785", "9807", "2000.63", "2163", "3408", "3410", "6931", + "6933", "3411", "9822", "54003", "54004", "54008", "54009", "26917", "900913"]) + +(defn check-projection-valid-values + "For a projection check to see if the ProjectionAuthority is a valid value for UMM-S 1.2. + If it is then use as is, if not them remove the invalid value. Return a Valid UMM-S version + 1.2 SupportedProjectionType object." + [projection] + (if (some #(= (:ProjectionAuthority projection) %) CRSIdentifierTypeEnum-service-1_2) + projection + (dissoc projection :ProjectionAuthority))) + +(defn remove-non-valid-formats + "Remove the formats that are not valid for UMM-S version 1.2." + [formats] + (remove #(= "ZARR" %) formats)) + +(defn update-projections + "Iterate through each projection calling the check-projection-valid-values function + checking to see if the ProjectionAuthority is valid. Return a list of Valid UMM-S version 1.2 + SupportedProjectionType objects." + [projections] + (map #(check-projection-valid-values %) projections)) + +(defn update-service-options-1_3->1_2 + "Update the service options from the passed in 1.3 UMM-S record to a valid UMM-S version 1.2 record." + [s] + (-> s + (update-in [:ServiceOptions :SupportedInputProjections] update-projections) + (update-in [:ServiceOptions :SupportedOutputProjections] update-projections) + (update :ServiceOptions dissoc :SupportedReformattings) + (update-in [:ServiceOptions :SupportedInputFormats] remove-non-valid-formats) + (update-in [:ServiceOptions :SupportedOutputFormats] remove-non-valid-formats))) + +(defn create-supported-reformatting-for-1-3 + "This function takes the format input and output and creates a single SupportedReformattingsPairType." + [input-format output-format] + {:SupportedInputFormat input-format + :SupportedOutputFormat output-format}) + +(defn update-supported-reformatting-for-1-3 + "This function takes a 1.3.1 SupportedReformattingsPairType and iterates through the SupportedOutputFormats + list creating single input and output format pairs for UMM-S version 1.3 SupportedReformattingsPairType." + [supported-reformatting] + (let [input-format (:SupportedInputFormat supported-reformatting)] + (map #(create-supported-reformatting-for-1-3 input-format %) (:SupportedOutputFormats supported-reformatting)))) + +(defn update-supported-reformattings-for-1-3 + "Iterate through the passed in supported reformattings and update each one." + [supported-reformattings] + (mapcat #(update-supported-reformatting-for-1-3 %) supported-reformattings)) + +(defn update-service-options-1_3_1->1_3 + "Update the service options from the passed in 1.3.1 UMM-S record to a valid UMM-S version 1.3 record." + [s] + (update-in s [:ServiceOptions :SupportedReformattings] update-supported-reformattings-for-1-3)) + +(defn get-supported-output-formats + "The input is a vector of maps. Example: [{:SupportedInputFormat HDF5 + :SupportedOutputFormat H1} + {:SupportedInputFormat HDF5 + :SupportedOutputFormat H2} + Return a vector of values from the SupportedOutputFormat key. Example: [H1 H2]" + [vector-of-maps] + (into [] (map :SupportedOutputFormat vector-of-maps))) + +(defn build-supported-reformattings-pair-for-1-3-1 + "Build a list of version 1.3.1 SupportedReformattingsPairType. The input is a vector that contains + 2 items. The first is the input format and the second is a vector of version 1.3 + SupportedReformattingsPairTypes. (Ex. {HDF5 [{:SupportedInputFormat HDF5, + :SupportedOutputFormat H1} + {:SupportedInputFormat HDF5, + :SupportedOutputFormat H2})." + [vector-of-a-group] + {:SupportedInputFormat (first vector-of-a-group) + :SupportedOutputFormats (get-supported-output-formats (second vector-of-a-group))}) + +(defn update-supported-reformattings-for-1-3-1 + "Iterate through each supported-reformatting pairs to migrate the SupportedOutputFormat to + SupportedOutputFormats." + [supported-reformattings] + (let [group (group-by :SupportedInputFormat supported-reformattings)] + (map #(build-supported-reformattings-pair-for-1-3-1 %) group))) + +(defn update-service-options-1_3->1_3_1 + "Update the service options from the passed in 1.3.1 UMM-S record to a valid UMM-S version 1.3 record." + [s] + (def s s) + (update-in s [:ServiceOptions :SupportedReformattings] #(update-supported-reformattings-for-1-3-1 %))) + +(defn remove-non-valid-formats-1_3_3-to-1_3_2 + "Remove the non valid Supported Format enumerations when migrating to 1.3.2 from 1.3.3." + [supported-formats] + (->> supported-formats + (remove #(= "Shapefile" %)) + (remove #(= "GeoJSON" %)) + (remove #(= "COG" %)) + (remove #(= "WKT" %)) + seq)) + +(defn remove-reformattings-when-input-not-valid + [reformatting] + (def reformatting reformatting) + (let [input (remove-non-valid-formats-1_3_3-to-1_3_2 (vector (:SupportedInputFormat reformatting)))] + (when input + (update reformatting :SupportedOutputFormats remove-non-valid-formats-1_3_3-to-1_3_2)))) + +(defn remove-reformattings-non-valid-formats + "Remove the non valid formats going from UMM-S version 1.3.3 to UMM-S version 1.3.2" + [reformattings] + (remove nil? (map #(remove-reformattings-when-input-not-valid %) reformattings))) diff --git a/umm-spec-lib/src/cmr/umm_spec/migration/version/service.clj b/umm-spec-lib/src/cmr/umm_spec/migration/version/service.clj index c062b5da06..73ec744d8d 100644 --- a/umm-spec-lib/src/cmr/umm_spec/migration/version/service.clj +++ b/umm-spec-lib/src/cmr/umm_spec/migration/version/service.clj @@ -4,7 +4,7 @@ [clojure.set :as set] [clojure.string :as string] [cmr.common.util :as util] - [cmr.common.log :as log] + [cmr.umm-spec.migration.service-service-options :as service-options] [cmr.umm-spec.migration.version.interface :as interface])) (defn- migrate-related-url-subtype-down @@ -43,116 +43,6 @@ (dissoc :Type)) (dissoc coverage-type :Type))) -(defn- duplicate-supported-projections - "Duplicate the SupportedProjections in v1.1 ServiceOptions to SupportedInputProjections - and SupportedOutputProjections in v1.2 ServiceOptions when migrate from 1.1 to 1.2." - [service-options] - (-> service-options - (assoc :SupportedInputProjections (seq (map #(hash-map :ProjectionName %) - (:SupportedProjections service-options)))) - (assoc :SupportedOutputProjections (seq (map #(hash-map :ProjectionName %) - (:SupportedProjections service-options)))) - (dissoc :SupportedProjections))) - -(defn- duplicate-supported-formats - "Duplicate the SupportedFormats in v1.1 ServiceOptions to SupportedInputFormats - and SupportedOutputFormats in v1.2 ServiceOptions when migrate from 1.1 to 1.2." - [service-options] - (-> service-options - (assoc :SupportedInputFormats (:SupportedFormats service-options)) - (assoc :SupportedOutputFormats (:SupportedFormats service-options)) - (dissoc :SupportedFormats))) - -(def v1-1-supported-formats-enum->v1-2-supported-formats-enum - "Defines SupportedFormats ENUM changes from v1.1 to v1.2" - {"HDF4" "HDF4" - "HDF5" "HDF5" - "HDF-EOS4" "HDF-EOS2" - "HDF-EOS5" "HDF-EOS5" - "netCDF-3" "NETCDF-3" - "netCDF-4" "NETCDF-4" - "Binary" "BINARY" - "ASCII" "ASCII" - "PNG" "PNG" - "JPEG" "JPEG" - "GeoTIFF" "GEOTIFF" - "image/png" "PNG" - "image/tiff" "TIFF" - "image/gif" "GIF" - "image/png; mode=24bit" "PNG24" - "image/jpeg" "JPEG" - "image/vnd.wap.wbmp" "BMP"}) - -(def v1-2-supported-formats-enum->v1-1-supported-formats-enum - "Defines SupportedFormats ENUM changes from v1.2 to v1.1" - (-> v1-1-supported-formats-enum->v1-2-supported-formats-enum - set/map-invert - (assoc "HDF-EOS" "HDF-EOS5"))) - -(defn- supported-Formats-1-1->1-2 - "Migrate SupportedFormats from vector of 1.1 enums to vector of 1.2 enums." - [supported-formats] - (let [supported-formats (->> supported-formats - (map #(get v1-1-supported-formats-enum->v1-2-supported-formats-enum %)) - (remove nil?))] - (when (seq supported-formats) - (vec supported-formats)))) - -(defn- v1-1-supported-formats->v1-2-supported-formats - "Migrate v1.1 supported formats in ServiceOptions to v1.2" - [service-options] - (-> service-options - (update :SupportedFormats supported-Formats-1-1->1-2) - duplicate-supported-formats)) - -(defn- revert-supported-projections - "Revert the SupportedInputProjections and SupportedOutputProjections in v1.2 ServiceOptions - to SupportedProjections in v1.1 ServiceOptions when migrate from 1.2 to 1.1." - [service-options] - (-> service-options - (assoc :SupportedProjections (seq (map :ProjectionName - (:SupportedInputProjections service-options)))) - (dissoc :SupportedInputProjections :SupportedOutputProjections))) - -(defn- supported-Formats-1-2->1-1 - "Migrate SupportedFormats from vector of 1.2 enums to vector of 1.1 enums." - [supported-formats] - (let [supported-formats (->> supported-formats - (map #(get v1-2-supported-formats-enum->v1-1-supported-formats-enum %)) - (remove nil?))] - (when (seq supported-formats) - (vec supported-formats)))) - -(defn- revert-supported-formats - "Revert the SupportedInputFormats and SupportedOutputFormats in v1.2 ServiceOptions - to SupportedFormats in v1.1 ServiceOptions when migrate from 1.2 to 1.1." - [service-options] - (-> service-options - (assoc :SupportedFormats (:SupportedInputFormats service-options)) - (dissoc :SupportedInputFormats :SupportedOutputFormats))) - -(defn- v1-2-supported-formats->v1-1-supported-formats - "Migrate v1.2 supported formats in ServiceOptions to v1.1" - [service-options] - (-> service-options - revert-supported-formats - (update :SupportedFormats supported-Formats-1-2->1-1))) - -(defn- v1-1-service-options->v1-2-service-options - "Migrate v1.1 ServiceOptions to v1.2" - [service-options] - (-> service-options - duplicate-supported-projections - v1-1-supported-formats->v1-2-supported-formats)) - -(defn- v1-2-service-options->v1-1-service-options - "Migrate v1.2 ServiceOptions to v1.1" - [service-options] - (-> service-options - revert-supported-projections - v1-2-supported-formats->v1-1-supported-formats - (dissoc :VariableAggregationSupportedMethods :MaxGranules))) - (defn- fix-contact-info "Drops Uuid and NonServiceOrganizationAffiliation fields from the given contact list when migrating from v1.1 to v1.2" @@ -294,43 +184,6 @@ "WMTS" (assoc s :Type "WMS") s)) -(def CRSIdentifierTypeEnum-service-1_2 - "These are the valid enum values in UMM-S 1.2. These are used to migrate ServiceOptions - SupportedInputProjections/SupportedOutputProjections ProjectionAuthority string in version 1.3 to 1.2." - ["4326", "3395", "3785", "9807", "2000.63", "2163", "3408", "3410", "6931", - "6933", "3411", "9822", "54003", "54004", "54008", "54009", "26917", "900913"]) - -(defn check-projection-valid-values - "For a projection check to see if the ProjectionAuthority is a valid value for UMM-S 1.2. - If it is then use as is, if not them remove the invalid value. Return a Valid UMM-S version - 1.2 SupportedProjectionType object." - [projection] - (if (some #(= (:ProjectionAuthority projection) %) CRSIdentifierTypeEnum-service-1_2) - projection - (dissoc projection :ProjectionAuthority))) - -(defn remove-non-valid-formats - "Remove the formats that are not valid for UMM-S version 1.2." - [formats] - (remove #(= "ZARR" %) formats)) - -(defn update-projections - "Iterate through each projection calling the check-projection-valid-values function - checking to see if the ProjectionAuthority is valid. Return a list of Valid UMM-S version 1.2 - SupportedProjectionType objects." - [projections] - (map #(check-projection-valid-values %) projections)) - -(defn update-service-options-1_3->1_2 - "Update the service options from the passed in 1.3 UMM-S record to a valid UMM-S version 1.2 record." - [s] - (-> s - (update-in [:ServiceOptions :SupportedInputProjections] update-projections) - (update-in [:ServiceOptions :SupportedOutputProjections] update-projections) - (update :ServiceOptions dissoc :SupportedReformattings) - (update-in [:ServiceOptions :SupportedInputFormats] remove-non-valid-formats) - (update-in [:ServiceOptions :SupportedOutputFormats] remove-non-valid-formats))) - (defn remove-non-valid-operation-name "Remove the operation metadata if the OperationName is GetTile. This is not a valid option in version 1.2." @@ -389,62 +242,6 @@ (util/remove-nil-keys) (util/remove-empty-maps))) -(defn create-supported-reformatting-for-1-3 - "This function takes the format input and output and creates a single SupportedReformattingsPairType." - [input-format output-format] - {:SupportedInputFormat input-format - :SupportedOutputFormat output-format}) - -(defn update-supported-reformatting-for-1-3 - "This function takes a 1.3.1 SupportedReformattingsPairType and iterates through the SupportedOutputFormats - list creating single input and output format pairs for UMM-S version 1.3 SupportedReformattingsPairType." - [supported-reformatting] - (let [input-format (:SupportedInputFormat supported-reformatting)] - (map #(create-supported-reformatting-for-1-3 input-format %) (:SupportedOutputFormats supported-reformatting)))) - -(defn update-supported-reformattings-for-1-3 - "Iterate through the passed in supported reformattings and update each one." - [supported-reformattings] - (mapcat #(update-supported-reformatting-for-1-3 %) supported-reformattings)) - -(defn update-service-options-1_3_1->1_3 - "Update the service options from the passed in 1.3.1 UMM-S record to a valid UMM-S version 1.3 record." - [s] - (update-in s [:ServiceOptions :SupportedReformattings] update-supported-reformattings-for-1-3)) - -(defn get-supported-output-formats - "The input is a vector of maps. Example: [{:SupportedInputFormat HDF5 - :SupportedOutputFormat H1} - {:SupportedInputFormat HDF5 - :SupportedOutputFormat H2} - Return a vector of values from the SupportedOutputFormat key. Example: [H1 H2]" - [vector-of-maps] - (into [] (map :SupportedOutputFormat vector-of-maps))) - -(defn build-supported-reformattings-pair-for-1-3-1 - "Build a list of version 1.3.1 SupportedReformattingsPairType. The input is a vector that contains - 2 items. The first is the input format and the second is a vector of version 1.3 - SupportedReformattingsPairTypes. (Ex. {HDF5 [{:SupportedInputFormat HDF5, - :SupportedOutputFormat H1} - {:SupportedInputFormat HDF5, - :SupportedOutputFormat H2})." - [vector-of-a-group] - {:SupportedInputFormat (first vector-of-a-group) - :SupportedOutputFormats (get-supported-output-formats (second vector-of-a-group))}) - -(defn update-supported-reformattings-for-1-3-1 - "Iterate through each supported-reformatting pairs to migrate the SupportedOutputFormat to - SupportedOutputFormats." - [supported-reformattings] - (let [group (group-by :SupportedInputFormat supported-reformattings)] - (map #(build-supported-reformattings-pair-for-1-3-1 %) group))) - -(defn update-service-options-1_3->1_3_1 - "Update the service options from the passed in 1.3.1 UMM-S record to a valid UMM-S version 1.3 record." - [s] - (def s s) - (update-in s [:ServiceOptions :SupportedReformattings] #(update-supported-reformattings-for-1-3-1 %))) - (defn update-url-with-default-values "If a value exists then pass it back. If not, given the passed in key (k) pass back the default value." @@ -539,7 +336,7 @@ (defmethod interface/migrate-umm-version [:service "1.1" "1.2"] [context s & _] (-> s - (update :ServiceOptions v1-1-service-options->v1-2-service-options) + (update :ServiceOptions service-options/v1-1-service-options->v1-2-service-options) (fix-contacts :ContactGroups) (fix-contacts :ContactPersons) (util/update-in-each [:ServiceOrganizations] #(fix-contacts % :ContactGroups)) @@ -550,7 +347,7 @@ (defmethod interface/migrate-umm-version [:service "1.2" "1.1"] [context s & _] (-> s - (update :ServiceOptions v1-2-service-options->v1-1-service-options) + (update :ServiceOptions service-options/v1-2-service-options->v1-1-service-options) (update :Type v1-2-type->v1-1-type) (update :LongName #(util/trunc % 120)) (dissoc :OperationMetadata) @@ -580,7 +377,7 @@ (update :UseConstraints #(get % :LicenseText)) (assoc :RelatedURLs url) (assoc :ServiceOrganizations service-orgs) - (update-service-options-1_3->1_2) + (service-options/update-service-options-1_3->1_2) (assoc :OperationMetadata op-metadata) (dissoc :URL :LastUpdatedDate @@ -590,11 +387,11 @@ [context s & _] (-> s (update :URL update-url-1_3->1_3_1) - (update-service-options-1_3->1_3_1))) + (service-options/update-service-options-1_3->1_3_1))) (defmethod interface/migrate-umm-version [:service "1.3.1" "1.3"] [context s & _] - (update-service-options-1_3_1->1_3 s)) + (service-options/update-service-options-1_3_1->1_3 s)) (defmethod interface/migrate-umm-version [:service "1.3.1" "1.3.2"] [context s & _] @@ -612,3 +409,15 @@ (update :UseConstraints #(set/rename-keys % {:LicenseURL :LicenseUrl})) (update :ContactGroups update-contacts-1_3_2->1_3_1) (update :ContactPersons update-contacts-1_3_2->1_3_1))) + +(defmethod interface/migrate-umm-version [:service "1.3.2" "1.3.3"] + [context s & _] + ;; There is nothing to migrate up. New supported format enumerations were added in 1.3.3. + s) + +(defmethod interface/migrate-umm-version [:service "1.3.3" "1.3.2"] + [context s & _] + (-> s + (update-in [:ServiceOptions :SupportedInputFormats] service-options/remove-non-valid-formats-1_3_3-to-1_3_2) + (update-in [:ServiceOptions :SupportedOutputFormats] service-options/remove-non-valid-formats-1_3_3-to-1_3_2) + (update-in [:ServiceOptions :SupportedReformattings] service-options/remove-reformattings-non-valid-formats))) diff --git a/umm-spec-lib/src/cmr/umm_spec/versioning.clj b/umm-spec-lib/src/cmr/umm_spec/versioning.clj index c3c136db8c..d24ab892e9 100644 --- a/umm-spec-lib/src/cmr/umm_spec/versioning.clj +++ b/umm-spec-lib/src/cmr/umm_spec/versioning.clj @@ -13,7 +13,7 @@ "1.13" "1.14" "1.15" "1.15.1" "1.15.2" "1.15.3"] :granule ["1.4" "1.5" "1.6" "1.6.1"] :variable ["1.0" "1.1" "1.2" "1.3" "1.4" "1.5" "1.6"] - :service ["1.0" "1.1" "1.2" "1.3" "1.3.1" "1.3.2"] + :service ["1.0" "1.1" "1.2" "1.3" "1.3.1" "1.3.2" "1.3.3"] :tool ["1.0"] :subscription ["1.0"]}) diff --git a/umm-spec-lib/test/cmr/umm_spec/test/migration/service_service_options.clj b/umm-spec-lib/test/cmr/umm_spec/test/migration/service_service_options.clj new file mode 100644 index 0000000000..7e10438747 --- /dev/null +++ b/umm-spec-lib/test/cmr/umm_spec/test/migration/service_service_options.clj @@ -0,0 +1,39 @@ +(ns cmr.umm-spec.test.migration.service-service-options + (:require + [clojure.test :refer :all] + [cmr.umm-spec.migration.service-service-options :as service])) + +(deftest update-supported-reformattings-for-1-3-1-test + "Test to see that the migration of the SupportedReformattingsPairType from 1.3 to 1.3.1 works." + + (let [supported-reformattings [{:SupportedInputFormat "HDF5", :SupportedOutputFormat "H1"} + {:SupportedInputFormat "HDF5", :SupportedOutputFormat "H2"} + {:SupportedInputFormat "HDF5", :SupportedOutputFormat "H3"} + {:SupportedInputFormat "HDF6", :SupportedOutputFormat "H1"} + {:SupportedInputFormat "HDF6", :SupportedOutputFormat "H2"} + {:SupportedInputFormat "HDF6", :SupportedOutputFormat "H3"} + {:SupportedInputFormat "HDF5", :SupportedOutputFormat "H4"}]] + + (is (= '({:SupportedInputFormat "HDF5", + :SupportedOutputFormats ["H1" "H2" "H3" "H4"]} + {:SupportedInputFormat "HDF6", + :SupportedOutputFormats ["H1" "H2" "H3"]}) + (service/update-supported-reformattings-for-1-3-1 supported-reformattings))))) + +(deftest update-supported-reformattings-for-1-3-test + "Test to see that the migration of the SupportedReformattingsPairType from 1.3.1 to 1.3 works." + + (let [supported-reformattings [{:SupportedInputFormat "HDF5" + :SupportedOutputFormats ["H1" "H2" "H3"]} + {:SupportedInputFormat "HDF6" + :SupportedOutputFormats ["H1" "H2" "H3"]} + {:SupportedInputFormat "HDF5" + :SupportedOutputFormats ["H4"]}]] + (is (= '({:SupportedInputFormat "HDF5" :SupportedOutputFormat "H1"} + {:SupportedInputFormat "HDF5" :SupportedOutputFormat "H2"} + {:SupportedInputFormat "HDF5" :SupportedOutputFormat "H3"} + {:SupportedInputFormat "HDF6" :SupportedOutputFormat "H1"} + {:SupportedInputFormat "HDF6" :SupportedOutputFormat "H2"} + {:SupportedInputFormat "HDF6" :SupportedOutputFormat "H3"} + {:SupportedInputFormat "HDF5" :SupportedOutputFormat "H4"}) + (service/update-supported-reformattings-for-1-3 supported-reformattings))))) diff --git a/umm-spec-lib/test/cmr/umm_spec/test/migration/version/service.clj b/umm-spec-lib/test/cmr/umm_spec/test/migration/version/service.clj index 8dd9514046..a429574c9d 100644 --- a/umm-spec-lib/test/cmr/umm_spec/test/migration/version/service.clj +++ b/umm-spec-lib/test/cmr/umm_spec/test/migration/version/service.clj @@ -529,23 +529,6 @@ (vm/migrate-umm {} :service "1.3" "1.2" s1-3))))) -(deftest update-supported-reformattings-for-1-3-1-test - "Test to see that the migration of the SupportedReformattingsPairType from 1.3 to 1.3.1 works." - - (let [supported-reformattings [{:SupportedInputFormat "HDF5", :SupportedOutputFormat "H1"} - {:SupportedInputFormat "HDF5", :SupportedOutputFormat "H2"} - {:SupportedInputFormat "HDF5", :SupportedOutputFormat "H3"} - {:SupportedInputFormat "HDF6", :SupportedOutputFormat "H1"} - {:SupportedInputFormat "HDF6", :SupportedOutputFormat "H2"} - {:SupportedInputFormat "HDF6", :SupportedOutputFormat "H3"} - {:SupportedInputFormat "HDF5", :SupportedOutputFormat "H4"}]] - - (is (= '({:SupportedInputFormat "HDF5", - :SupportedOutputFormats ["H1" "H2" "H3" "H4"]} - {:SupportedInputFormat "HDF6", - :SupportedOutputFormats ["H1" "H2" "H3"]}) - (service/update-supported-reformattings-for-1-3-1 supported-reformattings))))) - (deftest migrate-main-fields-1-3->1-3-1 "Test the full migration of UMM-S from version 1.3 to version 1.3.1 using predefined example files." (let [s1-3 (decode @@ -558,24 +541,6 @@ (vm/migrate-umm {} :service "1.3" "1.3.1" s1-3))))) -(deftest update-supported-reformattings-for-1-3-test - "Test to see that the migration of the SupportedReformattingsPairType from 1.3.1 to 1.3 works." - - (let [supported-reformattings [{:SupportedInputFormat "HDF5" - :SupportedOutputFormats ["H1" "H2" "H3"]} - {:SupportedInputFormat "HDF6" - :SupportedOutputFormats ["H1" "H2" "H3"]} - {:SupportedInputFormat "HDF5" - :SupportedOutputFormats ["H4"]}]] - (is (= '({:SupportedInputFormat "HDF5" :SupportedOutputFormat "H1"} - {:SupportedInputFormat "HDF5" :SupportedOutputFormat "H2"} - {:SupportedInputFormat "HDF5" :SupportedOutputFormat "H3"} - {:SupportedInputFormat "HDF6" :SupportedOutputFormat "H1"} - {:SupportedInputFormat "HDF6" :SupportedOutputFormat "H2"} - {:SupportedInputFormat "HDF6" :SupportedOutputFormat "H3"} - {:SupportedInputFormat "HDF5" :SupportedOutputFormat "H4"}) - (service/update-supported-reformattings-for-1-3 supported-reformattings))))) - (deftest migrate-main-fields-1-3-1->1-3 "Test the full migration of UMM-S from version 1.3.1 to version 1.3 using predefined example files." (let [s1-3 (decode @@ -611,6 +576,18 @@ (is (= s1-3-1 (vm/migrate-umm {} :service "1.3.2" "1.3.1" s1-3-2))))) + +(deftest migrate-main-fields-1-3-3->1-3-2 + "Test the full migration of UMM-S from version 1.3.3 to version 1.3.2 using predefined example files." + (let [s1-3-2 (decode + (slurp (io/file (io/resource "example-data/umm-json/service/v1.3.2/Service_v1.3.2-from-v1.3.3.json"))) + true) + s1-3-3 (decode + (slurp (io/file (io/resource "example-data/umm-json/service/v1.3.3/Service_v1.3.3-to-v1.3.2.json"))) + true)] + (is (= s1-3-2 + (vm/migrate-umm + {} :service "1.3.3" "1.3.2" s1-3-3))))) (comment (core/validate-metadata