SoapUI MockService: Work as proxy - soap

I'm writing MockService in SoapUI.
In the case if node exist in a received SOAP Request (by XPath) I want generate response by groovy script. In other cases I want redirect a received SOAP-Request. I mean, I want send a received SOAP-Request to other SOAP-Service (I want send by URL).
Is there way to do this?

If you want use your soapUI MockService as proxy, do this :
Create placeholder in response (for example ${responseMessage})
Add script that printed below
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
// load JKS (need for https)
def keyStorePath = "keystore.jks"
def keyStorePassword = "keystore_pswd"
def trustStorePath = "truststore.jks"
def trustStorePassword = "truststore_pswd"
def keyStoreFactory = javax.net.ssl.KeyManagerFactory.getInstance("SUNX509")
def trustStoreFactory = javax.net.ssl.TrustManagerFactory.getInstance("SUNX509")
def keyStore = java.security.KeyStore.getInstance("JKS")
def trustStore = java.security.KeyStore.getInstance("JKS")
def keyInput = new FileInputStream(keyStorePath)
keyStore.load(keyInput, keyStorePassword.toCharArray())
keyInput.close()
def trustInput = new FileInputStream(trustStorePath)
trustStore.load(trustInput, trustStorePassword.toCharArray())
trustInput.close()
keyStoreFactory.init(keyStore, keyStorePassword.toCharArray())
trustStoreFactory.init(trustStore)
def sslContext = javax.net.ssl.SSLContext.getInstance("TLS")
sslContext.init(keyStoreFactory.getKeyManagers(), trustStoreFactory.getTrustManagers(), new java.security.SecureRandom())
def sslFactory = sslContext.getSocketFactory()
// Send received request to https://example.org/soap/service
def soapRequest = mockRequest.requestContent
def soapUrl = new URL("https://example.org/soap/service")
def connection = soapUrl.openConnection()
connection.setRequestMethod("POST")
connection.setRequestProperty("Content-Type" ,"text/html")
connection.setRequestProperty("SOAPAction", "")
connection.setSSLSocketFactory(sslFactory)
connection.doOutput = true
Writer writer = new OutputStreamWriter(connection.outputStream);
writer.write(soapRequest)
writer.flush()
writer.close()
connection.connect()
def soapResponse = connection.content.text
def responseXPathHelper = groovyUtils.getXmlHolder(soapResponse)
responseXPathHelper.declareNamespace("envelop", "http://www.w3.org/2003/05/soap-envelope")
responseXPathHelper.declareNamespace("msg", "https://example.org/soap/service")
// Here you can modify condition (Where you want to spoofing)
if ("ExampleResponse".equals(responseXPathHelper["/envelop:Envelope/envelop:Body/*/local-name()"])) // spoofing
{
def requestXPathHelper = groovyUtils.getXmlHolder(mockRequest.requestContent)
requestXPathHelper.declareNamespace("envelop", "http://www.w3.org/2003/05/soap-envelope")
def messageValue = "spoofed response : " + requestXPathHelper[/envelop:Envelope/envelop:Body/msg:ExampleResponse/text()]
def responseTemplate = """<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
<S:Body>
<ExampleResponse xmlns="https://example.org/soap/service">
${messageValue}
</ExampleResponse>
</S:Body>
</S:Envelope>"""
requestContext.responseMessage = responseTemplate
}
// work as proxy, i.e. just return response recieved from example.org/soap/service
else requestContext.responseMessage = soapResponse

Related

How can i write the AWS lamda unit test cases in scala?

How we can implement the unit test cases for aws lamda serverless.
My code is
object Test1 extends RequestHandler[APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent] with ResponseObjProcess {
override def handleRequest(input: APIGatewayProxyRequestEvent, context: Context): APIGatewayProxyResponseEvent = {
var response = new APIGatewayProxyResponseEvent()
val gson = new Gson
val requestHttpMethod = input.getHttpMethod
val requestBody = input.getBody
val requestHeaders = input.getHeaders
val requestPath = input.getPath
val requestPathParameters = input.getPathParameters
val requestQueryStringParameters = input.getQueryStringParameters
val parsedBody = JSON.parseFull(requestBody).getOrElse(0).asInstanceOf[Map[String, String]]
println(" parsedBody is:: " + parsedBody)
val active = parsedBody.get("active").getOrElse("false")
val created = parsedBody.get("created").getOrElse("0").toLong
val updated = parsedBody.get("updated").getOrElse("0").toLong
requestHttpMethod match {
case "PUT" =>
println(" PUT Request method ")
// insertRecords("alert_summary_report", requestBody)
response.setStatusCode(200)
response.setBody(gson.toJson("PUT"))
case _ =>
println("")
response.setStatusCode(400)
response.setBody(gson.toJson("None"))
}
response
}
}
And I tried to implement unit test cases for the above code.
Below code is:
test("testing record success case") {
var request = new APIGatewayProxyRequestEvent();
request.setHttpMethod(Constants.PUTREQUESTMETHOD)
DELETEREQUESTBODY.put("id", "")
request.setBody(EMPTYREQUESTBODY)
request.setPathParameters(DELETEREQUESTBODY)
println(s"body = ${request.getBody}")
println(s"headers = ${request.getHeaders}")
val response = ProxyRequestMain.handleRequest(subject, testContext)
val assertEqual = response.getStatusCode.equals(200)
assertEqual
}
Actually, I'm getting response.getStatusCode=400 bad requests but test case passed how can I write handle this.
I am looking at your test code and it's not clear to me what you are trying to achieve with your assertions. I think you might have mixed quite a few things. In the code as it currently stands, you have a val, not assertion. I'd encourage you to have a look at the relevant docs and research the options available to you:
http://www.scalatest.org/user_guide/using_assertions
http://www.scalatest.org/user_guide/using_matchers

Scala http client does not reuse connections

in Scala, I have an akka http client class with some local binding:
class AkkaConPoolingHttpClient(
override val timeout: Option[FiniteDuration] = None,
val localBinding: Option[InetSocketAddress] = None,
val userAgentHeader: Option[String] = None)(
implicit val config: HttpClient.Config,
val system: ActorSystem,
val materializer: Materializer)
extends AkkaHttpClient {
protected val http = Http()
override def dispatch(request: HttpRequest): Future[HttpResponse] = {
val effectivePort = request.uri.effectivePort
val connection =
http.outgoingConnection(
request.uri.authority.host.address(),
port = effectivePort,
localAddress = localBinding)
val preparedRequest = userAgentHeader match {
case Some(userAgent) => fixUri(request.withHeaders(request.headers ++ Seq(headers.`User-Agent`(userAgent))))
case None => fixUri(request)
}
Source.single(preparedRequest) via connection runWith Sink.head
}
object AkkaConPoolingHttpClient {
private def fixUri(request: HttpRequest): HttpRequest =
request.withUri(request.uri.toRelative)
}
and I'm trying to see if it reuses the connections and it seems it doesn't:
val connectionCount = new AtomicInteger()
val testServerFuture = Http().bind("127.0.0.1", 0).to {
Sink.foreach { incomingConnection =>
connectionCount.incrementAndGet()
incomingConnection.flow.join(Flow[HttpRequest].map(_ => HttpResponse())).run()
}
}.run()
val testServerPort = Await.result(testServerFuture, defaultExpectTimeout)
.localAddress.getPort
val address = "127.0.0.1"
val addr = Some(new InetSocketAddress(address, 0))
val client = new AkkaConPoolingHttpClient(localBinding = addr)
// Send some requests concurrently
val requests = List(
Get(s"http://127.0.0.1:$testServerPort/1"),
Get(s"http://127.0.0.1:$testServerPort/2"),
Get(s"http://127.0.0.1:$testServerPort/3"))
val responses = Await.result(
Future.sequence(requests.map(client.sendRequest)),
defaultExpectTimeout)
// Send some more requests -- the connections from before should be reused
Thread.sleep(500)
val responses2 = Await.result(
Future.sequence(requests.map(client.sendRequest)),
defaultExpectTimeout)
// Usually this is "3", occasionally "4".
connectionCount.get() must beLessThanOrEqualTo(4)
Unfortunately, the test fails, connectionCount.get() has 6 connections. Why isn't it reuse the connections? what's wrong with this code?
I also tried with:
val effectivePort = request.uri.effectivePort
val clientSettings = ClientConnectionSettings(system).withSocketOptions(SO.ReuseAddress(true) :: Nil)
val connectionFlow: Flow[HttpRequest, HttpResponse, Future[Http.OutgoingConnection]] =
Http().outgoingConnection(
request.uri.authority.host.address(),
port = effectivePort,
localAddress = localBinding,
settings = clientSettings
)
..................
Source.single(preparedRequest)
.via(connectionFlow)
.runWith(Sink.head)
But I still have 6 connections in my test...
Problem
The problem is rooted in the fact that you are creation a new connection for each request. The client code is actually quite clear:
Source.single(preparedRequest) via connection runWith Sink.head
Each request is being sent through a newly instantiated connection. This is due to a general design flaw where you are getting the address from the request:
val connection =
http.outgoingConnection(
request.uri.authority.host.address(), //address comes from request
port = effectivePort,
localAddress = localBinding)
It would be more efficient to establish the address once (ensuring a single Connection), and then each Request would just need the path.
Solution
To use a single connection you'll have to create a single Flow and send all of your requests through that, as described here.

How to form a data using MultiPart/form-data in Play scala?

I don't know how to send multipart data in play scala Test case(Specs2).
In my project, method receives multipart data, code look like this
def school_register() = Action(parse.multipartFormData) { implicit request =>
}
In my test case using Specs2 how to form multipart data manually and want hit the school_register method. Once method hitted values are inserted into DB. I have four parameters regno=100,name="xxxx", address="xxx", std=5. Without multipart its working but i have to use multipart data.
Without Multipart i'm using like this
"com.example.schooladmin" should {
"responds with 200 for addSchoolRegister action with all required parameters" in new WithApplication {
val controller = new TestController()
val result = controller.school_registerr() .apply(FakeRequest().withFormUrlEncodedBody(
“Reg No” -> “100”,“Name” -> “XXX”,“Address” -> “XXXXX”,“std” -> “5”))
status(result) must equalTo(OK)
}
}
Here is how I'm doing this, I create a temporary file and I post it with withMultipartFormDataBody:
val tempFile = TemporaryFile(new java.io.File("../server/idCards/5e7b7c6c-98b3-4245-a5fb-405c9cc904f4"))
val part = FilePart[TemporaryFile](key = "picture", filename = "the.file", contentType = Some("image/jpeg"), ref = tempFile)
val formData = MultipartFormData(dataParts = Map(), files = Seq(part), badParts = Seq(), missingFileParts = Seq())
val Some(result) = route(FakeRequest(userDomain.routes.UserController.createIdCard())
.withMultipartFormDataBody(formData))
status(result) mustEqual OK

Setting a cookie for HTTP POST in Scala with Dispatch

I can't seem to set a cookie using Dispatch. The server resends a new session ID implying that the one I tried to send didn't get sent in the right way. Here is the code:
val domain = "myhost.com"
val host_req = host(domain).secure
val request = host_req / "path" / "path"
def post = request << Map("key" -> "SomeValue")
val response: Either[Throwable, Map[String, String]] =
Http(post OK asHeaders).either()
//The cookie comes down in the form "Set-Cookie: SESSIONID=<somesession>; Path=/path/; HttpOnly"
//successfully retrieves the session id...
val sessionId = getSessionId(response)
println(sessionId)
val sessionCookie = new com.ning.http.client.Cookie(domain, "SESSIONID", sessionId, "/path/", -1, true)
request.POST.addCookie(sessionCookie)
def establishPost = request << Map("key" -> "SomeValue")
establishPost.addCookie(sessionCookie)
val establishResponse: Either[Throwable, Map[String, String]] =
Http(establishPost OK asHeaders).either()
//Server sends down new SESSIONID...
//sessionId != getSEssionId(establishPost)
This is using the newest version of Dispatch. I'm trying to learn Scala as I go, and the only thing I can't figure out how to do either is inspect the establishPost object for its headers before it is sent as a request.
This should be better:
def reqWithParams = request << Map("key" -> "SomeValue")
val reqWithCookies = reqWithParams.addCookie(sessionCookie)
addCookie method returns the new object (the one with a cookie), but your code didn't use it.

Decode a streaming GZIP response in Scala Dispatch?

Receiving a Gzipped response from an API, but Dispatch 0.9.5 doesn't appear to have any methods to decode the response. Any ideas?
Here's my current implementation, the println only prints out string representations of bytes.
Http(
host("stream.gnip.com")
.secure
.addHeader("Accept-Encoding", "gzip")
/ gnipUrl
> as.stream.Lines(println))()
Tried to look at implementing my own handler, but not sure where to begin. Here's the relevant file for Lines: https://github.com/dispatch/reboot/blob/master/core/src/main/scala/as/stream/lines.scala
Thanks!
Simply abandoned Dispatch and used Java APIs directly. Disappointing, but it got the job done.
val GNIP_URL = isDev match {
case true => "https://url/apath/track/dev.json"
case false => "https://url/path/track/prod.json"
}
val GNIP_CHARSET = "UTF-8"
override def preStart() = {
log.info("[tracker] Starting new Twitter PowerTrack connection to %s" format GNIP_URL)
val connection = getConnection(GNIP_URL, GNIP_USER, GNIP_PASSWORD)
val inputStream = connection.getInputStream()
val reader = new BufferedReader(new InputStreamReader(new StreamingGZIPInputStream(inputStream), GNIP_CHARSET))
var line = reader.readLine()
while(line != null){
println(line)
line = reader.readLine()
}
}
private def getConnection(urlString: String, user: String, password: String): HttpURLConnection = {
val url = new URL(urlString)
val connection = url.openConnection().asInstanceOf[HttpURLConnection]
connection.setReadTimeout(1000 * 60 * 60)
connection.setConnectTimeout(1000 * 10)
connection.setRequestProperty("Authorization", createAuthHeader(user, password));
connection.setRequestProperty("Accept-Encoding", "gzip")
connection
}
private def createAuthHeader(username: String, password: String) = {
val encoder = new BASE64Encoder()
val authToken = username+":"+password
"Basic "+encoder.encode(authToken.getBytes())
}
Used GNIP's example: https://github.com/gnip/support/blob/master/Premium%20Stream%20Connection/Java/StreamingConnection.java
This isn't so much a solution as a workaround, but I ended up resorting to bypassing the Future-based stuff and doing:
val stream = Http(req OK as.Response(_.getResponseBodyAsStream)).apply
val result =
JsonParser.parse(
new java.io.InputStreamReader(
new java.util.zip.GZIPInputStream(stream)))
I'm using JsonParser here because in my case the data I'm receiving happens to be JSON; substitute with something else in your use case, if needed.
My solution just defined a response parser and also adopted json4s parser:
object GzipJson extends (Response => JValue) {
def apply(r: Response) = {
if(r.getHeader("content-encoding")!=null && r.getHeader("content-encoding").equals("gzip")){
(parse(new GZIPInputStream(r.getResponseBodyAsStream), true))
}else
(dispatch.as.String andThen (s => parse(StringInput(s), true)))(r)
}
}
So that I can use it to extract Gzip Json response as the following code:
import GzipJson._
Http(req OK GzipJson).apply
Try >> instead of >
See https://github.com/dispatch/dispatch/blob/master/core/src/main/scala/handlers.scala#L58