Skip to content

Commit 227b16e

Browse files
authored
Merge pull request #329 from AmericaSCORESBayArea/sandbox
Production: Improved Global Error Handler, Duplicate Handling, Enrollment Concurrency Improvement
2 parents fc57627 + 46b3ef3 commit 227b16e

File tree

6 files changed

+170
-295
lines changed

6 files changed

+170
-295
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,4 @@ src/main/resources/deploy.json
5555

5656
src/main/resources/keystore.jks
5757
/bin/
58+
/venv

docs/concurrency_test.py

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -53,43 +53,52 @@
5353
#
5454
# ================================================
5555

56-
number_of_requests = 20
57-
url = "https://production-salesforce-data-api.us-e2.cloudhub.io/api/enrollments"
56+
number_of_requests = 10
57+
url = "https://localhost:8091/api/enrollments"
5858
headers = {
59-
'client_id': '',
60-
'client_secret': '',
61-
'Content-Type': 'application/json'
59+
'Content-Type': 'application/json'
6260
}
63-
payload = json.dumps({
64-
"TeamSeasonId": "",
65-
"StudentId": "",
66-
"StartDate": "",
67-
"EndDate": ""
68-
})
61+
payload = json.dumps(
62+
{
63+
"TeamSeasonId": "a0qUQ000003SRI5YAO",
64+
"StudentId": "003cX000009kPO1QAM",
65+
"StartDate": "2017-01-01",
66+
"EndDate": "2018-01-01"
67+
}
68+
)
6969

7070
async def send_post_request(session, url, headers, payload, idx):
71-
start_time = time.time()
71+
start_time = time.time()
7272
print(f"Starting request {idx + 1} to {url}")
73-
async with session.post(url, headers=headers, data=payload) as response:
74-
elapsed_time = time.time() - start_time
75-
print(f"Completed request {idx + 1} to {url}")
76-
return await response.text(), response.status, elapsed_time
77-
73+
try:
74+
async with session.post(url, headers=headers, data=payload) as response:
75+
elapsed_time = time.time() - start_time
76+
print(f"Completed request {idx + 1} to {url}")
77+
return await response.text(), response.status, elapsed_time
78+
except Exception as e:
79+
elapsed_time = time.time() - start_time
80+
print(f"Error in request {idx + 1}: {e}")
81+
return None, None, elapsed_time
7882

7983
async def main():
80-
async with aiohttp.ClientSession() as session:
84+
connector = aiohttp.TCPConnector(ssl=False) # Disable SSL verification
85+
timeout = aiohttp.ClientTimeout(total=60) # Set timeout to 60 seconds
86+
async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session:
8187
tasks = [send_post_request(session, url, headers, payload, idx) for idx in range(number_of_requests)]
8288
responses = await asyncio.gather(*tasks)
8389

8490
for idx, (response_text, status_code, elapsed_time) in enumerate(responses):
85-
print(f"Response from Request {idx + 1}:")
86-
print(f"Status Code: {status_code}")
87-
print(f"Time Taken: {elapsed_time:.2f} seconds")
88-
print(response_text)
91+
if response_text is not None:
92+
print(f"\nResponse from Request {idx + 1}:")
93+
print(f"Status Code: {status_code}")
94+
print(f"Time Taken: {elapsed_time:.2f} seconds")
95+
print(response_text)
96+
else:
97+
print(f"\nRequest {idx + 1} failed.")
8998

9099
start_total_time = time.time()
91100

92101
asyncio.run(main())
93102

94103
end_total_time = time.time()
95-
print(f"\nTotal time for all requests to complete: {end_total_time - start_total_time:.2f} seconds")
104+
print(f"\nTotal time for all requests to complete: {end_total_time - start_total_time:.2f} seconds")

src/main/mule/contacts.xml

Lines changed: 41 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -138,145 +138,7 @@ payload]]>
138138
</ee:set-variable>
139139
</ee:variables>
140140
</ee:transform>
141-
<ee:transform doc:id="check-required-fields" doc:name="Check Required Fields">
142-
<ee:message>
143-
<ee:set-payload>
144-
145-
146-
<![CDATA[%dw 2.0
147-
output application/java
148-
---
149-
{
150-
missingFields: [
151-
if (isEmpty(vars.originalPayload.FirstName) or vars.originalPayload.FirstName == null) "FirstName" else "",
152-
if (isEmpty(vars.originalPayload.LastName) or vars.originalPayload.LastName == null) "LastName" else "",
153-
// if (isEmpty(vars.originalPayload.Birthdate) or vars.originalPayload.Birthdate == null) "Birthdate" else "",
154-
// if (isEmpty(vars.originalPayload.ContactType) or vars.originalPayload.ContactType == null) "ContactType" else "",
155-
// if (isEmpty(vars.originalPayload.SchoolSiteId) or vars.originalPayload.SchoolSiteId == null) "SchoolSiteId" else ""
156-
] filter ((field) -> field != "")
157-
}]]>
158-
159-
160-
</ee:set-payload>
161-
</ee:message>
162-
</ee:transform>
163-
<choice doc:id="check-for-missing-fields" doc:name="Check for Missing Fields">
164-
<when expression="#[sizeOf(payload.missingFields) > 0]">
165-
<ee:transform doc:id="raise-missing-fields-error" doc:name="Raise Missing Fields Error">
166-
<ee:message>
167-
<ee:set-payload>
168-
169-
170-
<![CDATA[%dw 2.0
171-
output application/json
172-
---
173-
{
174-
error: "Field Error",
175-
missingFields: (payload.missingFields joinBy ", ")
176-
}]]>
177-
178-
179-
</ee:set-payload>
180-
</ee:message>
181-
</ee:transform>
182-
<raise-error doc:id="missing-fields-error" doc:name="Raise error" type="CREATECONTACT:MISSINGFIELDS"></raise-error>
183-
</when>
184-
<otherwise>
185-
<salesforce:query config-ref="Salesforce_Config" doc:id="61c0f5f7-6cee-4580-a92a-2432384dba3c" doc:name="Check for matching Contacts">
186-
<salesforce:salesforce-query>
187-
188-
189-
<![CDATA[
190-
SELECT
191-
Id,
192-
Contact_Type__c,
193-
RecordTypeId,
194-
FirstName,
195-
MiddleName,
196-
LastName,
197-
AccountId,
198-
School_Attending__c,
199-
Email,
200-
HomePhone,
201-
Birthdate,
202-
Gender__c,
203-
Grade__c,
204-
Level__c,
205-
Ethnicity__c,
206-
Permission_to_Commute_Alone__c,
207-
Reduced_Price_Lunch__c,
208-
Allergies__c,
209-
External_Student_ID__c,
210-
External_Student_DB__c,
211-
Parent_First_Name__c,
212-
Parent_Last_Name__c,
213-
Parent_Email_Address__c,
214-
Parent_Relationship_to_Child__c,
215-
Parent_Phone_01__c,
216-
Parent_Phone_02__c,
217-
Parent_Phone_03__c,
218-
MailingStreet,
219-
MailingCity,
220-
MailingState,
221-
MailingPostalCode,
222-
MailingCountry,
223-
Parent_English_Fluency__c,
224-
Parent_Home_Language__c,
225-
Parent_Other_Language__c,
226-
Volunteer_for_this_Program_Parent__c,
227-
Emergency_Contact_Name__c,
228-
Emergency_Contact_Relationship_to_Child__c,
229-
Emergency_Contact_Name_Phone_01__c,
230-
Emergency_Contact_Name_Phone_02__c,
231-
Emergency_Contact_Name_Phone_03__c,
232-
Emergency_Contact_Permission_to_Pick_Up__c,
233-
Second_Emergency_Contact_Name__c,
234-
Second_Emerg_Contact_Relationship_Child__c ,
235-
Second_Emergency_Phone_01__c,
236-
Second_Emergency_Phone_02__c,
237-
Second_Emergency_Phone_03__c,
238-
Second_Emergency_Permission_to_Pick_Up__c,
239-
Liability__c,
240-
Media_Release__c,
241-
Data_Release__c,
242-
Year_of_Reference_for_Grade_Information__c,
243-
Grades_child_participated__c,
244-
Latest_Waiver_Date__c
245-
FROM
246-
Contact
247-
WHERE
248-
(
249-
FirstName = ':firstName'
250-
AND LastName = ':lastName'
251-
)
252-
]]>
253-
254-
255-
</salesforce:salesforce-query>
256-
<salesforce:parameters>
257-
258-
259-
<![CDATA[#[output application/java
260-
import * from modules::GlobalModules
261-
---
262-
{
263-
firstName: escapeSpecialSOQLChars(vars.originalPayload.FirstName, chars) default '',
264-
lastName: escapeSpecialSOQLChars(vars.originalPayload.LastName, chars) default ''
265-
// birthDate: vars.originalPayload.Birthdate as Date {format: 'yyyy-MM-dd'}
266-
}]]]>
267-
268-
269-
</salesforce:parameters>
270-
</salesforce:query>
271-
<choice doc:id="lkfxwp" doc:name="Choice">
272-
<when expression="#[(sizeOf(payload)) == 0]">
273-
<set-variable doc:name="Set Response Message" value="Contact Created" variableName="responseMessage"></set-variable>
274-
</when>
275-
<otherwise doc:name="Otherwise">
276-
<set-variable doc:name="Set Response Message" value="Matching Record Found, but New Contact Created" variableName="responseMessage"></set-variable>
277-
</otherwise>
278-
</choice>
279-
<choice doc:id="4ebe7cc5-cdea-40dd-ad03-c336e80593f4" doc:name="Choice">
141+
<choice doc:id="4ebe7cc5-cdea-40dd-ad03-c336e80593f4" doc:name="Choice">
280142
<when expression="vars.originalPayload.IsCoach == true">
281143
<ee:transform doc:id="75aaae73-16f5-47d8-b711-36836005ac55" doc:name="Transform Message">
282144
<ee:message></ee:message>
@@ -317,35 +179,28 @@ import * from modules::GlobalModules
317179
<choice doc:id="f4cd0f1b-881f-43ff-9b0d-5f376b8d1c95" doc:name="Choice">
318180
<when expression="#[payload.successful == false and payload..errors != null]">
319181
<logger doc:id="e9c02dd8-02dd-495d-8e01-b26db3d73ec2" doc:name="Logger" level="INFO" message="Fuzzy contact match found"></logger>
320-
<ee:transform doc:id="25161c62-97b1-46bb-b132-14cfffd013e3" doc:name="Transform Message">
321-
<ee:message>
322-
<ee:set-payload>
323-
324-
325-
<![CDATA[%dw 2.0
326-
output application/json
327-
---
328-
payload.items[0].payload]]>
329-
330-
331-
</ee:set-payload>
332-
</ee:message>
333-
</ee:transform>
334-
<raise-error doc:id="ce9837bc-7e7b-40a4-a132-7f35e82f12bc" doc:name="Raise error" type="CREATECONTACT:CONFLICT"></raise-error>
182+
<set-variable doc:name="Set Custom Error Type" value="#['SALESFORCE_CONTACT_CREATE:' ++ (payload.items[0].statusCode default 'UNKNOWN')]" variableName="errorCustomType" />
183+
<set-variable value="#[payload.items[0].message default 'Unknown Error']" doc:name="Set Custom Error Message" doc:id="3881f772-34d8-4c47-88d3-1aab40c248d1" variableName="errorCustomMessage" />
184+
<choice doc:name="Choice" doc:id="68822a13-1319-472a-8858-780e4566d86d">
185+
<when expression='#[vars.errorCustomType == "SALESFORCE_CONTACT_CREATE:DUPLICATES_DETECTED"]'>
186+
<set-variable value="409" doc:name="Set Status Code" doc:id="03654d66-3aed-477e-88a3-e97dd843b1b3" variableName="httpStatus" />
187+
</when>
188+
<when expression='#[vars.errorCustomType == "SALESFORCE_CONTACT_CREATE:MALFORMED_ID"]'>
189+
<set-variable value="400" doc:name="Set Status Code" doc:id="28d20a62-20e9-4298-8fb0-2c715fa266ef" variableName="httpStatus" />
190+
</when>
191+
</choice>
192+
<raise-error doc:id="ce9837bc-7e7b-40a4-a132-7f35e82f12bc" doc:name="Raise error" type="CUSTOM:CUSTOM_ERROR" description="Something went wrong while creating a contact. " />
335193
</when>
336194
<otherwise>
337195
<set-variable doc:id="cpmuyh" doc:name="Set variable" value="#[payload.items[0].id]" variableName="contactId"></set-variable>
338196
<flow-ref name="get:\contacts\(contactId):salesforce-data-api-config"></flow-ref>
339197
<ee:transform doc:id="18206104-36d4-441a-aed7-42d906b5b2a2" doc:name="Create response" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
340198
<ee:message>
341-
<ee:set-payload>
342-
343-
344-
<![CDATA[%dw 2.0
199+
<ee:set-payload><![CDATA[%dw 2.0
345200
output application/json
346201
---
347202
{
348-
message: vars.responseMessage,
203+
message: "Contact successfully created.",
349204
ContactId: vars.contactId,
350205
data: payload
351206
}]]>
@@ -440,35 +295,28 @@ payload.items[0].payload]]>
440295
<choice doc:id="991c54f0-e8dc-4917-b914-9d0f787614c1" doc:name="Choice">
441296
<when expression="#[payload.successful == false and payload..errors != null]">
442297
<logger doc:id="7179ab2b-5642-4f83-a3d6-ff4161272ef3" doc:name="Logger" level="INFO" message="Fuzzy contact match found"></logger>
443-
<ee:transform doc:id="959dfdf6-d25f-47c4-a78e-ecc16c362c9b" doc:name="Transform Message">
444-
<ee:message>
445-
<ee:set-payload>
446-
447-
448-
<![CDATA[%dw 2.0
449-
output application/json
450-
---
451-
payload.items[0].payload]]>
452-
453-
454-
</ee:set-payload>
455-
</ee:message>
456-
</ee:transform>
457-
<raise-error doc:id="e2b03e01-fe96-4b23-86e0-5db2d933c816" doc:name="Raise error" type="CREATECONTACT:CONFLICT"></raise-error>
298+
<set-variable doc:name="Set Custom Error Type" value="#['SALESFORCE_CONTACT_CREATE:' ++ (payload.items[0].statusCode default 'UNKNOWN')]" variableName="errorCustomType" />
299+
<set-variable value="#[payload.items[0].message default 'Unknown Error']" doc:name="Set Custom Error Message" doc:id="3881f772-34d8-4c47-88d3-1aab40c248d1" variableName="errorCustomMessage" />
300+
<choice doc:name="Choice" doc:id="f7787813-3e7d-464d-8c06-e18f246213f9">
301+
<when expression='#[vars.errorCustomType == "SALESFORCE_CONTACT_CREATE:DUPLICATES_DETECTED"]'>
302+
<set-variable value="409" doc:name="Set Status Code" doc:id="796109aa-e4db-494c-b26c-b2bce9b90c44" variableName="httpStatus" />
303+
</when>
304+
<when expression='#[vars.errorCustomType == "SALESFORCE_CONTACT_CREATE:MALFORMED_ID"]'>
305+
<set-variable value="400" doc:name="Set Status Code" doc:id="65f5844b-33d7-4253-b66f-550d08d48f3f" variableName="httpStatus" />
306+
</when>
307+
</choice>
308+
<raise-error doc:id="ce9837bc-7e7b-40a4-a132-7f35e82f12bc" doc:name="Raise error" type="CUSTOM:CUSTOM_ERROR" description="Something went wrong while creating a contact. " />
458309
</when>
459310
<otherwise>
460311
<set-variable doc:id="eatcfc" doc:name="Set variable" value="#[payload.items[0].id]" variableName="contactId"></set-variable>
461312
<flow-ref name="get:\contacts\(contactId):salesforce-data-api-config"></flow-ref>
462313
<ee:transform doc:id="bc80392c-09c1-43c1-ac5b-ebf8dd509785" doc:name="Create response" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
463314
<ee:message>
464-
<ee:set-payload>
465-
466-
467-
<![CDATA[%dw 2.0
315+
<ee:set-payload><![CDATA[%dw 2.0
468316
output application/json
469317
---
470318
{
471-
message: vars.responseMessage,
319+
message: "Contact successfully created.",
472320
ContactId: vars.contactId,
473321
data: payload
474322
}]]>
@@ -482,8 +330,6 @@ payload.items[0].payload]]>
482330
</choice>
483331
</otherwise>
484332
</choice>
485-
</otherwise>
486-
</choice>
487333
</flow>
488334
<flow name="get:\contacts:salesforce-data-api-config">
489335
<logger doc:id="4757f003-ed95-4269-9939-0811ef781500" doc:name="Log entry-flow" level="INFO" message="Method and Request Path stored as vars: method=#[vars.method], request path=#[vars.requestPath]. queryparams=#[attributes.queryParams]"></logger>
@@ -874,7 +720,10 @@ attributes.queryParams.'searchString' replace /[&|!(){}\[\]^"~*?:\\'+\-]/ with("
874720
</choice>
875721
<choice doc:name="Choice1" doc:id="96cea7f6-14a1-4d76-8cf9-8e1d736b29b6">
876722
<when expression="#[isEmpty(vars.searchString)]">
877-
<raise-error doc:name="Raise error" doc:id="43545a36-38f7-4716-ad03-648ee734f5dc" type="SEARCH:BAD_REQUEST" description="`searchString` is empty or includes only special characters" />
723+
<set-variable value="SEARCH:BAD_REQUEST" doc:name="Set Custom Error Type" doc:id="57e888c4-bb95-4039-9807-624f70a3249e" variableName="errorCustomType" />
724+
<set-variable value="`searchString` is empty or includes only special characters" doc:name="Set Custom Error Message" doc:id="6a74df74-a9d5-48c4-9c32-b061d11fad2d" variableName="errorCustomMessage" />
725+
<set-variable value="400" doc:name="Set Status Code" doc:id="518684e1-cf60-4f92-9fa2-0fc97c449d8f" variableName="httpStatus" />
726+
<raise-error doc:name="Raise error1" doc:id="0e90e196-0b94-4c46-995b-8cc00804bbda" type="CUSTOM:CUSTOM_ERROR" description="Something went while performing a search." />
878727
</when>
879728
</choice>
880729
<salesforce:query
@@ -1863,7 +1712,16 @@ attributes.queryParams.'searchString' replace /[&|!(){}\[\]^"~*?:\\'+\-]/ with("
18631712
<!-- First SOSL query to get total count -->
18641713
<choice doc:name="Choice" doc:id="6c9d8b1d-4076-42d8-8d96-b8ba6b774ee2" >
18651714
<when expression="#[isEmpty(vars.searchString)]">
1866-
<raise-error doc:name="Raise error" doc:id="fe77e7ad-799e-4746-8702-cd006aa82693" type="SEARCH:BAD_REQUEST" description="`searchString` is empty or includes only special characters"/>
1715+
<set-variable value="SEARCH:BAD_REQUEST" doc:name="Set Custom Error Type" doc:id="93817aa7-88f2-480e-b17e-172c65934d04" variableName="errorCustomType" />
1716+
<set-variable value="`searchString` is empty or includes only special characters" doc:name="Set Custom Error Message" doc:id="2bd394d4-e6fc-4155-ae4b-f7de594c0286" variableName="errorCustomMessage" />
1717+
<set-variable value="400" doc:name="Set Status Code" doc:id="0c98deb5-8566-4366-832d-f7f2ca65ed3e" variableName="httpStatus" />
1718+
<raise-error doc:name="Raise error1" doc:id="5ddc84e5-66a7-4edb-a986-c4990d471b8e" type="CUSTOM:CUSTOM_ERROR" description="Something went while performing a search." />
1719+
</when>
1720+
<when expression="#[sizeOf(vars.searchString) == 1]">
1721+
<set-variable value="SEARCH:BAD_REQUEST" doc:name="Set Custom Error Type" doc:id="907c8a99-990b-43e2-a2a9-90a8d01f14b7" variableName="errorCustomType" />
1722+
<set-variable value="`searchString` must be more than 1 character after cleaning from special characters." doc:name="Set Custom Error Message" doc:id="0617dfe4-bb94-47de-993c-547978c7ef6e" variableName="errorCustomMessage" />
1723+
<set-variable value="422" doc:name="Set Status Code" doc:id="dd0a4f31-e1a3-49ed-ba19-dfdfba7d1fd2" variableName="httpStatus" />
1724+
<raise-error doc:name="Raise error1" doc:id="23438120-62a7-4e1c-8dfe-e517777ff937" type="CUSTOM:CUSTOM_ERROR" description="Something went while performing a search." />
18671725
</when>
18681726
</choice>
18691727
<salesforce:search config-ref="Salesforce_Config" doc:id="count-query" doc:name="Get Total Count">

0 commit comments

Comments
 (0)