trafficparrot.virtualservice.httpRequestLoggingDisabled=true trafficparrot.virtualservice.accessLogsEnabled=false trafficparrot.virtualservice.handlebars.maxCacheEntries=10000
trafficparrot.openapi.import.on.startup=true
{{jwt maxAge='12 days'}}
{{jwt exp=(parseDate '2041-02-23T21:22:23Z')}}
{{jwt nbf=(parseDate '2019-02-23T21:22:23Z')}}
{{jwt iss='https://issuer.trafficparrot.com/'}}
{{jwt aud='https://audience.trafficparrot.com/'}}
{{jwt sub='subject'}}
{{jwt alg='RS256'}}
{{jwt
customBoolClaim=true
customIntClaim=23
customStringClaim='example@x.y.z'
customDateClaim=(parseDate '2024-01-02T03:04:05Z')
}}
{{jwks}}{
"settings" : {
"extended" : {
"jwt" : {
"hs256Secret" : "...",
"rs256PublicKeyId" : "...",
"rs256PublicKey" : "-----BEGIN RSA PUBLIC KEY-----\n...\n-----END RSA PUBLIC KEY-----\n",
"rs256PrivateKey" : "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----\n"
}
}
}
}
trafficparrot.http.jwt.enabled=true
curl -v http://localhost:8080/thrift/management/sendThriftMessage -d send-mapping-id=fc7ee4ad-e247-49a8-8528-af20845adde9 -d send-to-host-port=localhost:5562
"postServeActions" : [ {
"name" : "send-jms-message",
"parameters" : {
"jmsConnectionId" : "(connection id from jms-connections.json)",
"destination" : {
"name" : "queue-name",
"type" : "QUEUE"
},
"variables" : {
"id" : "{{randomValue length=24 type='ALPHANUMERIC'}}"
},
"properties" : {
"id" : "{{variables.id}}"
},
"jsonBody" : {
"id" : "{{variables.id}}",
"fieldFromRequest" : "{{originalRequest.jsonBody.requestField}}",
"fieldFromResponse" : "{{originalResponse.jsonBody.responseField}}"
},
"delayDistribution" : {
"type" : "fixed",
"milliseconds" : 500
}
}
} ]trafficparrot.http.optionsResponse.enabled=true
trafficparrot.gui.forwardToVirtualService.enabled=true
trafficparrot.okta.enabled=false
trafficparrot.okta.clientId=some_client_id
trafficparrot.okta.clientSecret=some_client_secret
trafficparrot.okta.oktaAuthorizeUri=https://${yourOktaDomain}/oauth2/default/v1/authorize
trafficparrot.okta.oktaTokenUri=https://${yourOktaDomain}/oauth2/default/v1/token
trafficparrot.okta.oktaIssuerUri=https://${yourOktaDomain}/oauth2/default
trafficparrot.okta.oktaAudience=api://default
trafficparrot.okta.oktaRedirectUri=https://some-TP-deployment-uri
trafficparrot.virtualservice.containerThreads=100
{{#if (jsonPath request.body '$.[?(@.field)]') }}field is present{{/if}}
{{#if (not (jsonPath request.body '$.[?(@.field)]') ) }}field is not present{{/unless}}
{{#if (jsonPath request.body '$.[?(!(@.field))]') }}field is not present{{/unless}}
{{#unless (jsonPath request.body '$.[?(@.field)]') }}field is not present{{/unless}}
{
"connectionId": "couchbase.db",
"type": "COUCHBASE_CONNECTION",
"connectionString": "couchbase://localhost:32784",
"username": "Administrator",
"password": "password",
"warmupQuery": "SELECT COUNT(*) FROM bucket_a UNION SELECT COUNT(*) FROM bucket_b",
"enableDnsSrv": true,
"networkResolution": "auto"
}
# OFF will turn off validation # DEFAULT_VALIDATION will turn on validation and provide default responses when not annotated # ONLY_ANNOTATED will turn on validation only for annotated specifications trafficparrot.openapi.request.validation.mode=OFF
paths:
/items:
get:
parameters:
# standard OpenAPI parameters with schema definitions
responses:
'400':
content:
application/json:
schema:
# standard OpenAPI response schema definition
x-traffic-parrot-validation: # array of validations that trigger this response codex-traffic-parrot-validation:
- type: schema
response: ${in} parameter ${name} has invalid value ${value} because ${reason}x-traffic-parrot-validation:
- type: schema
response:
code: INVALID_REQUEST
message: ${in} parameter ${name} has invalid value ${value} because ${reason}x-traffic-parrot-validation:
- type: schema
parameters:
- name: style
in: query
- name: limit
in: query
- name: id
in: path
- name: X-Request-Label
in: header
response:
code: INVALID_REQUEST_PARAMETER
message: ${in} parameter ${name} has invalid value ${value} because ${reason}x-traffic-parrot-validation:
- type: schema
parameters:
- name: *
in: requestBody
response:
code: REQUEST_BODY_INVALID
message: Request body has invalid value ${value} because ${reason}x-traffic-parrot-validation:
- type: schema
parameters:
- name: style
in: query
response:
code: INVALID_QUERY
message: query parameter ${name} has invalid value ${value} because ${reason}
- type: schema
response:
code: INVALID_REQUEST
message: ${in} parameter ${name} has invalid value ${value} because ${reason}
{{ modifyResponse 'headerValue' 'header-name-1' 'header-value-1' }}
{{ modifyResponse 'headerValue' 'header-name-2' 'header-value-2' }}
trafficparrotserver.logging.properties.filename=trafficparrotserver.logback.xml
{{ randomValue length=10 type='ALPHANUMERIC' mixedcase=true }}{{ modifyResponse 'headerValue' 'header-name' 'header-value' }}trafficparrot.openapi.import.mode=SELECT_RESPONSE_STATUS trafficparrot.openapi.skeletons.mode=SELECT_RESPONSE_STATUS
trafficparrot.gui.security.mode=LOGIN_PROPERTIES
admin=password,traffic-parrot-gui-role,traffic-parrot-gui-edit-role readonly=password,traffic-parrot-gui-role
{{ dataSource 'couchbase.db' 'INSERT INTO PERSON(KEY, VALUE) VALUES ("$id", {"id" : $id,"name" : $name})' id=1000 name='some-name' syntax='N1QL' }}
{{ dataSource 'couchbase.db' 'SELECT name FROM PERSON USE KEYS "$id"' id=1000 single=true syntax='N1QL' }}
{{ dataSource 'couchbase.db' 'INSERT INTO PERSON(KEY, VALUE) VALUES ("$id", $object)' id=1000 object=example syntax='N1QL' }}
{{#times 10}}{{@index}}{{#unless @last}},{{/unless}}{{/times}}DELETE http://localhost:8080/api/http/mappings/bulk/UUID1,UUID2,UUID3
DELETE http://localhost:8080/api/grpc/mappings/bulk/UUID1,UUID2,UUID3
com.example.Service/method -> host1:port1 com.example.packageA.* -> host2:port2 com.example.packageB.* -> host3:port3
trafficparrot.virtualservice.handlebars.now.provider=HANDLEBARS
trafficparrot.virtualservice.handlebars.now.provider=WIREMOCK
trafficparrot.virtualservice.handlebars.now.dynamic=true
{{now offset='2 years' format='epoch' provider='WIREMOCK'}}{{now format='short' provider='HANDLEBARS'}}trafficparrot.gui.security.mode=LOGIN_PROPERTIES
admin=password,traffic-parrot-gui-role
2020-10-07 20:09:32,330 INFO Request to 'GET /test123' was received on '2020-10-07T19:09:32.326Z' from '127.0.0.1'. Response was sent on '2020-10-07T19:09:32.397Z' to '127.0.0.1'. Total processing time 71ms
trafficparrot.virtualservice.handlebars.select.indexAndCacheCsvFiles=truethe CSV file loading performance will be significantly improved.
javax.servlet.ServletException: java.lang.IllegalStateException: Insufficient configured threads: required=212 < max=200 for QueuedThreadPool[qtp318353283]@12f9af83{STARTED,8<=168<=200,i=0,r=20,q=0}[ReservedThreadExecutor@71b3bc45{s=0/20,p=0}]
The fix is to increase the number of threads Jetty can spin up. This was done by exposing two properties to configure HTTP Jetty server thread queues:
trafficparrot.gui.http.queuedThreadPool.maxThreads=200 trafficparrot.gui.http.queuedThreadPool.minThreads=8
"sslCipherSuite": "TLS_RSA_WITH_AES_128_CBC_SHA", "sslPeerName": "OU=TP IBM MQ"To provide the server and client certificates you can add the following config to jvm.args:
-Djavax.net.ssl.trustStore=certificates/ca-chain.jks -Djavax.net.ssl.trustStorePassword=trafficparrot -Djavax.net.ssl.keyStore=certificates/mq-client.jks -Djavax.net.ssl.keyStorePassword=trafficparrot -Dcom.ibm.mq.cfg.useIBMCipherMappings=false
For more details see Connect to the queue manager via SSL/TLS channels
trafficparrot.ibmmq.logger.logMessageBodyAsPrintableCharacters=false
test@test-pcs:~/Downloads/trafficparrot-no-jre-5.x.y$ export TP_STARTUP_WAIT_MILLIS=180000 test@test-pcs:~/Downloads/trafficparrot-no-jre-5.x.y$ ./start.sh /optf/programs/jdk1.8.0_181/bin/java Picked up environment startup timeout in milliseconds 180000
trafficparrot.ibmmq.start.queue.replay.on.startup.script=classpath:start-ibmmq-queue-replay-on-startup.txt
trafficparrot.ibmmq.connect.options.accessQueue.output=MQOO_OUTPUT|MQOO_FAIL_IF_QUIESCING
trafficparrot.ibmmq.logger.logMessageBody=true
trafficparrot.virtualservice.mapping.cache.milliseconds=0 trafficparrot.virtualservice.mapping.cache.populate.on.startup=false
"readConnectionsToOpen": 5, "writeConnectionsToOpen": 5
"receiveThreads" : 5, "sendThreads" : 1
"maxMessagesInProgress": 1000000
# # This is a sample comment 1 # RequestQueueManager:'Request QM1' ResponseQueueManager:'Response QM1' RequestQueueNames:'REQ_1_A','REQ_1_B' # # This is a sample comment 2 # RequestQueueManager:'Request QM2' ResponseQueueManager:'Response QM2' RequestQueueNames:'REQ_2_A','REQ_2_B'
# # This is a sample comment # QueueManager:'Local Docker MQ 9' ProxyRequestQueue:'PROXY_PROCESS_PAYMENT' LiveRequestQueue:'PROCESS_PAYMENT' LiveResponseQueue:'PAYMENT_PROCESSESED' ProxyResponseQueue:'PROXY_PAYMENT_PROCESSESED' # # This is a sample comment # QueueManager:'Local Docker MQ 9' ProxyRequestQueue:'PROXY_CREATE_ORDER' LiveRequestQueue:'CREATE_ORDER' LiveResponseQueue:'ORDER_CREATED' ProxyResponseQueue:'PROXY_ORDER_CREATED'
This means that the standard WireMock client libraries can be used when connecting to the API port e.g. when using WireMock.configureFor("localhost", 8080, "/api/http");
Custom HTTP clients or a browser may continue to drop the /__admin section of the path so that API calls such as http://localhost:8080/api/http/mappings can be made
#
# Template used for gRPC mapping file names
#
# Available properties:
# {{ mapping.id }}
# {{ mapping.package }}
# {{ mapping.service }}
# {{ mapping.method }}
# {{ mapping.isSuccess }}
# {{ mapping.status.name }}
# {{ mapping.status.code }}
#
# Available commands:
# {{ countGrpcMappings package=mapping.package service=mapping.service method=mapping.method success=true offset=1 format='%02d' }}
trafficparrot.virtualservice.grpc.saved.mapping.file.name.template={{ mapping.package }}.{{ countGrpcMappings package=mapping.package offset=1 format='%02d' }}.{{ mapping.service }}-{{ mapping.method }}[{{ mapping.status.name }}]
trafficparrot.virtualservice.grpc.saved.mapping.file.name.collision.suffix.template=-{{ mapping.id }}
UNKNOWN: Traffic Parrot Virtual Service: No responses matched the given request. See the Traffic Parrot logs for more details.
Request was not matched
=======================
-----------------------------------------------------------------------------------------------------------------------
| Closest stub | Request |
-----------------------------------------------------------------------------------------------------------------------
|
helloworldgreetersayhello-38d8ac56-38fe-4a57-89b3-5af8368 |
874a5.json |
|
ANY | ANY
helloworld.Greeter/SayHello | helloworld.Greeter/SayHello
|
Protocol: GRPC | Protocol: GRPC
|
{ | { <<<<< Body does not match [equalToJson]
"inputName" : "example" | "inputName" : "not matching"
} | }
|
-----------------------------------------------------------------------------------------------------------------------
Configure how long to cache the proto files during replay using the trafficparrot.virtualservice.grpc.server.replay.proto.cache.milliseconds property.
A value of 0 means do not cache at all.
Configure the number of boss and worker threads of the gRPC server using the trafficparrot.virtualservice.grpc.server.boss.threads and trafficparrot.virtualservice.grpc.server.worker.threads properties.
The special value DOUBLE_NUMBER_OF_PROCESSORS means use double the number of processors.