This is an interesting week for Facebook. I quit using Facebook about 8 years ago and never signed up for Instagram. I did not see any value in these services. And looking at the recent revelations by the whistleblower, I am glad that I am not on these platforms. But I (have to) use WhatsApp to stay connected with my family and friends. There is no alternative. There is strong social pressure in India that requires the use of WhatsApp. My parents use it. Our extended families are hooked to WhatsApp. All my friends are on WhatsApp. Even if I dislike Facebook’s business practices, WhatsApp is a necessary evil. When these systems went down, I was expecting minor inconvenience due to the unavailability of WhatsApp.
But Facebook’s downtime irritated me even so. What happened was mildly interesting. Vaidehi is due for her set of first Flu shots. She needs to take 2 shots, separated by 30 days. During her last wellness visit, her pediatrician indicated that the Flu vaccines would be available in the first week of October. Vaidehi’s regular visit is in the first week of November. I thought it would be a good idea to plan her first shot in early October so she could take the second shot at her regular wellness visit in November.
Her pediatrician’s office depends on Facebook to inform the vaccine schedule. It’s convenient to check their Facebook page to see if vaccines are available and what are the visit times. The alternative is to call the office and stay on hold for 15-20 minutes. As the pandemic has caused nationwide shortages in healthcare, especially nursing care, these appointment slots fill up fast. Due to this, I wanted to get in front of the line to schedule the appointment as soon as it was available. But Facebook was down, and we couldn’t get the information in time.
Anyway, it was not a big deal. I was able to get an appointment by following up over the phone. But it kept me wondering about the situation we are in. A single company has so much control over how the information could be disseminated. The promise of the internet was to make it easy to exchange the information. But if a mistake in the DNS configuration for one company’s servers brings the internet to halt, something has gone very wrong.
This year was my second attempt to make the clay Ganesha idol at home to celebrate Ganesh Utsav. I am not much of an artist. Actually, I am afraid to draw, paint, sing, play an instrument, dance, or do any sort of work that’s considered remotely artistic in nature.
When I was in school, drawing and painting were my Achilles’ heel. I would get the lowest grade possible in these subjects. In fact, I had to leverage my personal relationships with teachers, so they couldn’t flunk me in these subjects. Even with my excellent brownnosing, I distinctly remember scoring 40% in drawing one year. The same year I scored 90%+ marks in STEM subjects. Out of the peer pressure I also attempted the Elementary Drawing exam conducted by the Govt of Maharashtra and failed spectacularly in it. Simply put, I suck at art. That was enough of a deterrent not to try something heroic like making your own idol of a god, especially the one who is considered the master of all artistic skills.
In spite of my reservations about my mediocre skills, I decided to make an idol last year. Before investing in the procurement of supplies and committing to delivering the idol, I built a small prototype using clay doh. That wasn’t very bad. It looked like Ganapati. The mouse was even more adorable.
Encouraged by this prototype, I purchased supplies and various colors. My weekend was put into good use. Instead of mindlessly watching television or scrolling on social media, I built something with my hands. Granted that it was mediocre, that was still my best attempt yet. When I started painting it, I realized that the eyes are the most difficult part of an idol. The idol’s personality is by the eyes. Even a minor imperfection would completely ruin the idol. I became very anxious about it and decided to not draw the eyes but rather glued them. The rest of the adornment was easy. I used craft stones and golden chains along with my wife’s cosmetic bindis to decorate it. The result was pretty good.
Inspired by my earlier success of the first attempt in 2020, I tried making an idol again this year. I was more confident about handling not only the clay but also the brush while painting the idol. It turned out very well.
As a pixel pusher who rarely builds things with hands, creating this idol was such a fantastic and fulfilling experience.
Another practice I put into action was Giving myself an ‘A’. This practice talks about unconditional self-acceptance without judging your skills. Instead of getting bogged down by expectations and performance pressure, this simple act of giving yourself an ‘A’ can do wonders.
I recently read Thinking in Bets by Annie Duke. The book is about making better decisions when you don’t have all the facts.
Often times we confuse the quality of our decisions with the quality of the outcomes. Annie advocates that it is not the right approach. To make better decisions, it’s important to decouple the quality of decisions from the quality of outcomes. She talks about the hazards of resulting - the term poker players use to describe our tendancy of using outcomes to determine the quality of the decisions. The book highlights the irrational nature of our brain. From a survival perspective, our brains aren’t built for rationality. It has to make fast decisions, which can blindside us. For me, the most important takeaway was about redefining wrong - and using uncertainty as an advantage. Instead of thinking in a binary mode of right vs wrong, I liked the approach probabilistic percentages for better decision-making and self-compassion.
While I loved the book and got some good nuggets from it. The content was way too repetitive for my taste. After I completed half of the book, I felt like I am reading the same chapter over and over. There is a lot of filler content, the anecdotes weren’t resonating with me. I overlooked two chapters that talked about the buddy system and future planning.
Overall its a good book with the ideas applicable in professional and personal life.
The highlight of this past weekend was completing Vaidehi’s OCI application.
As soon as her passport arrived, I started working on it. The application process could’ve been so much easier, but turned out to be unnecessarily difficult.
First of all, The information is scattered across two different websites.
VFS - The visa and technology outsourcing company providing services to the Government of India
OCI portal of Government of India.
In more than a couple of places, the instructions are confusing and even conflicting with one another. E.g. The background of the applicant’s photograph can either be white or light-colored depending on which source you are referring to.
When filling out these forms, there are typos and inconsistencies everywhere. E.g. My current country of residence is referred to as the USA, UNITED STATES and UNITED STATES OF AMERICA in the same form.
There isn’t a tooltip or quick help available for some questions asked in a very bureaucratic language. E.g. What is the applicant’s ‘Relationship to the root of the Indian’? What does this question even mean? I had to google it to find an answer.
Getting an acceptable photograph of a 6-month-old baby is a matter of luck. I understand its not unique to the OCI application. But I was warned by a friend whose application was rejected because he used the same photograph as the passport application. So I preferred to use a new photograph. I also needed a fingerprint of her left thumb. But when I looked more closely, I actually had to get the right thumbprint for a girl child. No matter how many times I tried, Vaidehi’s thumbprints were never identical. The uploaded digital image and the thumbprint on the printed form looked very different.
Notarizing this whole thing was another minor challenge. I wasn’t sure how many forms to get notarized. The parental authorization form had clear instructions about notarizing. But the actual application form also needed notarization. The passport could be ‘self notarized’. I wasn’t sure if I could sign the copy of the passport on my daughter’s behalf or should I get her thumbprint on it.
Beyond the challenges with paperwork, the technology experience has a lot of friction. As a user it’s one application for me, but I have to register on two separate websites. Upload some documents on one website, and download the checklist and acknowledgement receipt from another. The OCI site looks straight from the 80s. Even after registration and getting a login id, I have to use some combination of a passport number, date of birth and application number to retrieve or update my data. This whole thing could be packaged in just one application for the end user.
It took me the whole 2 days to get this done. It was surprising because my previous experience with passport renewal was so much better..
After I dropped off the application package at FedEx, I felt a sense of achievement and relief. I hope this gets issued without any challenges and I won’t have to do it again for the next 20 years.
Today practitioners and patients want to use innovative healthcare apps. Oftentimes they have their favorite app that they already use. To provide the best practitioner and patient experience, these apps need access to patient’s personal health information like allergies, or medications. This type of clinical information is stored inside the electronic health record systems (EHRs). Ultimately the apps are dependent on backend systems like EHRs to power their functionality.
There are more than 50 EHR systems popular in the US alone. For an healthcare application developer this would be a nightmare, if he needs to build his app to work with 50 different EHR systems.
Thanks to industry standards like FHIR and SMART on FHIR, this problem is easily solved.
FHIR provides a standardized data model to represent healthcare data, whereas the SMART on FHIR provides a consistent approach to security and data access requirements.
In this post let’s see some basics of SMART on FHIR.
What is SMART on FHIR
SMART stands for Substitutable Medical Applications and Reusable Technology.
SMART app is a web or mobile app, embedded in an Electronic Health Record (EHR) system or standalone. It’s substitutable, which means if you don’t like a particular app, you can choose another one or substitute it with something else. The app is reusable and should work with any EHR or backend system.
Simply put, SMART on FHIR provides a workflow to securely request access to data, as well as receive and use the data. And ultimately enables Electronic Health Record systems to become more like platforms.
SMART on FHIR addresses these key concerns
Identity and access management
Access to the data
Launch framework
Scopes and launch context
Let’s look into the details of each of these for a bit.
Identity and access management
SMART relies on the OIDC - OpenID Connect identity management protocol.
Built on top of OAuth 2.0, it is essentially a flavor or a profile of OIDC, customized for use in healthcare applications.It defines a method through which an app requests authorization to access a FHIR resource, and then uses that authorization to retrieve the resource.
Access to the data
SMART on FHIR uses FHIR to access the data.
FHIR provides a standardized representation of healthcare data, irrespective of how it is stored or where it is coming from. Using a standardized representation of the data makes these apps substitutable as well as reusable.
Launch framework
SMART on FHIR provides a framework for four different use cases
Patient apps that launch standalone
Patient apps that launch from an EHR portal
Provider apps that launch standalone
Provider apps that launch from an EHR portal
Scopes and launch context
SMART provides three different categories of scopes for different kinds of data. Launch context is a negotiation where client asks for specific launch context parameters, and server decides which launch context parameters to provide using client’s request as an input.
Clinical data
SMART on FHIR defines read and write permissions for patient specific and user level access.
E.g.
patient/Observation.read
user/Appointment.read
patient/*.*
Contextual data
Apps typically rely on contextual data like the currently open patient record in an EHR. They explicitly request the EHR context by using scopes like
launch=xyz
launch/patient
launch/encounter
Identity data
Some apps need to authenticate the clinical end-user. They use following openid connect scopes to request the identity information.
openid
fhirUser
This concludes my brief introduction to SMART on FHIR.
SMART on FHIR provides an open, free and standards based API. Developers can use to write an app once and have it run anywhere in healthcare IT system.
I frequently visit one online group. It sends some thought-provoking prompts to reflect on past experiences and random ideas.
Here are some examples.
Which bad commercial that you saw that has stayed with you?
What does a ‘perfect day’ mean to you?
This week’s prompt was about the act of kindness shown to you, that you’ll never forget.
I wanted to share such experience.
Before COVID-19, I was traveling for my job. In July-August 2019, my assignment was in Moline, IL. It’s a small town on Illinois - Iowa border. This was my very first visit to the city. Due to an inclement weather-induced delay, I landed at Moline airport around 12.50 AM on Monday. I couldn’t find an Uber or a taxi to go to the hotel. Apparently no one provides a ride at that time of the night. I didn’t have a rental car booking, and the rental car counters couldn’t provide me a car on the spot. My only other option was to wait at the airport for the next 5 hours and hope for the cab driver to show up. There was no food at that small airport. I was more worried about my important meeting in the morning. As a last attempt, I called the hotel - Element - to check on the possibility of helping me out. I was aware that they don’t provide an Airport shuttle. Fortunately, the front desk lady at the hotel was super helpful and drove at 1.30 AM in her own car to pick me up at the airport.
This random act of kindness from a stranger has left a lasting impression on me. It has also associated this experience with Mariott - the owners of the Element hotels. Whenever I book a hotel room, I search for availability at one of the Mariott’s hotels first.
I received ‘Thanks for the Feedback ’ by Douglas Stone & Sheila Heen as an optional read for my leadership coaching program. I wasn’t very enthusiastic to read it. I didn’t have high expectations from the book. I was suspecting that it will talk about the typical annual review process at work and the kind of feedback you get from your boss. After finishing it in a few days though, I was surprised by how useful it was, not only for the feedback at the job but also in the personal relationships.
I captured the following notes from the book.
What counts as feedback
Feedback is any type of information you receive from another person or organization about yourself. Your manager, partner or spouse, child or a friend always share their opinions with you. The book talks about the effectiveness of receiving feedback gracefully. It teaches the feedback receivers to build self-awareness and helps in planning concrete actions.
Three types of feedback
There are three types of feedback
Appreciation - This is an acknowledgment for a job well done.
Coaching - This type of feedback identifies where you fall short and how you can improve.
Evaluation - This feedback is calibrating your performance, and rating you. This often decides things like your raise and promotion.
Triggers that block the feedback
We do fine with the positive feedback. But the negative feedback is stressful for the giver as well as especially for the receiver. It triggers the receiver. The triggers block the feedback. The purpose of sharing the feedback is not met. The triggers are classified in 3 broad buckets.
Truth Triggers
When you feel that the feedback is wrong and untrue, it results in truth triggers. This can happen when there is a mismatch in the expectation. E.g. You are looking for an appreciation, but your manager gives you coaching. You feel that the feedback is unhelpful and wrong. Whereas your manager feels that with his coaching, he is helping you grow in your career.
There are a few things you can try when receiving the feedback to avoid the truth triggers.
Separate appreciation, coaching, and evaluation:
Ask about the type of feedback you are expecting. The feedback givers aren’t always equipped with the right tools and framework to share appropriate feedback with you. Proactively seek the feedback you are looking for.
Shift from “That’s wrong” to “Tell me more”:
When you receive untruthful feedback, try to learn more about it by asking questions.
Discover your blind spots, and uncover by learning more from the feedback.
Relationship Triggers
Relationship triggers are caused by the relationship you have with the feedback giver. You don’t trust that they are qualified or equipped to give you the feedback. It might be because of the organizational dynamics or interpersonal relationships
Disentangle ‘what’ from ‘who’: Instead of focusing on ‘who is giving you the feedback, focus on ‘what is the feedback.
Identify the relationship system : What is the particular combination of the relationship that is creating the problem? Are your roles clashing? How does this relationship fit into the big picture?
Identity Triggers
Identity triggers are caused when the feedback affects your self-image. This happens when the feedback challenges your relationship with yourself.
Learn how wiring and temperament affect your story:
Think about these questions -
What is your baseline temperament?
How far up or down do you go?
And how do you recover from the negative feedback?
See feedback at its actual size. Don’t exaggerate and get overwhelmed by it. Identify the feedback footprint. Imagine the worst and be prepared for it. Constrain the time, specificity, and the story of the feedback.
Cultivate a growth identity. Accept that you will make mistakes and learn from them. Give yourself a second score - by learning from the experience.
Accepting and rejecting the feedback
You don’t need to accept all the feedback. You can appreciate the efforts and thoughts from the feedback giver but reject the feedback that isn’t useful.
Draw boundaries when enough is enough
Navigate the conversation
Get aligned with the feedback giver
Listen for what’s right and why they see it differently
Assert what’s left out
Be your own process referee
Solve problems to create possibilities
Close with commitment
Keep the conversation in motion
Acting on the feedback
Once you decide to accept the feedback, act on it.
Identify one thing that you can immediately incorporate
Try small experiments
Ride out the J curve
Coach your coach to give you a helpful feedback
To summarize, this book is full of helpful techniques and provides us with ways to extract, cope, handle and grow with the feedback. Receiving feedback is a skill. This book provides a roadmap to build that skill.
Last month I signed up for Audible. I thought it would be great to listen to the audiobooks, instead of reading them. In the past, I had enjoyed a few audiobooks on my long road trips. I especially remember listening to George Carlin’s books. The idea of listening to books on the go, the ultimate portability, and convenience, and an opportunity to give rest to my eyes was very enticing. Audible was offering a 1-month free trial. I skimmed their huge catalog and signed up. The signup process was smooth - as you would expect from Amazon. I downloaded The Spy and the Traitor by Ben Macintyre and started listening to it. While the book was great, one of the best thrillers I enjoyed, my experience with Audible was suboptimal.
Challenges with Audiobooks:
Audiobooks feel strange: When reading a physical or ebook, I feel like driving in daylight, with clear visibility. I can look in the rearview mirrors or outside the windows. I can notice another car approaching the intersection. If someone is overtaking I can adjust my driving. With audiobooks, I feel like someone else is driving even though I am in the driver’s seat. We are traveling in the dark with only front lights. I can’t look sideways or behind, as its all dark
Audiobooks aren’t as convenient as I would like them to be: Audiobooks need a lot of concentration. It’s very easy to get distracted, tune out and miss the important part. Once you lose focus, it becomes very difficult to get back on track.
Audiobooks don’t give the satisfaction of reading: Almost always the narrator is different. His performance is very clean and robotic. There is a constant feeling that it’s not me who is reading this book.
Issues with Audible
Audible’s subscription: When I signed up for Audiobook’s trial, I thought it was like a Netflix model. I was hoping to get access to a large library of content for a low monthly price. I misunderstood. With Audible I get 1 credit to buy a book of my choice every month. Credits expire and there is pressure to buy the book to use those credits. I can buy most of the books I want, whenever I want, without an Audible subscription and still save some money.
Problems with the Audible app - Audible books have DRM, so I can’t listen in the app I like. I have to use the Audible app, which is okay for the most part. But my phone’s aggressive battery management policy kills the app if I pause the book. This is super inconvenient. To begin listening again, I have to restart the app.
Better and cheaper options available - I can borrow audiobooks for free from my local library. Their catalog is not as big as Audible’s but only 2 books I wanted to read were unavailable in my library.
I don’t think I will continue my Audible subscription for now.
This week I got my new pair of glasses. I use photochromic lenses to help protect my eyes from the bright sunlight. These lenses turn dark when exposed to sunlight or high temperature. With this pair, my optician gave me a ‘Certificate of Authenticity’ card from this company called ‘Transitions’. Transitions provide the photochromic feature in the lenses. I wasn’t aware of them. Anyway, this certificate requested that I should register my purchase. I can’t figure out why I should do this, and what’s the downside of not registering. This also got me confused on many fronts. My last 4 pairs purchased from the same optician had photochromic lenses. Yet, I never got a certificate of authenticity. Does it mean those were inauthentic photochromic lenses? What would happen if I continue wearing them? Is this a new program to certify authentic lenses? Is there a spread of inauthentic lenses that the company is trying to contain?
Whatever it might be. I am curious to understand how did this ‘Certificate of Authenticity’ program launch? What’s the strategy? What could be the end goal? Is it to increase brand awareness? That is one possibility. Even though my last 4 pairs had photochromic lenses, I never asked for a specific brand. Now I know about a product, which guarantees the authenticity of photochromic lenses. The next time I am ready for new glasses, should I insist on this specific brand? It is authentic. I know now! Or is it a desperate attempt to capture my contact information? So they can send me targeted advertisements? I looked at the registration page. It asked for my name, address, email, date of birth, gender(!), and other information. At least they didn’t ask for my phone number! (Do they already have it?)
Another interesting question is, how does it relate to Crizal - my go-to lens brand? My lense says it’s from Crizal! Then why do I have this certificate from Transitions? My cursory check on the internet shows that these are two different companies. Does Crizal provide the physical lens? And Transitions provide some sort of mechanism (sticker or a chemical?) to turn the lense dark when exposed to sunlight? Or is it the other way round where Transitions provide the color-changing physical lense, and Crizal provides an anti-reflective, anti-scratch coating on it?
This innocent little card has raised a lot of questions in my mind.
I haven’t posted anything in February. It was the busiest month I ever had. Our baby girl decided to arrive earlier than expected. Due to the pandemic, we decided to manage baby things on our own, without our parents. It’s fun, but for the first time parents like us, it’s not easy. The most difficult part is baby can’t talk and exactly tell us what she wants yet. So we have to decipher her crying. Decoding her crying is like solving a puzzle. Is the diper wet, or poopy? Is she hungry? Or too full and needs to burp? But we just burped few mins ago. Is she too cold or too warm? Or just plain bored? The first few weeks I took a brute force approach and tried everything to soothe her. It worked but it was very inefficient (and exhausting). After a couple of more weeks, we got a hang of it and somewhat able to understand what she wants. (or she has given up on our parenting :)). The interesting thing about parenting is that everyone else has an opinion, and it usually comes down to how we are doing it wrong. ;) I learned to ignore it for the most part. I think nobody knows what they are doing, so it’s just figuring out on the go.
Anyways, here is a funny anecdote. We were visiting the doctor for regular checkups over the last year. On our first visit to the hospital, the nurse told us to ‘go downstairs to the lab’ for the blood checkup. Downstairs I noticed something interesting. There was no lab to be found. At least not easily. There were at least 4 other offices, each of them telling me that ‘it’s not a lab’. The notice on one door told me that the lab was down the hall. But the Y shaped hallway had 3 corners to go.
After walking across all the hallways on that floor for 8-10 minutes, we finally located the lab in one remote corner. I guess we were just unlucky to pick the wrong hallways first. This bad ‘UX’ could’ve been easily avoided by simply putting a small arrow in the direction of the lab.
Whenever I am near the hospital, I feel I should go inside the building and put an arrow to show where the lab is.
FHIR (Fast Healthcare Interoperability Resources) is a new and emerging standard for interoperability in healthcare IT. Unlike the ancient HL7v2 standard, FHIR is open, extensible, and composable. It supports modern web standards like JSON, XML, HTTP(!), and Turtle. It also defines different data exchange methods like RESTful API, messaging, services, documents, and persistent storage. Best of all the FHIR documentation is outstanding: There is detail documentation for every type of resource, with lots of examples. Enough detail for anyone to create a compliant implementation. All of the data types like dates and times, terminologies, identifiers, references, numeric values, extensions are documented in detail, including how to read and write them. It’s probably one of the best documented and well thought out APIs I have worked with.
Epic made their FHIR APIs available on https://fhir.epic.com/. In this post, we will discuss using Epic’s FHIR APIs in Mule 4
Prerequisites
You will need an Epic developer account. You can get one for free by signing up here. I have used Anypoint Studio 7.7 for Mule app.
Configuration
Certificate setup for JWS
We will use SMART Backend Services approach described here which uses signed JWT to get the access token.
Generate a new public-private key pair, and get the certificate(s) in appropriate format
1
2
3
4
5
6
7
8
# generate a new public-private key pairopenssl genrsa -out Anypoint_Mulesoft.pem 2048# export the public key to a base64 encoded X.509 certificateopenssl req -new -x509 -key Anypoint_Mulesoft.pem -out Anypoint_PublicKey.pem -subj '/CN=Anypoint' -days 365# export the keystore in pkcs12openssl pkcs12 -export -in Anypoint_PublicKey.pem -inkey Anypoint_Mulesoft.pem -out Anypoint_Keystore.p12
Click on ‘Create’ and enter your app details as follows. Make sure to select the Application Audience as ‘Backend Systems’. For Sandbox JWT signing public key, upload the public key store (Anypoint_PublicKey.pem) file generated in the previous step. Click on save.
You should see the Client ID and Non-Production Client ID for your app. Select the SMART on FHIR version as R4, enter the summary, accept the terms of usage and click on ‘Save & Ready for Sandbox’.
In my experience it usually takes a couple of hours for your app to be usable in Epic. It took me ~2 hours for my app to be usable
Mule application details
Create a new Mule application, and copy the pkcs12 formatted keystore (Anypoint_Keystore.p12) created earlier, in the src/main/resources folder.
To generate a signed JWT (JWS), we will use Java JWT library. In the pom.xml of your Mule application, include the following dependencies. (I have included Apache log4j dependencies, these are optional).
In Mule application’s src/main/java folder, create a new Java package com.dhimate.demo, class JWTProvider and use following code snippet to generate signed JWT.
In Mule application’s src/main/java folder, create a new Java package com.dhimate.demo, class JWTProvider and use the following code snippet to generate signed JWT.
Calling Epic’s FHIR APIs is a two-step process.
In the first step we need to get the access token using the signed JWT token
In the second step we will use the access token received in the step above to access FHIR resource
Let’s look at the configuration of important components
Generate signed JWS token using Invoke Static component
Prepare request payload to get access token
Get the access token
Call FHIR API to get the data
Once this is done, we can add a simple HTTP listener and connect our flow to it to get the data from Epic’s FHIR API. Epic has provided test data in the sandbox. Let’s use it to search for a patient record.
MuleSoft offers multiple connectors for Salesforce integration. This post is about Salesforce Connector for Mule 4. This connector helps in integrating with Sales Cloud, Service Cloud, Salesforce Platform, and Force.com. We will specifically look into different options for authentication with Salesforce.
Software Prerequisites
You need a Salesforce developer account. You can get one for free by signing up here. I have used the following versions for MuleSoft software.
Anypoint Studio 7.7
Salesforce Connector 10.8.0
Configuration
Security Token in Salesforce
Salesforce security token is an alphanumeric code associated with your password. You do not need a security token if you are trying to authenticate from an IP address that is inside your Salesforce org’s trusted IP range, or your Salesforce profile’s login IP range. When you sign up for a new developer account, your Salesforce org does not have trusted IP ranges. You can either set up trusted or login IP ranges in your org, or use the security token for authentication. Generating security token is simple.
Go to settings
Reset security token by using the ‘Reset My Security Token’ menu and clicking on the ‘Reset Security Token’ button.
You should receive your new security token in your email account that you used to sign up for the Salesforce developer account.
Certificate setup in Salesforce
For certificate-based security, you need to set up a certificate in Salesforce.
Go to setup
Search for certificate and key management and select the option
Click on ‘Create Self-Signed Certificate’ button to create a new certificate and enter the information and save it.
Once certificate is created, download the certificate (.crt) file. We need it for setting up the connected app.
Export the certificate to keystore. We need it to configure the connection information in Mule app.
Enter the password when exporting to keystore
Make sure you save both the .crt file (downloaded in step 4 above) and the .jks file safely on your disk.
Connected App setup in Salesforce
Go to setup
Search for app manager and select the ‘App Manager’ option
Use the ‘New Connected App’ button to create a new connected app.
Fill in name and email. Select ‘Enable OAuth Settings’ Enter two Callback URLs
It should redirect you to enter your credentials on Salesforce login screen and you should receive an authorization code.
This will complete the connected app setup.
Basic Authentication
Basic authentication is the easiest way to authenticate with Salesforce. For basic authentication you need username and password, and optionally a security token.
OAuth JWT
For OAuth JWT connection copy and paste the key store file (.jks) that you created in the certificate setup section into the src/main/resources folder.
Consumer Key – Consumer key of the Connected App that was created in Salesforce
Key Store – Keystore file (.jks) that you downloaded from the certificate setup
Store Password – Keystore password that was created when you generated the key store file
Principal – Salesforce username of the user that was approved against the authorization URL
OAuth SAML
For OAuth SAML connection copy and paste the key store file (.jks) that you created in the certificate setup section into the src/main/resources folder.
Consumer Key – Consumer key of the Connected App that was created in Salesforce
Key Store – Keystore file (.jks) that you downloaded from the certificate setup
Store Password – Keystore password that was created when you generated the key store file
Principal – Salesforce username of the user that was approved against the authorization URL
OAuth Username Password
For OAuth Username Password configure the following properties
Consumer Key – Consumer key of the Connected App that was created in Salesforce
Consumer Secret – Consumer secret of the Connected App that was created in Salesforce
Username – Salesforce login id
Password – Salesforce password
Security Token - Security token associated with the username
I recently finished reading Range - Why Generalists Triumph in a Specialized World by David Epstein. It wasn’t exactly a new topic. It was recommended in Bill Gates’ blog so I was curious about it and picked it up. The book talks about (hyper)specialization vs broad thinking in career as well as life. I had read one perspective about this in other books like ‘Talent is Overrated’ by Geoffrey Colvin, and Cal Newport’s ‘So Good They Can’t Ignore You’.
This book offers a different perspective. It’s quite a myth-buster about the 10000 hours theory or deliberate practice. It explains how the hyperspecialization of narrow skills can be harmful to your long term growth. David kept me engaged throughout the book, even though sometimes the content kept on dragging the same message. It also felt relevant to my experience in life and career. I have been a sort of generalist, trying out different things like software engineering, solution architecture, or pre-sales over the last 20 years in my career. I intentionally avoided sticking to a single tech stack or framework or career track. And sometimes felt bad (or incompetent) being a jack of all trades type of a person. Turns out it isn’t bad to be that guy. In a way, I felt vindicated of everything I have done so far.
The key messages that stuck with me were about the experimentation and match quality - the term used to describe the fit between work someone does and their abilities. Everyone progresses at a different rate, so feeling behind doesn’t help much. Most likely you don’t know where exactly you are going. In this situation, the proactive pursuit of match quality, experimentation with different things, learning and adjusting as you go is the best approach. Comparing yourself to (cherry-picked) younger people doesn’t help either. Instead, compare yourself to your yesterday’s self and see how you are progressing. Epstein provides a good framework and reason to encourage range (rather than depth) over different areas of interest and stay curious.
As noted above, some of the repetitive content could’ve been edited to make it more concise. But other than that it was a fun and enjoyable read.
I like to keep my code clean, understandable, and readable. It helps the next person who will take over my work. I try my best to avoid any trouble reading, maintaining, and updating the code.
There are recommended and well known best practices about organizing Mule code. It involves better structuring of the project, maintaining configuration files, hiding or securing sensitive information like passwords and API keys, transaction management, or reconnection and caching strategies.
The lesser-known trick is about externalizing SOQL and SQL queries. Before I knew this trick I organized my SQL queries in properties files, and used spring placeholders like ${account.query} or dataweave Mule::p function to inject or read the queries in the code. It is not an elegant approach. It made the properties file difficult to manage and read. Then I discovered ${file::} notation to inject the queries. It offers a much better way to externalize the queries.
Using this notation is easy. In your Mule app, organize your queries in the src/main/resources folder in their own files as shown below.
Once you organize your queries properly, injecting those queries is easy.
This organization helps in keeping the XML configuration file readable and easily maintainable.
I discovered that the easiest way to start drinking more water is to always keep a water bottle with me. Before going to bed, I keep a bottle of water next to the bed. The idea is, when I wake up, the first thing I see is the water bottle. I drink that bottle before getting out of bed. This system helps me get a significant headstart in meeting my daily water drinking quota.
A few years back I was consulting for a client in Minneapolis. I traveled every other week to Minneapolis to work from their office. I worked with them for almost a year. It was fun and enjoyable work. During that time I developed a good camaraderie with my colleagues there. When I started working with them I noticed that they had a similar - effortless - system to drink more water during office hours.
Our office in Minneapolis was a repurposed shopping complex. It was a huge single-story building with a large parking place all around it. Our sitting arrangement was based on the ‘open office’ concept. In this arrangement, each team would get a or working area - but not individual cubicles for each team member. This improves the collaboration and communication within the team. Our working area was in one corner of the building. It was diagonally opposite to the cafeteria, which was located in another corner of the building. There was a water fountain nearby our working area. My colleagues followed a system to only get water from the cafeteria, or the water-fountain near the cafeteria. Like clockwork, we used to get up every couple of hours, walk to the cafeteria, refill our bottles, and get back to the desk. Without consciously putting any effort, or setting specific goals, this simple system ensured that we drink enough water throughout the day. The other advantage was getting some sunlight and fresh air when the weather was nice. Or simply getting out of the chair and get our bodies moving. Drinking more water also ensured more restroom visits, so that was an additional ‘get out of the chair’ bonus. When I was not in the office, and working from home, I didn’t drink enough water. I did not have an effortless system in place to develop this habit.
My brain is lazy. It wants to conserve energy. And so instead of looking at each problem and providing an appropriate solution, it falls into usual patterns. To develop a good habit, I need to have an effortless system. It should be simple. e.g. Keeping a water bottle with me.
This is a simple trick I use to debug connection issues with the mule app deployed to CloudHub.
First of all its important to understand that there are different ways to set up your application
1. Using shared load balancer (i.e. cloudhub.io domain) with HTTP protocol.
In this scenario, the client application makes a request to a shared load balancer URL using HTTP protocol. The SLB forwards the request to the upstream mule application listening on port 8081.
Note that in this scenario the SLB URL receives the request on port 80, and forwards it to mule application listening on port 8081.
2. Using shared load balancer (i.e. cloudhub.io domain) with HTTPS protocol.
In this scenario, the client application makes a request to a shared load balancer URL using HTTPS protocol. The SLB forwards the request to the upstream mule application listening on port 8082.
Note that in this scenario the SLB URL receives the request on port 443, and forwards it to mule application listening on port 8082.
3. Using dedicated load balancer (i.e. vanity domain) with HTTPS protocol.
In this scenario, the client application makes a request to a dedicated load balancer URL(exposed by a vanity domain) using HTTPS protocol. The DLB forwards the request to the upstream mule application listening on port 8091.
Note that in this scenario the DLB URL receives the request on port 443, and forwards it to mule application listening on port 8091.
4. Using dedicated load balancer (i.e. vanity domain) with HTTPS protocol.
In this scenario, the client application makes a request to a dedicated load balancer URL(exposed by a vanity domain) using HTTPS protocol. The DLB forwards the request to the upstream mule application listening on port 8092.
Note that in this scenario the DLB URL receives the request on port 443, and forwards it to mule application listening on port 8092.
5. Not using load balancers.
This is one of those scenarios where you are not using Anypoint Platform load balancers. You are either using third-party load balancers, or your applications are using non HTTP protocols like a simple socket, or MLLP. In this case, the client application makes a request directly to the application (mule-worker).
As seen above, to make your application endpoint available to the clients
When using a shared load balancer, your application should be listening on an appropriate port (8081 or 8082)
When using a dedicated load balancer, your application should be listening on an appropriate port (8091 or 8092), and the load balancer’s upstream HTTP protocol should be configured properly.
The VPC firewall should be configured properly to allow the ingress traffic on the appropriate port.
If there is a misconfiguration, your application endpoint will not be accessible. Your clients will get errors like ‘Bad Gateway’, or ‘Timeout’. The easiest way to debug these types of errors is to use netcat to perform port scanning and identify open ports on your application.
For example, to check if your application hello-httpbin is listening on port 8081 you can use
nc -w 1 -G 1 -z -v mule-worker-hello-httpbin.cloudhub.io 8081 Connection to mule-worker-hello-httpbin.cloudhub.io port 8081[tcp/sunproxyadmin] succeeded!
In this you can see, the application name is prefixed with mule-worker, to get the correct DNS name. For more details about this convention, please see the DNS records section in Cloudhub Networking Guide. The other options of netcat (or nc) are as follows
-w: Timeout when a connection is idle for more than specified seconds.
-G: TCP connection timeout in seconds.
-z: Just scan for listening daemons, without sending any data to them.
-v: Give more verbose output.
If you are not sure about the specific open port in your application, you can specify the range and identify all open ports using
nc -w 1 -G 1 -z -v mule-worker-hello-httpbin.cloudhub.io 8081-8092
Connection to mule-worker-hello-httpbin.cloudhub.io port 8081[tcp/sunproxyadmin] succeeded!
nc: connectx to mule-worker-hello-httpbin.cloudhub.io port 8082(tcp) failed: Connection refused
nc: connectx to mule-worker-hello-httpbin.cloudhub.io port 8083(tcp) failed: Operation timed out
nc: connectx to mule-worker-hello-httpbin.cloudhub.io port 8084(tcp) failed: Operation timed out
nc: connectx to mule-worker-hello-httpbin.cloudhub.io port 8085(tcp) failed: Operation timed out
nc: connectx to mule-worker-hello-httpbin.cloudhub.io port 8086(tcp) failed: Operation timed out
nc: connectx to mule-worker-hello-httpbin.cloudhub.io port 8087(tcp) failed: Operation timed out
nc: connectx to mule-worker-hello-httpbin.cloudhub.io port 8088(tcp) failed: Operation timed out
nc: connectx to mule-worker-hello-httpbin.cloudhub.io port 8089(tcp) failed: Operation timed out
nc: connectx to mule-worker-hello-httpbin.cloudhub.io port 8090(tcp) failed: Operation timed out
nc: connectx to mule-worker-hello-httpbin.cloudhub.io port 8091(tcp) failed: Connection refused
nc: connectx to mule-worker-hello-httpbin.cloudhub.io port 8092(tcp) failed: Connection refused
In this, you can see that the application only has port 8081 open. Also interesting to note that the ports 8082, 8091, and 8092 are ‘refusing connection’, as they are allowed in the firewall but they are not exposed in the application. Whereas for the remaining ports we are getting an ‘Operation timed out’ error as they are blocked at the firewall.
The simple netcat/nc utility has saved me a lot of time. I hope it helps you as well.