Skip to content

Commit d0e07b0

Browse files
committed
CMR-10542: Modifying subscription worker to get the granule record as umm_json to create the granule subscription notification
1 parent bd3f65c commit d0e07b0

2 files changed

Lines changed: 20 additions & 124 deletions

File tree

subscription/src/search.py

Lines changed: 15 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,12 @@ def get_token(self):
155155
self.get_token_from_parameter_store()
156156
return self.token
157157

158-
def get_concept(self, concept_id):
158+
def get_concept(self, concept_id, revision_id):
159159
"""This function calls search using a token, and a CMR concept id to get
160160
a granule by concept id in umm_json format."""
161161

162162
# Set the search concepts URL.
163-
url = f"{self.get_public_search_url()}/concepts/{concept_id}.umm_json"
163+
url = f"{self.get_public_search_url()}/concepts/{concept_id}/{revision_id}.umm_json"
164164

165165
# Set the headers
166166
headers = {
@@ -186,7 +186,7 @@ def get_producer_granule_id(self, metadata):
186186
Get the granule producer id from the metadata and create a string for the
187187
subscription notification message.
188188
"""
189-
identifiers = metadata["DataGranule"]['Identifiers'] #concept.get('DataGranule', {}).get('Identifiers', [])
189+
identifiers = metadata["DataGranule"]['Identifiers']
190190
pgi = None
191191
for identifier in identifiers:
192192
if identifier.get('IdentifierType') == 'ProducerGranuleId':
@@ -197,56 +197,6 @@ def get_producer_granule_id(self, metadata):
197197
else:
198198
return None
199199

200-
def create_notification_message_body(self, result_dict):
201-
"""Create the notification. Returns either a notification message json string or None.
202-
The notification should look like
203-
"{\"concept-id\": \"G1200484356-PROV\", \"granule-ur\": \"SWOT_L2_HR_PIXC_578_020_221L_20230710T223456_20230710T223506_PIA1_01\", \"producer-granule-id\": \"SWOT_L2_HR_PIXC_578_020_221L_20230710T223456_20230710T223506_PIA1_01.nc\", \"location\": \"http://localhost:3003/concepts/G1200484356-PROV/39\"}"
204-
"""
205-
print(f"Result dict: {result_dict}")
206-
concept_id = result_dict["concept_id"]
207-
revision_id = result_dict["revision_id"]
208-
metadata = result_dict["metadata"]
209-
210-
pgi = self.get_producer_granule_id(metadata)
211-
212-
search_root_url = self.get_public_search_url()
213-
location = f"{search_root_url}concepts/{concept_id}/{revision_id}"
214-
granule_ur = metadata["GranuleUR"] #concept.get('metadata', {}).get('GranuleUR', '')
215-
216-
message = {
217-
"concept-id": concept_id,
218-
"granule-ur": granule_ur,
219-
"location": location
220-
}
221-
222-
if pgi:
223-
message.update({"producer-granule-id": pgi})
224-
print(f"Message: {message}")
225-
return message
226-
227-
def process_result(self, search_result):
228-
"""The search results contain XML, but the metadata is in JSON.
229-
Parse out the XML to get the concept-id and revision-id and store it
230-
in a map. Store the JSON metadata also in the map and return the map."""
231-
# Split the input string into XML and JSON parts
232-
xml_part, json_part = search_result.split('</result>')
233-
234-
# Parse the XML
235-
root = ET.fromstring(xml_part + '</result>')
236-
concept_id = root.find('concept-id').text
237-
revision_id = root.find('revision-id').text
238-
239-
# Parse the JSON into dict.
240-
json_data = json.loads(json_part)
241-
242-
# Create a dictionary with the extracted information
243-
result = {
244-
'concept_id': concept_id,
245-
'revision_id': revision_id,
246-
'metadata': json_data
247-
}
248-
return result
249-
250200
def process_message(self, message):
251201
"""This function gets the Message value from
252202
a SQS message that contains: "{\"concept-id\": \"G1200484356-ERICH_PROV\"}"
@@ -262,16 +212,20 @@ def process_message(self, message):
262212
message_dict = json.loads(message)
263213
print(f"Search process_message The message_dict type is: {type(message_dict)}")
264214
concept_id = message_dict["concept-id"]
215+
revision_id = message_dict["revision-id"]
265216
print(f"Search process_message concept_id: {concept_id}")
266217
# Get the concept from search
267-
result = self.get_concept(concept_id)
218+
result = self.get_concept(concept_id, revision_id)
219+
268220
print(f"Search process_message result: {result}")
269221

270-
# convert the result to a dict containing the concept-id, revision-id, and metadata.
271-
result_dict = self.process_result(result)
272-
print(f"Search process_message result_dict: {result_dict}")
222+
# Parse the JSON into dict.
223+
result_dict = json.loads(result)
273224

274-
# create and return json dict containing the concept-id, granule-ur, producer-granule-id, and the granule location.
275-
new_message = self.create_notification_message_body(result_dict)
276-
print (f"new_message: {new_message}")
277-
return new_message
225+
#Get the producer granule id
226+
pgi = self.get_producer_granule_id(result_dict)
227+
del message_dict['revision-id']
228+
if pgi:
229+
message_dict.update({"producer-granule-id": pgi})
230+
print(f"Search process_message end message: {message_dict}")
231+
return message_dict

subscription/test/search_test.py

Lines changed: 5 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -43,69 +43,14 @@ def test_get_concept(self, mock_get):
4343
self.search.url = 'http://test-url.com'
4444
self.search.token = 'test-token'
4545

46-
result = self.search.get_concept('test-concept-id')
46+
result = self.search.get_concept('test-concept-id', '1')
4747
self.assertEqual(result, json.dumps(self.test_input))
4848

4949
def test_get_producer_granule_id(self):
5050
result = self.search.get_producer_granule_id(self.test_input)
5151
expected = "S1-GUNW-A-R-014-tops-20141030_20141018-152945-24166N_21930N-PP-f419-v2_0_3"
5252
self.assertEqual(result, expected)
5353

54-
def test_create_notification_message_body(self):
55-
# Prepare test input
56-
result_dict = {
57-
"concept_id": "G1200484356-PROV",
58-
"revision_id": "39",
59-
"metadata": {
60-
"GranuleUR": "SWOT_L2_HR_PIXC_578_020_221L_20230710T223456_20230710T223506_PIA1_01",
61-
"DataGranule": {
62-
"Identifiers": [
63-
{
64-
"IdentifierType": "ProducerGranuleId",
65-
"Identifier": "SWOT_L2_HR_PIXC_578_020_221L_20230710T223456_20230710T223506_PIA1_01.nc"
66-
}
67-
]
68-
}
69-
}
70-
}
71-
72-
# Call the method
73-
result = self.search.create_notification_message_body(result_dict)
74-
75-
# Parse the result
76-
result_json = result
77-
78-
# Assert the results
79-
self.assertEqual(result_json["concept-id"], "G1200484356-PROV")
80-
self.assertEqual(result_json["granule-ur"], "SWOT_L2_HR_PIXC_578_020_221L_20230710T223456_20230710T223506_PIA1_01")
81-
self.assertEqual(result_json["producer-granule-id"], "SWOT_L2_HR_PIXC_578_020_221L_20230710T223456_20230710T223506_PIA1_01.nc")
82-
self.assertEqual(result_json["location"], "https://cmr.earthdata.nasa.gov/search/concepts/G1200484356-PROV/39")
83-
84-
def test_create_notification_message_body_no_producer_granule_id(self):
85-
# Prepare test input without producer granule id
86-
result_dict = {
87-
"concept_id": "G1200484356-PROV",
88-
"revision_id": "39",
89-
"metadata": {
90-
"GranuleUR": "SWOT_L2_HR_PIXC_578_020_221L_20230710T223456_20230710T223506_PIA1_01",
91-
"DataGranule": {
92-
"Identifiers": []
93-
}
94-
}
95-
}
96-
97-
# Call the method
98-
result = self.search.create_notification_message_body(result_dict)
99-
100-
# Parse the result
101-
result_json = result
102-
103-
# Assert the results
104-
self.assertEqual(result_json["concept-id"], "G1200484356-PROV")
105-
self.assertEqual(result_json["granule-ur"], "SWOT_L2_HR_PIXC_578_020_221L_20230710T223456_20230710T223506_PIA1_01")
106-
self.assertEqual(result_json["location"], "https://cmr.earthdata.nasa.gov/search/concepts/G1200484356-PROV/39")
107-
self.assertNotIn("producer-granule-id", result_json)
108-
10954
@patch('search.os.getenv')
11055
def test_get_public_search_url_from_parameter_store(self, mock_getenv):
11156
mock_getenv.return_value = 'http://public-search.com/'
@@ -143,10 +88,6 @@ def test_process_message(self, mock_get_public_search_url, mock_get_concept):
14388

14489
# Mock the get_concept method
14590
mock_get_concept.return_value = """
146-
<result>
147-
<concept-id>G1200484356-ERICH_PROV</concept-id>
148-
<revision-id>1</revision-id>
149-
</result>
15091
{
15192
"GranuleUR": "SWOT_L2_HR_PIXC_578_020_221L_20230710T223456_20230710T223506_PIA1_01",
15293
"DataGranule": {
@@ -161,7 +102,7 @@ def test_process_message(self, mock_get_public_search_url, mock_get_concept):
161102
"""
162103

163104
# Input message
164-
input_message = '{"concept-id": "G1200484356-ERICH_PROV"}'
105+
input_message = '{"concept-id": "G1200484356-ERICH_PROV", "revision-id": "1", "granule-ur": "SWOT_L2_HR_PIXC_578_020_221L_20230710T223456_20230710T223506_PIA1_01", "location": "https://cmr.earthdata.nasa.gov/search/concepts/G1200484356-ERICH_PROV/1"}'
165106

166107
# Expected output
167108
expected_output = {"concept-id": "G1200484356-ERICH_PROV", "granule-ur": "SWOT_L2_HR_PIXC_578_020_221L_20230710T223456_20230710T223506_PIA1_01", "location": "https://cmr.earthdata.nasa.gov/search/concepts/G1200484356-ERICH_PROV/1", "producer-granule-id": "SWOT_L2_HR_PIXC_578_020_221L_20230710T223456_20230710T223506_PIA1_01.nc"}
@@ -170,9 +111,10 @@ def test_process_message(self, mock_get_public_search_url, mock_get_concept):
170111
result = search.process_message(input_message)
171112

172113
# Assert
114+
print(f"Test expect: {expected_output}")
115+
print(f"Test result: {result}")
173116
self.assertEqual(result, expected_output)
174-
mock_get_concept.assert_called_once_with("G1200484356-ERICH_PROV")
175-
mock_get_public_search_url.assert_called_once()
117+
mock_get_concept.assert_called_once_with("G1200484356-ERICH_PROV", '1')
176118

177119
if __name__ == '__main__':
178120
unittest.main()

0 commit comments

Comments
 (0)