A lookup chapter. Use this when you remember the shape of what you need but not the exact syntax: ports, default URLs, CLI flags, XML skeletons, error codes, and common fixes.
Overview
The earlier chapters teach concepts in order; this one is alphabet soup arranged for grep. Bookmark the port and URL tables first, then the deployment.toml block. Everything else slots in around them.
Default Ports
| Service | HTTP | HTTPS | Notes |
|---|
| Carbon Management Console | 9763 | 9443 | /carbon |
| API Gateway (NIO) | 8280 | 8243 | API traffic |
| API Publisher Portal | n/a | 9443 | /publisher |
| API Developer Portal | n/a | 9443 | /devportal |
| API Admin Portal | n/a | 9443 | /admin |
| Micro Integrator | 8290 | 8253 | Integration runtime |
| MI Management API | n/a | 9164 | MI admin operations |
| Identity Server | 9763 | 9443 | /carbon |
| Streaming Integrator | 9090 | 9443 | Siddhi runtime |
| JMX RMI | 11111 | n/a | JVM monitoring |
| Thrift (Analytics) | 7611 | 7711 | Event receivers |
Port Offset: If running multiple products on one host, set [server] offset in deployment.toml. All ports shift by that offset (e.g., offset=1 makes 9443 become 9444).
[server]
offset = 1
Default Credentials
| Component | Username | Password | Notes |
|---|
| Carbon Console | admin | admin | Super admin |
| API Publisher | admin | admin | Same as carbon |
| API DevPortal | admin | admin | Same as carbon |
| MI Management API | admin | admin | Basic auth |
| H2 Database Console | wso2carbon | wso2carbon | Embedded DB |
| Identity Server | admin | admin | Super admin |
Change admin password (deployment.toml):
[super_admin]
username = "admin"
password = "newStrongPassword123"
create_admin_account = true
Useful URLs
| URL | Purpose |
|---|
https://localhost:9443/carbon | Management Console |
https://localhost:9443/publisher | API Publisher |
https://localhost:9443/devportal | Developer Portal |
https://localhost:9443/admin | Admin Portal |
https://localhost:9164/management | MI Management API |
https://localhost:9443/oauth2/token | OAuth2 Token endpoint |
https://localhost:9443/oauth2/authorize | OAuth2 Authorization endpoint |
https://localhost:9443/oauth2/revoke | OAuth2 Revoke endpoint |
https://localhost:9443/oauth2/introspect | Token introspection |
https://localhost:9443/.well-known/openid-configuration | OIDC Discovery |
https://localhost:8243/ | Gateway HTTPS base |
http://localhost:8280/ | Gateway HTTP base |
CLI Commands
API Manager CLI (apictl)
# Initialize environment
apictl add env dev --apim https://localhost:9443
apictl add env prod --apim https://prod-apim:9443
# Login
apictl login dev -u admin -p admin
apictl login dev # interactive prompt
# List APIs
apictl list apis -e dev
# Export an API
apictl export api -n PetStoreAPI -v 1.0.0 -e dev
# Creates: PetStoreAPI_1.0.0.zip
# Import an API
apictl import api -f PetStoreAPI_1.0.0.zip -e prod
# Export/Import all APIs
apictl export apis -e dev --all
apictl import apis -f exported/ -e prod
# Delete an API
apictl delete api -n PetStoreAPI -v 1.0.0 -e dev
# List applications
apictl list apps -e dev -o admin
# API Projects (source-controlled)
apictl init MyAPI --oas https://petstore.swagger.io/v2/swagger.json
apictl import api -f MyAPI/ -e dev
# Get API keys for testing
apictl get keys -n PetStoreAPI -v 1.0.0 -e dev
# Logout
apictl logout dev
Micro Integrator CLI (mi)
# Remote login
mi remote add dev https://localhost:9164
mi remote login dev -u admin -p admin
# Manage artifacts
mi api show -e dev # List all APIs
mi api show OrderAPI -e dev # Show specific API details
mi proxyservice show -e dev # List proxy services
mi endpoint show -e dev # List endpoints
mi sequence show -e dev # List sequences
mi inboundendpoint show -e dev # List inbound endpoints
mi messagestore show -e dev # List message stores
mi messageprocessor show -e dev # List message processors
# Activate/deactivate
mi api activate OrderAPI -e dev
mi api deactivate OrderAPI -e dev
mi messageprocessor activate OrderProcessor -e dev
mi messageprocessor deactivate OrderProcessor -e dev
mi proxyservice activate MyProxy -e dev
# Log levels
mi log-level show org.apache.synapse -e dev
mi log-level update org.apache.synapse DEBUG -e dev
# Data services
mi dataservice show -e dev
# Connectors
mi connector show -e dev
# Users
mi user show -e dev
mi user add newuser newpassword -e dev
Server Commands
# Start servers
./bin/api-manager.sh # API Manager
./bin/micro-integrator.sh # Micro Integrator
./bin/wso2server.sh # Identity Server
# Start in background
./bin/api-manager.sh start
./bin/api-manager.sh stop
./bin/api-manager.sh restart
# Start with debug
./bin/api-manager.sh -debug 5005 # Remote debug on port 5005
# Start in OSGi console mode
./bin/api-manager.sh -DosgiConsole
# Check version
./bin/api-manager.sh version
# Clean temp files before start
./bin/api-manager.sh -Dclean
Common XML Configurations
API Definition
<api name="CustomerAPI" context="/customers" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" uri-template="/{id}">
<inSequence>
<call>
<endpoint>
<http method="get" uri-template="http://backend:8080/api/customers/{uri.var.id}"/>
</endpoint>
</call>
<respond/>
</inSequence>
<faultSequence>
<sequence key="commonFaultHandler"/>
</faultSequence>
</resource>
<resource methods="POST">
<inSequence>
<call>
<endpoint>
<http method="post" uri-template="http://backend:8080/api/customers"/>
</endpoint>
</call>
<respond/>
</inSequence>
</resource>
</api>
Proxy Service
<proxy name="LegacyOrderProxy" startOnLoad="true" transports="http https"
xmlns="http://ws.apache.org/ns/synapse">
<target>
<inSequence>
<log level="full"/>
<call>
<endpoint>
<address uri="http://legacy-system:9000/services/OrderService"/>
</endpoint>
</call>
<respond/>
</inSequence>
<faultSequence>
<log level="custom">
<property name="error" expression="get-property('ERROR_MESSAGE')"/>
</log>
</faultSequence>
</target>
</proxy>
Endpoint Types
<!-- Simple HTTP endpoint -->
<endpoint name="SimpleHTTP" xmlns="http://ws.apache.org/ns/synapse">
<http method="get" uri-template="http://backend:8080/api/resource"/>
</endpoint>
<!-- Address endpoint (SOAP/REST) -->
<endpoint name="AddressEP" xmlns="http://ws.apache.org/ns/synapse">
<address uri="http://backend:8080/service">
<suspendOnFailure>
<initialDuration>30000</initialDuration>
<progressionFactor>2</progressionFactor>
<maximumDuration>120000</maximumDuration>
<errorCodes>101500,101501,101506,101507,101508</errorCodes>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>3</retriesBeforeSuspension>
<retryDelay>1000</retryDelay>
<errorCodes>101500,101501</errorCodes>
</markForSuspension>
<timeout>
<duration>30000</duration>
<responseAction>fault</responseAction>
</timeout>
</address>
</endpoint>
<!-- Load Balance endpoint -->
<endpoint name="LoadBalanceEP" xmlns="http://ws.apache.org/ns/synapse">
<loadbalance algorithm="org.apache.synapse.endpoints.algorithms.RoundRobin">
<endpoint>
<address uri="http://backend1:8080/service"/>
</endpoint>
<endpoint>
<address uri="http://backend2:8080/service"/>
</endpoint>
<endpoint>
<address uri="http://backend3:8080/service"/>
</endpoint>
</loadbalance>
</endpoint>
<!-- Failover endpoint -->
<endpoint name="FailoverEP" xmlns="http://ws.apache.org/ns/synapse">
<failover>
<endpoint>
<address uri="http://primary:8080/service"/>
</endpoint>
<endpoint>
<address uri="http://secondary:8080/service"/>
</endpoint>
</failover>
</endpoint>
Scheduled Task
<task name="CleanupTask"
class="org.apache.synapse.startup.tasks.MessageInjector"
group="synapse.simple.quartz"
xmlns="http://ws.apache.org/ns/synapse">
<trigger interval="3600"/> <!-- every hour -->
<property name="injectTo" value="sequence"/>
<property name="sequenceName" value="cleanupSequence"/>
<property name="message">
<request xmlns="">
<action>cleanup</action>
</request>
</property>
</task>
Data Service
<data name="EmployeeDataService" transports="http https"
xmlns="http://ws.wso2.org/ns/dataservice">
<config id="MySQLConnection">
<property name="driverClassName">com.mysql.cj.jdbc.Driver</property>
<property name="url">jdbc:mysql://localhost:3306/employees</property>
<property name="username">db_user</property>
<property name="password">db_pass</property>
</config>
<query id="GetEmployeeQuery" useConfig="MySQLConnection">
<sql>SELECT id, name, email, department FROM employees WHERE id = :id</sql>
<param name="id" sqlType="INTEGER" paramType="SCALAR"/>
<result element="employee" rowName="">
<element name="id" column="id" xsdType="integer"/>
<element name="name" column="name" xsdType="string"/>
<element name="email" column="email" xsdType="string"/>
<element name="department" column="department" xsdType="string"/>
</result>
</query>
<resource method="GET" path="/employees/{id}">
<call-query href="GetEmployeeQuery">
<with-param name="id" query-param="id"/>
</call-query>
</resource>
</data>
REST API Calls (curl)
OAuth2 Token Generation
# Client credentials grant
curl -k -X POST https://localhost:9443/oauth2/token \
-H "Authorization: Basic $(echo -n 'clientId:clientSecret' | base64)" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials"
# Password grant
curl -k -X POST https://localhost:9443/oauth2/token \
-H "Authorization: Basic $(echo -n 'clientId:clientSecret' | base64)" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password&username=admin&password=admin"
# Refresh token
curl -k -X POST https://localhost:9443/oauth2/token \
-H "Authorization: Basic $(echo -n 'clientId:clientSecret' | base64)" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token&refresh_token=<refresh_token>"
# Token introspection
curl -k -X POST https://localhost:9443/oauth2/introspect \
-H "Authorization: Basic $(echo -n 'admin:admin' | base64)" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token=<access_token>"
API Manager REST APIs
# Register a client for Admin REST API
curl -k -X POST https://localhost:9443/client-registration/v0.17/register \
-H "Authorization: Basic $(echo -n 'admin:admin' | base64)" \
-H "Content-Type: application/json" \
-d '{
"callbackUrl": "www.google.lk",
"clientName": "rest_api_admin",
"owner": "admin",
"grantType": "password refresh_token",
"saasApp": true
}'
# List all APIs (Publisher)
curl -k -X GET "https://localhost:9443/api/am/publisher/v4/apis" \
-H "Authorization: Bearer <access_token>"
# Get specific API
curl -k -X GET "https://localhost:9443/api/am/publisher/v4/apis/<api-id>" \
-H "Authorization: Bearer <access_token>"
# List subscriptions (DevPortal)
curl -k -X GET "https://localhost:9443/api/am/devportal/v3/subscriptions?apiId=<api-id>" \
-H "Authorization: Bearer <access_token>"
# Create an application (DevPortal)
curl -k -X POST "https://localhost:9443/api/am/devportal/v3/applications" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "TestApp",
"throttlingPolicy": "Unlimited",
"description": "Test application"
}'
Micro Integrator Management API
MI_URL="https://localhost:9164/management"
# Login and get token
TOKEN=$(curl -sk -X GET "$MI_URL/login" \
-H "Authorization: Basic $(echo -n 'admin:admin' | base64)" | jq -r '.AccessToken')
# List APIs
curl -sk -X GET "$MI_URL/apis" \
-H "Authorization: Bearer $TOKEN"
# Get specific API details
curl -sk -X GET "$MI_URL/apis?apiName=OrderAPI" \
-H "Authorization: Bearer $TOKEN"
# List endpoints
curl -sk -X GET "$MI_URL/endpoints" \
-H "Authorization: Bearer $TOKEN"
# List sequences
curl -sk -X GET "$MI_URL/sequences" \
-H "Authorization: Bearer $TOKEN"
# List message stores
curl -sk -X GET "$MI_URL/message-stores" \
-H "Authorization: Bearer $TOKEN"
# List message processors
curl -sk -X GET "$MI_URL/message-processors" \
-H "Authorization: Bearer $TOKEN"
# Activate/deactivate message processor
curl -sk -X POST "$MI_URL/message-processors" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "OrderProcessor", "status": "active"}'
# List inbound endpoints
curl -sk -X GET "$MI_URL/inbound-endpoints" \
-H "Authorization: Bearer $TOKEN"
# Get server logs
curl -sk -X GET "$MI_URL/logs?file=wso2carbon" \
-H "Authorization: Bearer $TOKEN"
# Update log level
curl -sk -X PATCH "$MI_URL/logging" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"loggerName": "org.apache.synapse", "loggingLevel": "DEBUG"}'
deployment.toml Quick Reference
# ─── Server ───────────────────────────────
[server]
hostname = "apim.example.com"
offset = 0
[super_admin]
username = "admin"
password = "admin"
create_admin_account = true
# ─── Database ─────────────────────────────
[database.apim_db]
type = "mysql"
url = "jdbc:mysql://db-host:3306/apim_db?useSSL=false"
username = "apim_user"
password = "apim_pass"
driver = "com.mysql.cj.jdbc.Driver"
[database.apim_db.pool_options]
maxActive = 50
maxWait = 60000
testOnBorrow = true
validationQuery = "SELECT 1"
validationInterval = 30000
[database.shared_db]
type = "mysql"
url = "jdbc:mysql://db-host:3306/shared_db?useSSL=false"
username = "shared_user"
password = "shared_pass"
driver = "com.mysql.cj.jdbc.Driver"
# ─── Keystore ─────────────────────────────
[keystore.primary]
file_name = "wso2carbon.jks"
password = "wso2carbon"
alias = "wso2carbon"
key_password = "wso2carbon"
[keystore.tls]
file_name = "server.jks"
password = "changeit"
alias = "server"
key_password = "changeit"
[truststore]
file_name = "client-truststore.jks"
password = "wso2carbon"
# ─── Gateway ──────────────────────────────
[[apim.gateway.environment]]
name = "Production"
type = "production"
service_url = "https://gateway:9443/services/"
ws_endpoint = "ws://gateway:9099"
wss_endpoint = "wss://gateway:8099"
http_endpoint = "http://gateway:8280"
https_endpoint = "https://gateway:8243"
# ─── Traffic Manager ─────────────────────
[apim.throttling]
enable_data_publishing = true
service_url = "https://traffic-manager:9443/services/"
throttle_decision_endpoints = ["tcp://traffic-manager:5672"]
# ─── CORS ─────────────────────────────────
[apim.cors]
allow_origins = "*"
allow_methods = ["GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"]
allow_headers = ["Authorization", "Content-Type", "X-Requested-With"]
allow_credentials = false
# ─── JWT ──────────────────────────────────
[apim.jwt]
enable = true
encoding = "base64"
header = "X-JWT-Assertion"
claims_extractor_impl = "org.wso2.carbon.apimgt.impl.token.DefaultClaimsRetriever"
# ─── Caching ──────────────────────────────
[apim.cache.gateway_token]
enable = true
expiry_time = "900s"
[apim.cache.resource]
enable = true
expiry_time = "900s"
# ─── Analytics ────────────────────────────
[apim.analytics]
enable = true
type = "elk"
[apim.analytics.elk]
host = "elasticsearch:9200"
Error Codes
Transport Error Codes
| Code | Meaning | Common Cause |
|---|
| 101000 | Receiver I/O error | Backend refused connection |
| 101001 | Receiver I/O timeout | Backend too slow to accept |
| 101500 | Sender I/O error | Cannot write to backend |
| 101501 | Sender I/O timeout | Backend didn't respond in time |
| 101503 | Connection failed | DNS or network issue |
| 101504 | Connection timed out | Firewall or backend down |
| 101505 | Connection closed | Backend dropped connection |
| 101506 | Protocol violation | Malformed HTTP response |
| 101507 | Connect cancel | Connection attempt cancelled |
| 101508 | Connect timeout | TCP handshake timeout |
| 101509 | Send abort | Send operation aborted |
Synapse Error Codes
| Code | Meaning | Common Cause |
|---|
| 0 | Unexpected error | Unclassified |
| 303000 | Failure sending using PT | Passthrough transport send failure |
| 303001 | Connecting to backend | Backend unreachable |
| 303100 | Connection timeout | Response waited too long |
| 304000 | Receiving response | Malformed response from backend |
<!-- Read the backend's HTTP status code -->
<property name="backendStatus" expression="$axis2:HTTP_SC"/>
<!-- Set a specific HTTP status code for the response -->
<property name="HTTP_SC" value="201" scope="axis2"/>
<!-- Common status codes to set -->
<!-- 200 OK (default) | 201 Created | 202 Accepted | 204 No Content -->
<!-- 400 Bad Request | 401 Unauthorized | 403 Forbidden | 404 Not Found -->
<!-- 500 Internal Error | 502 Bad Gateway | 503 Service Unavailable -->
Troubleshooting
Server Won't Start
# Check port conflicts
netstat -tlnp | grep -E '(9443|8280|8243)'
# Check Java version (requires JDK 11 or 17)
java -version
# Check JAVA_HOME
echo $JAVA_HOME
# Review startup log
tail -200 repository/logs/wso2carbon.log
# Check for lock files
ls -la repository/components/default/configuration/org.eclipse.equinox.simpleconfigurator/.lock
# Clean and restart
rm -rf repository/deployment/server/webapps/ # will be regenerated
./bin/api-manager.sh -Dclean
API Returns 401 Unauthorized
# Check if token is valid
curl -k -X POST https://localhost:9443/oauth2/introspect \
-H "Authorization: Basic $(echo -n 'admin:admin' | base64)" \
-d "token=<your_token>"
# Check if API is published (not just CREATED)
apictl list apis -e dev
# Verify subscription exists
apictl list api-products -e dev
# Check token type matches (API key vs OAuth2 vs JWT)
# Ensure Authorization header format: "Bearer <token>"
Backend Connection Failures
# Test backend connectivity from WSO2 host
curl -v http://backend-host:8080/health
# Check DNS resolution
nslookup backend-host
# Enable wire logs temporarily
# In deployment.toml:
# [[logging.loggers]]
# name = "org.apache.synapse.transport.http.wire"
# level = "DEBUG"
# Check endpoint status via MI CLI
mi endpoint show BackendEndpoint -e dev
High Memory Usage
# Check current heap settings
ps aux | grep wso2 | grep -o 'Xm[sx][^ ]*'
# Tune JVM in bin/api-manager.sh or bin/micro-integrator.sh
# -Xms512m -Xmx2048m (min/max heap)
# -XX:MaxMetaspaceSize=512m
# Take a heap dump for analysis
jmap -dump:format=b,file=heap.hprof <PID>
# Take a thread dump
jstack <PID> > threads.txt
# Monitor GC
tail -f repository/logs/gc.log
<!-- Debug: Log the full message at each step -->
<log level="full"/>
<!-- Debug: Log specific expressions -->
<log level="custom">
<property name="debug-payload" expression="json-eval($)"/>
<property name="debug-status" expression="$axis2:HTTP_SC"/>
<property name="debug-content-type" expression="get-property('ContentType')"/>
</log>
<!-- Common issue: wrong content type -->
<property name="messageType" value="application/json" scope="axis2"/>
<property name="ContentType" value="application/json" scope="axis2"/>
<!-- Common issue: empty body after call mediator -->
<!-- Ensure the backend returns a body; check for 204 No Content -->
File System Layout
wso2am-4.2.0/
├── bin/ # Startup scripts
│ ├── api-manager.sh # Main startup
│ ├── micro-integrator.sh # MI startup
│ └── ciphertool.sh # Password encryption
├── repository/
│ ├── conf/
│ │ └── deployment.toml # Main configuration
│ ├── deployment/
│ │ └── server/
│ │ ├── synapse-configs/ # Mediation artifacts
│ │ │ └── default/
│ │ │ ├── api/ # API definitions
│ │ │ ├── endpoints/
│ │ │ ├── sequences/
│ │ │ ├── proxy-services/
│ │ │ └── tasks/
│ │ ├── carbonapps/ # Deployable CARs
│ │ └── webapps/ # Web applications
│ ├── components/
│ │ ├── lib/ # Third-party JARs (JDBC, etc.)
│ │ └── dropins/ # OSGi bundles
│ ├── database/ # Embedded H2 databases
│ ├── logs/ # All log files
│ └── resources/
│ └── security/
│ ├── wso2carbon.jks # Primary keystore
│ └── client-truststore.jks
├── docker-compose.yml # Docker deployment (if bundled)
└── updates/ # WSO2 Updates metadata
Expression Quick Reference
JSON Path Expressions
| Expression | Description |
|---|
json-eval($.name) | Root-level field |
json-eval($.user.address.city) | Nested field |
json-eval($.items[0]) | First array element |
json-eval($.items[*].name) | All names from array |
json-eval($.items.length()) | Array length |
XPath Expressions
| Expression | Description |
|---|
//element | Select element anywhere |
//element/@attr | Select attribute |
//ns:element | Namespace-qualified element |
//element[1] | First matching element |
//element[last()] | Last matching element |
count(//item) | Count of elements |
Property Access
| Expression | Description |
|---|
$ctx:propertyName | Default (synapse) scope |
$trp:headerName | Transport header |
$axis2:propertyName | Axis2 scope |
get-property('name') | Default scope |
get-property('transport', 'name') | Transport scope |
get-property('axis2', 'name') | Axis2 scope |
get-property('operation', 'name') | Operation scope |
get-property('registry', 'path') | Registry resource |
get-property('system', 'key') | Java system property |
get-property('SYSTEM_TIME') | Current timestamp |
get-property('MESSAGE_ID') | Message UUID |
URI Template Variables
| Pattern | In Endpoint | Access |
|---|
/{id} in resource | {uri.var.id} | get-property('uri.var.id') |
?name=val query param | n/a | get-property('query.param.name') |
Docker Quick Start
# docker-compose.yml: minimal WSO2 APIM + MI
version: '3.8'
services:
apim:
image: wso2/wso2am:4.2.0
ports:
- "9443:9443"
- "8280:8280"
- "8243:8243"
volumes:
- ./conf/deployment.toml:/home/wso2carbon/wso2am-4.2.0/repository/conf/deployment.toml
healthcheck:
test: ["CMD", "curl", "-k", "https://localhost:9443/carbon/admin/login.jsp"]
interval: 30s
timeout: 10s
retries: 5
mi:
image: wso2/wso2mi:4.2.0
ports:
- "8290:8290"
- "8253:8253"
- "9164:9164"
volumes:
- ./carbonapps:/home/wso2carbon/wso2mi-4.2.0/repository/deployment/server/carbonapps
depends_on:
apim:
condition: service_healthy
# Build and deploy a CAPP from Integration Studio
# 1. Export CompositeExporter as .car file
# 2. Copy to carbonapps volume
cp MyIntegration_1.0.0.car ./carbonapps/
# MI hot-deploys automatically; verify:
curl -sk https://localhost:9164/management/apis \
-H "Authorization: Basic $(echo -n 'admin:admin' | base64)"
Common Patterns Cheat Sheet
| I want to... | Use |
|---|
| Transform JSON payload | <payloadFactory media-type="json"> |
| Transform XML payload | <payloadFactory media-type="xml"> or <xslt> |
| Route by content | <switch source="json-eval($.field)"> |
| Route by header | <filter source="get-property('transport','X-Type')"> |
| Call backend and continue | <call> (non-blocking) |
| Call backend and wait | <callout> (blocking) |
| Fan out to N backends | <clone> with N <target> blocks |
| Split array, process each | <iterate expression="json-eval($.items)"> |
| Merge parallel results | <aggregate> after <clone> |
| Async fire-and-forget | <property name="OUT_ONLY" value="true"/> + <call> |
| Queue for guaranteed delivery | <store messageStore="MyStore"/> |
| Set response status code | <property name="HTTP_SC" value="201" scope="axis2"/> |
| Add response header | <property name="X-Custom" value="val" scope="transport"/> |
| Log for debugging | <log level="full"/> or <log level="custom"> |
| Handle errors | <faultSequence> with get-property('ERROR_MESSAGE') |
| Schedule a recurring job | <task> with <trigger interval="N"/> |
| Expose a database as REST | Data Service (.dbs artifact) |
| Validate JSON schema | <validate> with JSON Schema resource |
Key Takeaways
- Bookmark the port and URL tables: you will reference them constantly
- Use
apictl for API lifecycle and mi CLI for integration artifact management - The MI Management REST API provides programmatic access to everything the CLI can do
deployment.toml is the single configuration file for all product settings- Transport error codes (101xxx) indicate network-level issues; Synapse codes (303xxx/304xxx) indicate mediation issues
- Wire logs are your best friend for debugging but must be disabled in production
- Expression syntax (json-eval, XPath, property access) is the foundation of all mediation logic
Where to Go From Here
You have read enough WSO2 to start building real things. Pick the path that matches your role:
- API platform owner: stand up an API Manager cluster behind a load balancer, integrate it with WSO2 Identity Server, and put
apictl in a CI pipeline so APIs flow from dev to production through Git. - Integration developer: build a Composite Application of three or four real APIs with mediation, deploy it to Micro Integrator on Kubernetes, and wire correlation logging through to Grafana.
- Identity engineer: federate Identity Server with at least one external IdP (Google, Azure AD, or Okta), enable adaptive MFA based on risk, and write a custom authenticator script.
External resources worth bookmarking:
When something breaks in production: read the correlation log first, the wire log second, and the JVM stats third. The fix is almost always somewhere in the first three minutes of those.