被测系统:Mule ESB 3.3.1 操作系统:CentOS 5.1 64 位四核 3 GHz 32 GB RAM
Mule ESB 只是拦截 SOAP 请求;验证有效令牌的 SOAP 请求并简单地将请求转发到托管 Web 服务的预定 Web 服务器。
当我们使用 SOAP UI 运行性能测试时,CPU 以每秒 10 个请求的速度非常快地达到 100%。
<spring:beans>
<spring:bean class="ca.mpac.soa.BAMNotificationListener" id="BAMNotificationListener"/>
<context:component-scan base-package="ca.mpac.soa"/>
<util:properties id="appProps" location="classpath:bedrock.properties"/>
</spring:beans>
<notifications>
<notification event="COMPONENT-MESSAGE"/> <notification-listener ref="BAMNotificationListener"/>
</notifications>
<context:property-placeholder location="bedrock.properties"/>
<object-to-string-transformer name="SecurityTokenResponseToString" doc:name="Object to String"/>
<custom-transformer name="WSDLTransformer" class="ca.mpac.soa.WSDLTransformer" doc:name="Java"/>
<flow name="bedrock" doc:name="bedrock">
<http:inbound-endpoint exchange-pattern="request-response" host="${proxy.host}" port="${proxy.port}" doc:name="proxy">
<not-filter>
<wildcard-filter pattern="/favicon.ico" caseSensitive="true"/>
</not-filter>
</http:inbound-endpoint>
<component class="ca.mpac.soa.HttpAccessLog" doc:name="HttpAccessLog"/>
<!-- <logger message="#[header:INBOUND:http.version] #[header:INBOUND:http.method] #[header:INBOUND:Host]#[header:INBOUND:http.request.path]?#[header:INBOUND:http.query.string] #[header:INBOUND:MULE_REMOTE_CLIENT_ADDRESS] #[header:INBOUND:User-Agent]" level="INFO" doc:name="Header Information" category="mule.http.accesslog"/> -->
<!-- logger message="Incoming request: #[payload]" level="INFO" doc:name="Incoming request"/> -->
<choice doc:name="Choice">
<when evaluator="groovy" expression="message.getInboundProperty('http.request.path')==~'^/rest/.*'">
<processor-chain>
<flow-ref name="REST" doc:name="REST Flow"/>
</processor-chain>
</when>
<when evaluator="groovy" expression="message.getInboundProperty('http.request.path')==~'^/soap/.*'">
<processor-chain>
<flow-ref name="SOAP" doc:name="SOAP Flow"/>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<flow-ref name="404NotFound" doc:name="404 Not Found"/>
</processor-chain>
</otherwise>
</choice>
</flow>
<sub-flow name="REST" doc:name="REST">
<!-- logger message="Launching REST Flow: #[payload]" level="INFO" doc:name="Launching REST Flow"/> -->
<choice doc:name="Choice">
<when evaluator="groovy" expression="message.getInboundProperty('http.request.path')==~'^/rest/security/gettoken$'">
<processor-chain>
<choice doc:name="Choice">
<when evaluator="header" expression="INBOUND:http.method=POST">
<processor-chain>
<mulexml:xml-to-object-transformer returnClass="ca.mpac.soa.ClientAuthenticationRequest" doc:name="XML to Object">
<mulexml:alias name="credential" class="ca.mpac.soa.ClientAuthenticationRequest"/>
</mulexml:xml-to-object-transformer>
<!-- logger message="Accessing to ${openam.host}:${openam.port}/openam/identity/authenticate?username=#[payload.username]&password=#[payload.password]&uri=realm=${openam.realm}" level="INFO" doc:name="Accessing to URL"/> -->
<http:outbound-endpoint exchange-pattern="request-response" host="${openam.host}" port="${openam.port}" path="openam/identity/authenticate?username=#[payload.username]&password=#[payload.password]&uri=realm=${openam.realm}" method="GET" responseTransformer-refs="SecurityTokenResponseToString" doc:name="OpenAM Get Token"/>
<choice doc:name="Choice">
<when evaluator="header" expression="INBOUND:http.status=200">
<processor-chain>
<logger message="Getting Token: #[payload]" level="INFO" doc:name="Getting Token"/>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<!-- <logger message="401 Access Denied: Invalid Account Information" level="INFO" doc:name="401 Access Denied"/> -->
<set-payload value="401 Access Denied: Invalid Account Information" doc:name="401 Access Denied" />
<http:response-builder status="401" doc:name="HTTP 401" contentType="text/plain"/>
</processor-chain>
</otherwise>
</choice>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<flow-ref name="405MethodNotAllowed" doc:name="405 Method Not Allowed"/>
</processor-chain>
</otherwise>
</choice>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<flow-ref name="404NotFound" doc:name="404 Not Found"/>
</processor-chain>
</otherwise>
</choice>
</sub-flow>
<sub-flow name="SOAP" doc:name="SOAP">
<!-- <logger message="Launching SOAP Flow: #[payload]" level="INFO" doc:name="Launching SOAP Flow"/> -->
<choice doc:name="Choice">
<when evaluator="groovy" expression="message.getInboundProperty('http.request')==~'^/soap/BuildingPermitService/v1/BuildingPermit\\?.*'">
<processor-chain>
<choice doc:name="Choice">
<when evaluator="header" expression="INBOUND:http.method=GET">
<processor-chain>
<!-- <logger message="Accessing to ${bpe.host}:${bpe.port}#[header:INBOUND:http.request.path]?#[header:INBOUND:http.query.string]" level="INFO" doc:name="Accessing to URL"/> -->
<http:outbound-endpoint exchange-pattern="request-response" address="http://${bpe.host}:${bpe.port}#[header:INBOUND:http.request.path]?#[header:INBOUND:http.query.string]" method="GET" doc:name="SOAP Service" responseTransformer-refs="WSDLTransformer"/>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<flow-ref name="405MethodNotAllowed" doc:name="405 Method Not Allowed"/>
</processor-chain>
</otherwise>
</choice>
</processor-chain>
</when>
<when evaluator="groovy" expression="message.getInboundProperty('http.request')==~'^/soap/BuildingPermitService/v1/BuildingPermit$'">
<processor-chain>
<choice doc:name="Choice">
<when evaluator="header" expression="INBOUND:http.method=POST">
<processor-chain>
<component class="ca.mpac.soa.HttpRequestToAuthorization" doc:name="HttpRequest To Authorization"/>
<choice doc:name="Choice">
<when evaluator="header" expression="INVOCATION:authResult=true">
<processor-chain>
<!--
<logger message="Accessing to ${bpe.host}:${bpe.port}#[header:INBOUND:http.request]" level="INFO" doc:name="Accessing to URL"/>
<component class="ca.mpac.soa.SoapRequest" doc:name="SOAP Request"/>
<http:outbound-endpoint exchange-pattern="request-response" address="http://${bpe.host}:${bpe.port}#[header:INBOUND:http.request]" doc:name="SOAP Service" >
<cxf:proxy-client payload="envelope" />
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</http:outbound-endpoint>
-->
<http:outbound-endpoint exchange-pattern="request-response" address="http://${bpe.host}:${bpe.port}/soap/BuildingPermitService/v1/BuildingPermit" doc:name="SOAP Service" >
<cxf:proxy-client payload="envelope" />
<!-- <logger message="#[payload]" level="INFO" doc:name="Logger"/> -->
</http:outbound-endpoint>
<!-- <logger message="Discovered an Authorization Request" level="INFO" doc:name="Discovered an Authorization Request"/> -->
</processor-chain>
</when>
<when evaluator="header" expression="INVOCATION:authResult=false">
<processor-chain>
<logger message="403 Authorization Failure" level="INFO" doc:name="403 Authorization Failure"/>
<expression-component doc:name="403 AuthorizationFailure"><![CDATA[
message.payload = '<?xml version=\'1.0\' encoding=\'UTF-8\'?>'
+ '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'
+ '<soap:Body>'
+ '<soap:Fault>'
+ '<faultcode>soap:Server</faultcode>'
+ '<faultstring>A security fault has occured</faultstring>'
+ '<detail>'
+ '<ns2:securityFault xmlns:ns3="http://services.mpac.ca/soap/security/v1.0/schema" xmlns:ns2="http://services.mpac.ca/soap/common/faulttypes/v1.0/schema" xmlns="http://services.mpac.ca/soap/buildingpermit/v1.0/schema">'
+ '<ns2:name>AuthorizationFailure</ns2:name>'
+ '<ns2:status>403</ns2:status>'
+ '<ns2:reason>Client is unauthorized to use this service | please contact your MPAC representative</ns2:reason>'
+ '</ns2:securityFault>'
+ '</detail>'
+ '</soap:Fault>'
+ '</soap:Body>'
+ '</soap:Envelope>';
]]></expression-component>
<http:response-builder status="403" doc:name="HTTP 403" contentType="text/xml"/>
</processor-chain>
</when>
<when evaluator="header" expression="INVOCATION:authResult=401">
<processor-chain>
<logger message="401 Access Denied: Invalid Token" level="INFO" doc:name="401 Access Denied"/>
<expression-component doc:name="401 Access Denied: AuthenticationFailed"><![CDATA[
message.payload = '<?xml version=\'1.0\' encoding=\'UTF-8\'?>'
+ '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'
+ '<soap:Body>'
+ '<soap:Fault>'
+ '<faultcode>soap:Server</faultcode>'
+ '<faultstring>A security fault has occured</faultstring>'
+ '<detail>'
+ '<ns2:securityFault xmlns:ns3="http://services.mpac.ca/soap/security/v1.0/schema" xmlns:ns2="http://services.mpac.ca/soap/common/faulttypes/v1.0/schema" xmlns="http://services.mpac.ca/soap/buildingpermit/v1.0/schema">'
+ '<ns2:name>AuthenticationFailed</ns2:name>'
+ '<ns2:status>401</ns2:status>'
+ '<ns2:reason>Client authentication has failed | please contact your MPAC representative</ns2:reason>'
+ '</ns2:securityFault>'
+ '</detail>'
+ '</soap:Fault>'
+ '</soap:Body>'
+ '</soap:Envelope>';
]]></expression-component>
<http:response-builder status="401" doc:name="HTTP 401" contentType="text/xml"/>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<component class="ca.mpac.soa.SoapActionErrorLog" doc:name="SoapActionErrorLog"/>
<http:response-builder status="400" doc:name="HTTP 400" contentType="text/plain"/>
</processor-chain>
</otherwise>
</choice>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<flow-ref name="405MethodNotAllowed" doc:name="405 Method Not Allowed"/>
</processor-chain>
</otherwise>
</choice>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<flow-ref name="404NotFound" doc:name="404 Not Found"/>
</processor-chain>
</otherwise>
</choice>
</sub-flow>
<sub-flow name="404NotFound" doc:name="404NotFound">
<logger message="404 Not Found: #[header:INBOUND:http.request]" level="INFO" doc:name="404 Not Found"/>
<set-payload value="404 Not Found" doc:name="404 Not Found" />
<http:response-builder status="404" doc:name="HTTP 404" contentType="text/plain"/>
</sub-flow>
<sub-flow name="405MethodNotAllowed" doc:name="405MethodNotAllowed">
<logger message="405 Method Not Allowed: #[header:INBOUND:http.method]" level="INFO" doc:name="405 Method Not Allowed"/>
<set-payload value="405 Method Not Allowed" doc:name="405 Method Not Allowed" />
<http:response-builder status="405" doc:name="HTTP 405" contentType="text/plain"/>
</sub-flow>