Repository: CS-SI/eodag
Pull request #1737 (2025-07-16 18:12:11)

fix(plugins): metadata_mapping_from_product in search config
Fixed `metadata_mapping_from_product` mechanism, and use it in `wekeo_main`

eodag-bot: ![badge](https://raw.githubusercontent.com/CS-SI/eodag/_xml_coverage_reports_win/data/fixed-metadata_mapping_from_product/./badge.svg)


## Code Coverage (Windows)

<details>


```
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                      8       0  100.00%
cli.py                                         320      64  80.00%   62-63, 87, 687-750, 852-903, 907
config.py                                      452      31  93.14%   81-83, 92, 100, 104-106, 177, 188, 205-206, 728-730, 854-857, 901-902, 911-912, 946, 1026, 1055, 1085-1090, 1092
crunch.py                                        5       5  0.00%    20-24
api/__init__.py                                  0       0  100.00%
api/core.py                                    816      79  90.32%   380-381, 431, 700, 731, 775-778, 816, 860, 894, 939-944, 970, 1061, 1129, 1352-1364, 1404, 1406, 1436, 1440-1451, 1464-1470, 1555-1558, 1595-1615, 1684-1689, 1701-1704, 1722-1734, 2029-2035, 2286, 2290-2294, 2303-2305, 2349-2350, 2379-2380
api/search_result.py                           126      11  91.27%   87, 96, 103, 117, 282, 287-288, 336, 359-360, 366
api/product/__init__.py                         18       1  94.44%   62
api/product/_assets.py                          52       5  90.38%   97, 183, 191, 194-198
api/product/_product.py                        213      19  91.08%   72-74, 238-239, 345, 372, 473, 491, 515-518, 527-530, 585-588
api/product/metadata_mapping.py                708      63  91.10%   122-124, 222, 254-255, 312-324, 326, 337, 362, 402-403, 440, 461-464, 487, 495-496, 589-590, 614-615, 621-624, 639-640, 789, 840, 993, 1002-1006, 1023-1028, 1155, 1169-1189, 1209, 1214, 1366, 1380, 1405, 1451, 1512, 1535-1536, 1556-1560, 1576, 1584
api/product/drivers/__init__.py                 20       2  90.00%   33-36
api/product/drivers/base.py                     29       1  96.55%   98
api/product/drivers/generic.py                   7       0  100.00%
api/product/drivers/sentinel1.py                15       0  100.00%
api/product/drivers/sentinel2.py                15       0  100.00%
plugins/__init__.py                              0       0  100.00%
plugins/base.py                                 21       3  85.71%   48, 55, 68
plugins/manager.py                             173      19  89.02%   105-110, 145-150, 154, 192, 214, 218, 242, 281-282, 382-385, 397-398
plugins/apis/__init__.py                         0       0  100.00%
plugins/apis/base.py                             4       0  100.00%
plugins/apis/ecmwf.py                           97      10  89.69%   165-167, 214-215, 241-243, 296-297
plugins/apis/usgs.py                           180      26  85.56%   156, 258, 292, 327-329, 334, 360-361, 366, 396-403, 414-419, 441-447, 478
plugins/authentication/__init__.py               6       1  83.33%   31
plugins/authentication/aws_auth.py              20       0  100.00%
plugins/authentication/base.py                  17       2  88.24%   45, 58
plugins/authentication/generic.py               16       3  81.25%   50, 55, 65
plugins/authentication/header.py                19       0  100.00%
plugins/authentication/keycloak.py              46       7  84.78%   153-156, 177-182
plugins/authentication/oauth.py                 13       7  46.15%   43-45, 49-52
plugins/authentication/openid_connect.py       231      28  87.88%   92-93, 105-123, 170, 176-204, 212, 351-354, 380, 421
plugins/authentication/qsauth.py                34       1  97.06%   91
plugins/authentication/sas_auth.py              47       1  97.87%   76
plugins/authentication/token.py                128       9  92.97%   180, 217, 289-290, 340-344
plugins/authentication/token_exchange.py        36      14  61.11%   75, 93-121
plugins/crunch/__init__.py                       0       0  100.00%
plugins/crunch/base.py                          10       1  90.00%   43
plugins/crunch/filter_date.py                   59      14  76.27%   52-57, 69, 78, 87, 90, 100-102, 109-111, 118
plugins/crunch/filter_latest_intersect.py       47      33  29.79%   49-54, 67-112
plugins/crunch/filter_latest_tpl_name.py        31       1  96.77%   83
plugins/crunch/filter_overlap.py                66      18  72.73%   28-30, 66-69, 76-79, 85, 93, 104-120
plugins/crunch/filter_property.py               30       5  83.33%   55-60, 63-64
plugins/download/__init__.py                     0       0  100.00%
plugins/download/aws.py                        528     158  70.08%   272, 285, 365-368, 382-386, 476-478, 482, 515-516, 522-526, 556, 589, 593, 600, 630-638, 642, 677-685, 696-698, 729-810, 828-886, 897-902, 955, 970-972, 975, 985-993, 1001-1015, 1025-1048, 1055-1068, 1106, 1132, 1177-1179, 1399
plugins/download/base.py                       260      37  85.77%   129, 157, 224-226, 304-305, 363-364, 406, 410-421, 435, 503-507, 537-538, 563-571, 573-577, 627, 648, 670, 678
plugins/download/creodias_s3.py                 25       9  64.00%   55-69
plugins/download/http.py                       542      93  82.84%   228, 270-273, 334-337, 340, 347-352, 383-385, 402, 417, 471, 506, 520, 534, 542-546, 562-567, 578, 596, 632-635, 656, 666, 673, 693, 770, 789-800, 808-813, 823-840, 858, 888-897, 933, 958-959, 978-983, 992, 1007-1009, 1013, 1016, 1031-1032, 1067, 1129, 1144, 1203-1204, 1210, 1220, 1256, 1292, 1312, 1347-1349
plugins/download/s3rest.py                     120      26  78.33%   119, 153, 160, 195, 222-229, 232-234, 238, 249-255, 263-264, 267-271, 286-289, 298, 319-322
plugins/search/__init__.py                      22       0  100.00%
plugins/search/base.py                         170      14  91.76%   103, 107, 131-137, 274, 295, 434, 456-459, 468
plugins/search/build_search_result.py          479      63  86.85%   245-246, 282, 285, 310, 313, 344-346, 554-565, 692, 694, 755, 762, 786, 823, 874, 890, 924-939, 987, 1012, 1015, 1019, 1140-1141, 1150-1159, 1222, 1237, 1243, 1262-1271, 1388-1389, 1434, 1443-1445, 1505, 1551
plugins/search/cop_marine.py                   254      47  81.50%   56, 64-66, 76-77, 82, 87-88, 104, 106, 109, 175-176, 232, 238, 242, 246, 259, 270-271, 279, 312, 316, 337, 341, 345, 349, 353-357, 363-366, 369-383, 400, 449-453, 458, 470
plugins/search/creodias_s3.py                   25       1  96.00%   51
plugins/search/csw.py                          105      81  22.86%   98-99, 103-104, 112-160, 166-179, 187-219, 237-278
plugins/search/data_request_search.py          207      72  65.22%   190-193, 209, 220, 224-225, 236, 241, 246, 253, 266-269, 323-324, 328, 338-344, 349, 367-371, 387-390, 398-409, 426, 428, 435-438, 440-441, 459-463, 496, 506, 517, 530, 536-551, 556
plugins/search/qssearch.py                     717     102  85.77%   416-417, 461, 519, 533, 537-543, 558-559, 571-575, 688-700, 745-748, 819-820, 871, 890, 897, 909, 966, 987, 990-991, 1000-1001, 1010-1011, 1020-1021, 1048, 1134-1139, 1143-1152, 1186, 1209, 1282-1283, 1289, 1379, 1476-1480, 1540, 1543, 1549-1550, 1571, 1599-1611, 1618, 1650-1652, 1662-1668, 1698, 1721, 1726-1727, 1742, 1758, 1833, 1845, 1852, 1863, 1886-1891, 1900, 1908-1918, 1936, 1952-1956
plugins/search/stac_list_assets.py              25      10  60.00%   44-51, 75-85
plugins/search/static_stac_search.py            79      13  83.54%   100-126, 170, 183
rest/__init__.py                                 4       2  50.00%   21-22
rest/cache.py                                   33      22  33.33%   35-37, 44-70
rest/config.py                                  25       1  96.00%   35
rest/constants.py                                6       0  100.00%
rest/core.py                                   260     153  41.15%   157, 159, 161, 164-165, 179-189, 198-199, 205, 208, 249-303, 316-352, 384-422, 437-453, 469-478, 485-524, 541, 583-668, 707, 714-767
rest/errors.py                                  72      51  29.17%   63, 68-111, 116-119, 126-129, 137-167, 175-180, 195-201
rest/server.py                                 194     194  0.00%    18-596
rest/stac.py                                   333      77  76.88%   246, 312, 334, 386-389, 416-443, 474-476, 499, 531-532, 614-654, 676-692, 719, 784-788, 795, 850-851, 857, 861-866, 876-880, 929, 967, 1000, 1019-1021
rest/types/__init__.py                           0       0  100.00%
rest/types/collections_search.py                13      13  0.00%    18-44
rest/types/eodag_search.py                     180      20  88.89%   225-229, 262-264, 282, 285, 291, 295, 353, 371-386
rest/types/queryables.py                        64      20  68.75%   54-55, 60-63, 68-79, 105-110, 119-120, 174
rest/types/stac_search.py                      125      11  91.20%   126-128, 174, 189-191, 199, 203, 251, 254
rest/utils/__init__.py                          94      30  68.09%   72-78, 98, 101-102, 121-123, 136, 143, 168-176, 183-204
rest/utils/cql_evaluate.py                      48       5  89.58%   69, 76, 90, 97, 105
rest/utils/rfc3339.py                           23       5  78.26%   43-44, 48, 60, 62
types/__init__.py                              161      41  74.53%   67, 80-84, 95-107, 135-137, 144-149, 214, 252, 262-278, 283, 285, 307, 312, 320, 330
types/bbox.py                                   43      19  55.81%   46-61, 72-74, 85-87, 99-101, 113-115, 123
types/download_args.py                           9       0  100.00%
types/queryables.py                            111       0  100.00%
types/search_args.py                            70      18  74.29%   60-64, 71-88, 103
types/whoosh.py                                 81      16  80.25%   129-132, 136-143, 155-161, 174-176
utils/__init__.py                              551      40  92.74%   81, 208-209, 218-245, 248, 263, 343-347, 420-424, 443-445, 459, 551, 566, 606-607, 636, 1011-1014, 1022-1023, 1061-1062, 1109-1110, 1250
utils/cache.py                                  22       0  100.00%
utils/env.py                                     3       0  100.00%
utils/exceptions.py                             46       0  100.00%
utils/import_system.py                          28      19  32.14%   64-78, 89-99
utils/logging.py                                28       1  96.43%   41
utils/notebook.py                               44      23  47.73%   25-29, 36-41, 58-62, 72-78, 83-87
utils/repr.py                                   38       8  78.95%   51, 53, 57, 98, 122-129
utils/requests.py                               55      29  47.27%   51-52, 64, 85-96, 107-124, 128
utils/rest.py                                   36       1  97.22%   55
utils/s3.py                                     69       3  95.65%   162-163, 226
utils/stac_reader.py                           113      44  61.06%   63-85, 95-97, 101, 138, 154-159, 206-216, 226-256
TOTAL                                        10675    2076  80.55%
```

</details>


### Diff against develop

```
Filename                      Stmts    Miss  Cover
--------------------------  -------  ------  -------
config.py                        +1       0  +0.01%
plugins/search/base.py           -1       0  -0.05%
plugins/search/qssearch.py       +5      +2  -0.19%
TOTAL                            +5      +2  -0.01%
```


Results for commit: d9309d37805100a81883fff0b7a5414f6b47f16c


_Minimum allowed coverage is `70%`_


:recycle: This comment has been updated with latest results


<!-- Sticky Pull Request Commentartifacts/unit-test-results-python3.13-windows-latest/coverage.xml -->

Patch:
diff --git a/eodag/config.py b/eodag/config.py
index bd49e45e..257af6cb 100644
--- a/eodag/config.py
+++ b/eodag/config.py
@@ -452,6 +452,9 @@ class PluginConfig(yaml.YAMLObject):
     discover_queryables: PluginConfig.DiscoverQueryables
     #: :class:`~eodag.plugins.search.base.Search` The mapping between eodag metadata and the plugin specific metadata
     metadata_mapping: dict[str, Union[str, list[str]]]
+    #: :class:`~eodag.plugins.search.base.Search` :attr:`~eodag.config.PluginConfig.metadata_mapping` got from the given
+    #: product type
+    metadata_mapping_from_product: str
     #: :class:`~eodag.plugins.search.base.Search` A mapping for the metadata of individual assets
     assets_mapping: dict[str, dict[str, Any]]
     #: :class:`~eodag.plugins.search.base.Search` Parameters to remove from queryables
diff --git a/eodag/plugins/search/base.py b/eodag/plugins/search/base.py
index 5fd2c69b..5ca3aa63 100644
--- a/eodag/plugins/search/base.py
+++ b/eodag/plugins/search/base.py
@@ -160,10 +160,6 @@ class Search(PluginTopic):
         :returns: The product type definition parameters
         """
         if product_type in self.config.products.keys():
-            logger.debug(
-                "Getting provider product type definition parameters for %s",
-                product_type,
-            )
             return self.config.products[product_type]
         elif GENERIC_PRODUCT_TYPE in self.config.products.keys():
             logger.debug(
diff --git a/eodag/plugins/search/qssearch.py b/eodag/plugins/search/qssearch.py
index 0d9ddc9b..c8af3928 100644
--- a/eodag/plugins/search/qssearch.py
+++ b/eodag/plugins/search/qssearch.py
@@ -386,36 +386,48 @@ class QueryStringSearch(Search):
 
         # parse jsonpath on init: product type specific metadata-mapping
         for product_type in self.config.products.keys():
-            if "metadata_mapping" in self.config.products[product_type].keys():
-                self.config.products[product_type][
-                    "metadata_mapping"
-                ] = mtd_cfg_as_conversion_and_querypath(
-                    self.config.products[product_type]["metadata_mapping"]
-                )
+
+            product_type_metadata_mapping = {}
+            # product-type specific metadata-mapping
+            if any(
+                mm in self.config.products[product_type].keys()
+                for mm in ("metadata_mapping", "metadata_mapping_from_product")
+            ):
                 # Complete and ready to use product type specific metadata-mapping
                 product_type_metadata_mapping = deepcopy(self.config.metadata_mapping)
 
-                # update config using provider product type definition metadata_mapping
-                # from another product
-                other_product_for_mapping = cast(
-                    str,
-                    self.config.products[product_type].get(
-                        "metadata_mapping_from_product", ""
-                    ),
+            # metadata_mapping from another product
+            if other_product_for_mapping := self.config.products[product_type].get(
+                "metadata_mapping_from_product"
+            ):
+                other_product_type_def_params = self.get_product_type_def_params(
+                    other_product_for_mapping,
                 )
-                if other_product_for_mapping:
-                    other_product_type_def_params = self.get_product_type_def_params(
-                        other_product_for_mapping,
-                    )
+                # parse mapping to apply
+                if other_product_type_mtd_mapping := other_product_type_def_params.get(
+                    "metadata_mapping", {}
+                ):
                     other_product_type_mtd_mapping = (
                         mtd_cfg_as_conversion_and_querypath(
                             other_product_type_def_params.get("metadata_mapping", {})
                         )
                     )
-                    # updated mapping at the end
-                    for metadata, mapping in other_product_type_mtd_mapping.items():
-                        product_type_metadata_mapping.pop(metadata, None)
-                        product_type_metadata_mapping[metadata] = mapping
+                else:
+                    msg = f"Cannot reuse empty metadata_mapping from {other_product_for_mapping} for {product_type}"
+                    raise MisconfiguredError(msg)
+                # update mapping
+                for metadata, mapping in other_product_type_mtd_mapping.items():
+                    product_type_metadata_mapping.pop(metadata, None)
+                    product_type_metadata_mapping[metadata] = mapping
+
+            # metadata_mapping from current product
+            if "metadata_mapping" in self.config.products[product_type].keys():
+                # parse mapping to apply
+                self.config.products[product_type][
+                    "metadata_mapping"
+                ] = mtd_cfg_as_conversion_and_querypath(
+                    self.config.products[product_type]["metadata_mapping"]
+                )
 
                 # from current product, updated mapping at the end
                 for metadata, mapping in self.config.products[product_type][
@@ -424,6 +436,7 @@ class QueryStringSearch(Search):
                     product_type_metadata_mapping.pop(metadata, None)
                     product_type_metadata_mapping[metadata] = mapping
 
+            if product_type_metadata_mapping:
                 self.config.products[product_type][
                     "metadata_mapping"
                 ] = product_type_metadata_mapping
diff --git a/eodag/resources/providers.yml b/eodag/resources/providers.yml
index 38efa3af..1611cc17 100644
--- a/eodag/resources/providers.yml
+++ b/eodag/resources/providers.yml
@@ -1574,7 +1574,7 @@
         <<: *month_year
     CAMS_GLOBAL_EMISSIONS:
       dataset: cams-global-emission-inventories
-      version: latest
+      version: v6.2
       data_format: zip
       variable: acids
       source: anthropogenic
@@ -2941,21 +2941,15 @@
     S1_SAR_RAW:
       productType: EO:ESA:DAT:SENTINEL-1
       providerProductType: RAW
-      metadata_mapping:
-        <<: *s1_sar_params
-        orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:ESA:DAT:SENTINEL-1"}}'
+      metadata_mapping_from_product: S1_SAR_GRD
     S1_SAR_OCN:
       productType: EO:ESA:DAT:SENTINEL-1
       providerProductType: OCN
-      metadata_mapping:
-        <<: *s1_sar_params
-        orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:ESA:DAT:SENTINEL-1"}}'
+      metadata_mapping_from_product: S1_SAR_GRD
     S1_SAR_SLC:
       productType: EO:ESA:DAT:SENTINEL-1
       providerProductType: SLC
-      metadata_mapping:
-        <<: *s1_sar_params
-        orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:ESA:DAT:SENTINEL-1"}}'
+      metadata_mapping_from_product: S1_SAR_GRD
     S2_MSI_L1C:
       productType: EO:ESA:DAT:SENTINEL-2
       providerProductType: S2MSI1C
@@ -2972,14 +2966,7 @@
       productType: EO:ESA:DAT:SENTINEL-2
       providerProductType: S2MSI2A
       processingLevel: S2MSI2A
-      metadata_mapping:
-        processingLevel:
-          - '{{"processingLevel": "{processingLevel}"}}'
-          - '$.id.`sub(/^[^_]([^_]+)_([^_]+)_.*/, S2\\2)`'
-        cloudCover:
-          - '{{"cloudCover": "{cloudCover}"}}'
-          - '$.null'
-        orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:ESA:DAT:SENTINEL-2"}}'
+      metadata_mapping_from_product: S2_MSI_L1C
     S3_LAN_HY:
       productType: EO:ESA:DAT:SENTINEL-3
       providerProductType: SR_2_LAN_HY
@@ -2993,47 +2980,27 @@
       productType: EO:ESA:DAT:SENTINEL-3
       providerProductType: SR_2_LAN_SI
       processingLevel: 2
-      metadata_mapping:
-        processingLevel:
-          - '{{"processingLevel": "{processingLevel}"}}'
-          - '2'
-        orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:ESA:DAT:SENTINEL-3"}}'
+      metadata_mapping_from_product: S3_LAN_HY
     S3_LAN_LI:
       productType: EO:ESA:DAT:SENTINEL-3
       providerProductType: SR_2_LAN_LI
       processingLevel: 2
-      metadata_mapping:
-        processingLevel:
-          - '{{"processingLevel": "{processingLevel}"}}'
-          - '2'
-        orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:ESA:DAT:SENTINEL-3"}}'
+      metadata_mapping_from_product: S3_LAN_HY
     S3_OLCI_L2LFR:
       productType: EO:ESA:DAT:SENTINEL-3
       providerProductType: OL_2_LFR___
       processingLevel: 2
-      metadata_mapping:
-        processingLevel:
-          - '{{"processingLevel": "{processingLevel}"}}'
-          - '2'
-        orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:ESA:DAT:SENTINEL-3"}}'
+      metadata_mapping_from_product: S3_LAN_HY
     S3_OLCI_L2LRR:
       productType: EO:ESA:DAT:SENTINEL-3
       providerProductType: OL_2_LRR___
       processingLevel: 2
-      metadata_mapping:
-        processingLevel:
-          - '{{"processingLevel": "{processingLevel}"}}'
-          - '2'
-        orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:ESA:DAT:SENTINEL-3"}}'
+      metadata_mapping_from_product: S3_LAN_HY
     S3_SLSTR_L2:
       productType: EO:ESA:DAT:SENTINEL-3
       providerProductType: SL_2_LST___
       processingLevel: 2
-      metadata_mapping:
-        processingLevel:
-          - '{{"processingLevel": "{processingLevel}"}}'
-          - '2'
-        orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:ESA:DAT:SENTINEL-3"}}'
+      metadata_mapping_from_product: S3_LAN_HY
     S3_EFR:
       productType: EO:EUM:DAT:SENTINEL-3:OL_1_EFR___
       metadata_mapping:
@@ -3048,75 +3015,33 @@
         orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:EUM:DAT:SENTINEL-3:OL_1_EFR___"}}'
     S3_ERR:
       productType: EO:EUM:DAT:SENTINEL-3:OL_1_ERR___
+      metadata_mapping_from_product: S3_EFR
       metadata_mapping:
-        id:
-          - '{{"timeliness": {id#split_id_into_s3_params}["timeliness"], "sat": {id#split_id_into_s3_params}["sat"], "startdate": {id#split_id_into_s3_params}["startDate"], "enddate": {id#split_id_into_s3_params}["endDate"]}}'
-          - '{$.id#remove_extension}'
-        platform:
-          - '{{"sat": "{platform}"}}'
-          - '$.id.`sub(/^[^_]([^_]+)_.*/, Sentinel-\\1)`'
-        platformSerialIdentifier: '$.id.`sub(/^[^_]([^_]+)_.*/, S\\1)`'
-        <<: *orbit_cycle
         orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:EUM:DAT:SENTINEL-3:OL_1_ERR___"}}'
     S3_OLCI_L2WFR:
       productType: EO:EUM:DAT:SENTINEL-3:OL_2_WFR___
+      metadata_mapping_from_product: S3_EFR
       metadata_mapping:
-        id:
-          - '{{"timeliness": {id#split_id_into_s3_params}["timeliness"], "sat": {id#split_id_into_s3_params}["sat"], "startdate": {id#split_id_into_s3_params}["startDate"], "enddate": {id#split_id_into_s3_params}["endDate"]}}'
-          - '{$.id#remove_extension}'
-        platform:
-          - '{{"sat": "{platform}"}}'
-          - '$.id.`sub(/^[^_]([^_]+)_.*/, Sentinel-\\1)`'
-        platformSerialIdentifier: '$.id.`sub(/^[^_]([^_]+)_.*/, S\\1)`'
-        <<: *orbit_cycle
         orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:EUM:DAT:SENTINEL-3:OL_2_WFR___"}}'
     S3_OLCI_L2WRR:
       productType: EO:EUM:DAT:SENTINEL-3:OL_2_WRR___
+      metadata_mapping_from_product: S3_EFR
       metadata_mapping:
-        id:
-          - '{{"timeliness": {id#split_id_into_s3_params}["timeliness"], "sat": {id#split_id_into_s3_params}["sat"], "startdate": {id#split_id_into_s3_params}["startDate"], "enddate": {id#split_id_into_s3_params}["endDate"]}}'
-          - '{$.id#remove_extension}'
-        platform:
-          - '{{"sat": "{platform}"}}'
-          - '$.id.`sub(/^[^_]([^_]+)_.*/, Sentinel-\\1)`'
-        platformSerialIdentifier: '$.id.`sub(/^[^_]([^_]+)_.*/, S\\1)`'
-        <<: *orbit_cycle
         orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:EUM:DAT:SENTINEL-3:OL_2_WRR___"}}'
     S3_SRA:
       productType: EO:EUM:DAT:SENTINEL-3:SR_1_SRA___
+      metadata_mapping_from_product: S3_EFR
       metadata_mapping:
-        id:
-          - '{{"timeliness": {id#split_id_into_s3_params}["timeliness"], "sat": {id#split_id_into_s3_params}["sat"], "startdate": {id#split_id_into_s3_params}["startDate"], "enddate": {id#split_id_into_s3_params}["endDate"]}}'
-          - '{$.id#remove_extension}'
-        platform:
-          - '{{"sat": "{platform}"}}'
-          - '$.id.`sub(/^[^_]([^_]+)_.*/, Sentinel-\\1)`'
-        platformSerialIdentifier: '$.id.`sub(/^[^_]([^_]+)_.*/, S\\1)`'
-        <<: *orbit_cycle
         orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:EUM:DAT:SENTINEL-3:SR_1_SRA___"}}'
     S3_SRA_A:
       productType: EO:EUM:DAT:SENTINEL-3:SR_1_SRA_A_
+      metadata_mapping_from_product: S3_EFR
       metadata_mapping:
-        id:
-          - '{{"timeliness": {id#split_id_into_s3_params}["timeliness"], "sat": {id#split_id_into_s3_params}["sat"], "startdate": {id#split_id_into_s3_params}["startDate"], "enddate": {id#split_id_into_s3_params}["endDate"]}}'
-          - '{$.id#remove_extension}'
-        platform:
-          - '{{"sat": "{platform}"}}'
-          - '$.id.`sub(/^[^_]([^_]+)_.*/, Sentinel-\\1)`'
-        platformSerialIdentifier: '$.id.`sub(/^[^_]([^_]+)_.*/, S\\1)`'
-        <<: *orbit_cycle
         orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:EUM:DAT:SENTINEL-3:SR_1_SRA_A_"}}'
     S3_SRA_BS:
       productType: EO:EUM:DAT:SENTINEL-3:SR_1_SRA_BS
+      metadata_mapping_from_product: S3_EFR
       metadata_mapping:
-        id:
-          - '{{"timeliness": {id#split_id_into_s3_params}["timeliness"], "sat": {id#split_id_into_s3_params}["sat"], "startdate": {id#split_id_into_s3_params}["startDate"], "enddate": {id#split_id_into_s3_params}["endDate"]}}'
-          - '{$.id#remove_extension}'
-        platform:
-          - '{{"sat": "{platform}"}}'
-          - '$.id.`sub(/^[^_]([^_]+)_.*/, Sentinel-\\1)`'
-        platformSerialIdentifier: '$.id.`sub(/^[^_]([^_]+)_.*/, S\\1)`'
-        <<: *orbit_cycle
         orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:EUM:DAT:SENTINEL-3:SR_1_SRA_BS"}}'
     S3_SLSTR_L1RBT:
       productType: EO:EUM:DAT:SENTINEL-3:SL_1_RBT___
@@ -3152,14 +3077,7 @@
     S5P_L2_IR_ALL:
       productType: EO:ESA:DAT:SENTINEL-5P
       processingLevel: L2
-      metadata_mapping:
-        processingLevel:
-          - '{{"processingLevel": "{processingLevel}"}}'
-          - '$.id.`sub(/^[^_]([^_]+)_([^_]+)_([^_]+)_.*/, \\3)`'
-        processingMode:
-          - '{{"processingMode": "{processingMode}"}}'
-          - '$.null'
-        orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:ESA:DAT:SENTINEL-5P"}}'
+      metadata_mapping_from_product: S5P_L1B_IR_ALL
     EEA_DAILY_VI:
       productType: EO:EEA:DAT:CLMS_HRVPP_VI
       metadata_mapping:
@@ -3187,18 +3105,15 @@
     COP_DEM_GLO30_DTED:
       productType: EO:ESA:DAT:COP-DEM
       providerProductType: DTE_30
-      metadata_mapping:
-        orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:ESA:DAT:COP-DEM"}}'
+      metadata_mapping_from_product: COP_DEM_GLO30_DGED
     COP_DEM_GLO90_DGED:
       productType: EO:ESA:DAT:COP-DEM
       providerProductType: DGE_90
-      metadata_mapping:
-        orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:ESA:DAT:COP-DEM"}}'
+      metadata_mapping_from_product: COP_DEM_GLO30_DGED
     COP_DEM_GLO90_DTED:
       productType: EO:ESA:DAT:COP-DEM
       providerProductType: DTE_90
-      metadata_mapping:
-        orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:ESA:DAT:COP-DEM"}}'
+      metadata_mapping_from_product: COP_DEM_GLO30_DGED
     CLMS_GLO_NDVI_333M:
       productType: EO:CLMS:DAT:CLMS_GLOBAL_NDVI_300M_V1_10DAILY_NETCDF
       providerProductType: NDVI300
@@ -3238,38 +3153,26 @@
     CLMS_GLO_DMP_333M:
       productType: EO:CLMS:DAT:CLMS_GLOBAL_DMP_300M_V1_10DAILY_NETCDF
       providerProductType: DMP300
+      metadata_mapping_from_product: CLMS_GLO_FCOVER_333M
       metadata_mapping:
-        <<: *id_from_date
-        productGroupId:
-          - '{{"productGroupId": "{productGroupId}"}}'
-          - '$.null'
         orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:CLMS:DAT:CLMS_GLOBAL_DMP_300M_V1_10DAILY_NETCDF"}}'
     CLMS_GLO_GDMP_333M:
       productType: EO:CLMS:DAT:CLMS_GLOBAL_GDMP_300M_V1_10DAILY_NETCDF
       providerProductType: GDMP300
+      metadata_mapping_from_product: CLMS_GLO_FCOVER_333M
       metadata_mapping:
-        <<: *id_from_date
-        productGroupId:
-          - '{{"productGroupId": "{productGroupId}"}}'
-          - '$.null'
         orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:CLMS:DAT:CLMS_GLOBAL_GDMP_300M_V1_10DAILY_NETCDF"}}'
     CLMS_GLO_FAPAR_333M:
       productType: EO:CLMS:DAT:CLMS_GLOBAL_FAPAR_300M_V1_10DAILY_NETCDF
       providerProductType: FAPAR300
+      metadata_mapping_from_product: CLMS_GLO_FCOVER_333M
       metadata_mapping:
-        <<: *id_from_date
-        productGroupId:
-          - '{{"productGroupId": "{productGroupId}"}}'
-          - '$.null'
         orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:CLMS:DAT:CLMS_GLOBAL_FAPAR_300M_V1_10DAILY_NETCDF"}}'
     CLMS_GLO_LAI_333M:
       productType: EO:CLMS:DAT:CLMS_GLOBAL_LAI_300M_V1_10DAILY_NETCDF
       providerProductType: LAI300
+      metadata_mapping_from_product: CLMS_GLO_FCOVER_333M
       metadata_mapping:
-        <<: *id_from_date
-        productGroupId:
-          - '{{"productGroupId": "{productGroupId}"}}'
-          - '$.null'
         orderLink: 'https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/download?{{"location": "{downloadLink}","product_id":"{id}", "dataset_id": "EO:CLMS:DAT:CLMS_GLOBAL_LAI_300M_V1_10DAILY_NETCDF"}}'
   auth: !plugin
     type: TokenAuth
@@ -3601,16 +3504,7 @@
       pressure_level: 1
       data_format: grib
       download_format: unarchived
-      metadata_mapping:
-        startTimeFromAscendingNode:
-          - |
-            {{
-              "year": {startTimeFromAscendingNode#to_datetime_dict(list)}["year"],
-              "month": {startTimeFromAscendingNode#to_datetime_dict(list)}["month"],
-              "time": {startTimeFromAscendingNode#get_ecmwf_time}
-            }}
-          - $.properties.startdate
-        completionTimeFromAscendingNode: $.properties.enddate
+      metadata_mapping_from_product: ERA5_SL_MONTHLY
     ERA5_LAND:
       dataset: EO:ECMWF:DAT:REANALYSIS_ERA5_LAND
       variable: 2m_dewpoint_temperature
@@ -3624,16 +3518,7 @@
       variable: 2m_dewpoint_temperature
       data_format: grib
       download_format: unarchived
-      metadata_mapping:
-        startTimeFromAscendingNode:
-          - |
-            {{
-              "year": {startTimeFromAscendingNode#to_datetime_dict(list)}["year"],
-              "month": {startTimeFromAscendingNode#to_datetime_dict(list)}["month"],
-              "time": {startTimeFromAscendingNode#get_ecmwf_time}
-            }}
-          - $.properties.startdate
-        completionTimeFromAscendingNode: $.properties.enddate
+      metadata_mapping_from_product: ERA5_SL_MONTHLY
     CAMS_EAC4:
       dataset: EO:ECMWF:DAT:CAMS_GLOBAL_REANALYSIS_EAC4
       data_format: grib
@@ -3641,7 +3526,7 @@
       time: 00:00
     CAMS_GLOBAL_EMISSIONS:
       dataset: EO:ECMWF:DAT:CAMS_GLOBAL_EMISSION_INVENTORIES
-      version: latest
+      version: v6.2
       data_format: zip
       variable: acids
       source: anthropogenic


Test patch:
diff --git a/tests/units/test_search_plugins.py b/tests/units/test_search_plugins.py
index 284383f5..823b7f3c 100644
--- a/tests/units/test_search_plugins.py
+++ b/tests/units/test_search_plugins.py
@@ -3635,6 +3635,59 @@ class TestSearchPluginPostJsonSearchWithStacQueryables(BaseSearchPluginTest):
         )
         self.wekeomain_auth_plugin = self.get_auth_plugin(self.wekeomain_search_plugin)
 
+    def test_plugins_search_postjsonsearchwithstacqueryables_init_wekeomain(self):
+        """Check that the PostJsonSearchWithStacQueryables plugin is initialized correctly for wekeo_main provider"""
+
+        default_providers_config = load_default_config()
+        default_config = default_providers_config["wekeo_main"]
+        # "orderLink" in S1_SAR_GRD but not in provider conf or S1_SAR_SLC conf
+        self.assertNotIn("orderLink", default_config.search.metadata_mapping)
+        self.assertIn(
+            "orderLink", default_config.products["S1_SAR_GRD"]["metadata_mapping"]
+        )
+        self.assertNotIn("metadata_mapping", default_config.products["S1_SAR_SLC"])
+
+        # metadata_mapping_from_product: from S1_SAR_GRD to S1_SAR_SLC
+        self.assertEqual(
+            default_config.products["S1_SAR_SLC"]["metadata_mapping_from_product"],
+            "S1_SAR_GRD",
+        )
+
+        # check initialized plugin configuration
+        self.assertDictEqual(
+            self.wekeomain_search_plugin.config.products["S1_SAR_GRD"][
+                "metadata_mapping"
+            ],
+            self.wekeomain_search_plugin.config.products["S1_SAR_SLC"][
+                "metadata_mapping"
+            ],
+        )
+
+        # CLMS_GLO_LAI_333M has both metadata_mapping_from_product and metadata_mapping
+        # "metadata_mapping" must override "metadata_mapping_from_product"
+        self.assertIn(
+            "orderLink",
+            default_config.products["CLMS_GLO_LAI_333M"]["metadata_mapping"],
+        )
+        self.assertIn(
+            "orderLink",
+            default_config.products["CLMS_GLO_FCOVER_333M"]["metadata_mapping"],
+        )
+        self.assertEqual(
+            default_config.products["CLMS_GLO_LAI_333M"][
+                "metadata_mapping_from_product"
+            ],
+            "CLMS_GLO_FCOVER_333M",
+        )
+        self.assertNotEqual(
+            self.wekeomain_search_plugin.config.products["CLMS_GLO_LAI_333M"][
+                "metadata_mapping"
+            ]["orderLink"],
+            self.wekeomain_search_plugin.config.products["CLMS_GLO_FCOVER_333M"][
+                "metadata_mapping"
+            ]["orderLink"],
+        )
+
     @mock.patch(
         "eodag.plugins.search.qssearch.QueryStringSearch.normalize_results",
         autospec=True,