Anypoint Studio
-
Studio updates
- Keep your Anypoint Studio up-to-date (Install Studio Updates when available)
Mule Runtime
- It’s really important the coherence of the Mule Runtimes version within the SDLC. If you developed and tested your application using a Mule Runtime 3.9.0, deploy it to a worker with the same Runtime version.
- Upgrade your projects constantly to the latest patch-version 3.8.x/3.9.x (Install the new Runtimes from the Studio Update Site or from the Mule Runtime Update Site).
- If you want to migrate your applications to a minor-new-version or a major-new-version (e.g. 3.9.x or 4.x) follow the migration guides provided in the MuleSoft public documentation
Mule Projects in Anypoint Studio
- Use Maven
- Include a .gitignore file
- Add APIKit components getting the RAML from Design Center
Project Files Structure
- Create a separate xml for the global elements (e.g. configuration elements)
- Create a separate xml for each use-case or resource-implementation
- Create separate xmls for common structures/logic
- Create different packages for the resources (dataweave, wsdls, examples, etc)
XML identation and formatting
- Define a line width in your Anypoint Studio XML editor preferences, e.g. 140
- Indent all your xml (mule xmls, pom.xml, log4j2.xml, etc) files before committing to the source code repository
Naming Conventions
Category | Convention | Pattern | Examples | Comments |
Mule Projects | kebab-case | {domain}-{subdomain}-{layer}-{type}
{process-or-integration-name} |
students-sys-api
identity-sys-api cloudhub-log-aggregator |
The project name should match the API
name In the case of polling/batch processes, not API related projects, is enough to use a descriptive name with kebab-case |
Maven Group Id | fixed name | edu.nyu | edu.nyu | |
Mule XML files | kebab-case | {significant-name}.xml | students-api.xml
get-students.xml common.xml |
|
Global Elements | kebab-case | {significant-name} | http-listener-config | |
Mule properties files | dot separated | {domain}.{subdomain}.{layer}.{environment}.properties | students.sys.dev.properties
students.sys.prod.properties |
Lower case |
Mule properties keys | dot separated | – | http.host
core.utils.api.path |
Lower case |
Dataweave resources packages | package notation | {dw}.{classifier}
{dw}_{classifier} |
dw
dw.students dw.students.courses dw.health_check |
e.g. complete path: src/main/resources/dw/
students/courses |
Dataweave Scripts | kebab-case | {significant-name}.dwl | build-error-message.dwl | |
JSON Examples | kebab-case | {method}-{significant-name}-{request|response}-example | get-students-response-example | |
Mule flows | kebab-case | {significant-description}-flow | send-user-to-queue-flow | |
API HTTP base path (On Prem) | {domain}/{subdomain}/{layer}/
{version}/* |
/students/sys/v1/* | On premise applications will be on the
same server and the APIs will differentiate |
|
API HTTP base path (Cloudhub) | /api/* | Each Cloudhub application has its own s
erver |
Properties per environment
- Use property placeholders to externalise properties. Use a placeholder in the location-name of the file to identify the environment.
<context:property-placeholder location=”students.api.${mule.env}.properties”/> |
Mule Components
Dataweave
- Use Dataweave:
- To transform/enrich the data, dates transformation and build error/response messages instead of custom scripting code (Java, Groovy, etc)
- When dealing with large payloads, include the directive indent=false to improve the client’s parsing performance and to reduce the response payload size.
- Define the input content-type to avoid verbosive messages in the Log e.g.
<dw:transform-message doc:name=”Build Approval Message”>
<dw:input-payload mimeType=”application/java”/>
<dw:set-payload resource=”classpath:dw/governance/build-approval-status-response.dwl”/>
</dw:transform-message>
|
- Use inline dataweave scripts on the development phase, then pass it to an external file to have a clean xml and reusable scripts.
- For more information:
HTTP Listener
- Use the following placeholders:
- ${http.private.port} when deploying to CloudHub using HTTP and using a Dedicated Load Balancer (http.private.port is a reserved key in CloudHub that resolves to 8091)
- ${https.private.port} when deploying to CloudHub using HTTPS and using a Dedicated Load Balancer (https.private.port is a reserved key in CloudHub that resolves to 8092)
- If HTTPS is required (e.g. in the DLB upstream protocol or for the CloudHub shared load balancer) use the HTTP Listener with a TLS Context reference, configuring the key-store with a key-pair values generated with keytool.
<tls:context name=”TLS_Context” doc:name=”TLS Context”>
<tls:key-store type=”jks” path=”company-keystore.jks” alias=”${jks.alias}” keyPassword=”${jks.key.password}” password=”${jks.password}”/>
</tls:context>
|
HTTP Request
Request to APIs with self-signed certificates
When consuming APIs that are exposed with a self-signed certificate, use the HTTP Requester with a TLS Context reference, configuring the trust store with the self-signed certificate or including the “insecure=true” attribute to avoid the certificate validation (useful when running locally, don’t use this in prod).
<tls:context name=”tls.context.internal” doc:name=”TLS Context”>
<tls:trust-store path=”company-keystore.jks” password=”${internal.jks.password}” type=”jks” insecure=”true”/>
</tls:context>
|
HTTP Request Status Code Validator
By default the HTTP Request expects a 2xx status code from the target system, if there’s a different status code in the response it will throw an Exception. If you want to control different responses by adding some business logic, you have to configure the range of status codes considered as ‘valid’, by doing that you can put some logic after the HTTP Request, e.g. a Choice to take decisions based on the status code.
<http:request config-ref=“HTTP_Request_Configuration” ……>
<http:success-status-code-validator values=“200..599″/>
</http:request>
|
Web Service Consumer
- Import the wsdls and the xsds in your project
- Use the Webservice Consumer component and point it to the local wsdl
Database Connector
- Queries
- Use parameterized queries
- Use dynamic queries only if you don’t have another choice, remember to validate the inputs previously (using dynamic queries could cause SQL-Injection vulnerability https://www.owasp.org/index.php/SQL_Injection)
APIKit
- Use the APIKit features to generate the flows automatically
- Use the APIKit Exception Strategy to catch connector related exceptions
- It’s a good practice to disable the APIKit Console under all exposed environments (e.g. CloudHub environments, production -onPrem) as:
- If the API Console is used without caution, you can affect real objects/data due to the fact that you don’t have a ‘mocking-services’ option. When using API Portals (Exchange Public/Private Portal) you can enable mocking services.
- If an API Portal exists, the API Console is a redundancy.
- If there are no policies applied, the API Console is a risk, due to point #1.
- For more information:
Validator
- Use Validator instead of throwing exceptions with Groovy Scripts
- For more information:
Flows reusability
- Use Flow references to separate and reuse common logic. The flow diagram should be clear, showing the steps of the use case.
SSL
- Always use HTTPS listeners, if your applications are exposed on the internet or if you have internal security regulations. HTTPS can also be terminated at load balancer level when using Dedicated Load Balancer or where the user is hosting their own load balancer on-premises.
- In NYU, there is a Dedicated Load Balancer configured. HTTPS in listener in Mule applications is not mandatory because the SSL termination is done on the DLB.
- For more information:
Secure Application Properties
- Sensitive application properties such as access credentials and passwords can be obfuscated in CloudHub by using the Secure Application Properties feature.
- Such feature can be used in conjunction with the Mule Credentials Vault that allows users to encrypt properties within the application properties files.
- Use AES algorithm with a CBC mode.
- Define a 128 bits key, if you want to use a 256 bits key, the JCE Unlimited Strength Jurisdiction Policy Files need to be installed in each workstation
- For more information: Install the JCE Unlimited Strength Jurisdiction Policy
- For more information:
Java custom code/Scripting
- Only if there is no other choice.
Cache
- Use the Cache scope whenever possible, to wrap HTTP calls / flows / logic that obtain/produce information that doesn’t change frequently
- Define a ttl (time to live) based on an analysis, it shouldn’t be arbitrary
- For more information:
Unit and Integration Testing
- Create significative Unit tests using MUnit
- Create significative Integration tests using MUnit
Mule Deploy Maven Plugin
- Include the Mule Maven Deploy Plugin in each application
- Check the following how-to Mule Applications Configurations for CI/CD
Debugging & Troubleshooting
- Use Anypoint Studio Debugger to debug your Mule Applications.
Wire Logging
To enable a more detailed logging to see all the HTTP requests and responses, configure the following loggers in src/main/resources/log4j2.xml
<AsyncLogger name=”org.mule.module.http.internal.HttpMessageLogger” level=”DEBUG” />
<AsyncLogger name=”com.ning.http” level=”DEBUG” />
|