How to do HTTP PUT/POSTs from inside Groovy code without having to import any libraries (if at all possible)? I know there is a simple getText() methods that Groovy adds to the java.net.URL class, that could be used without adding any dependencies. Is there a way to do Rest PUT in the same fashion?
You can do it with HttpURLConnection in a similar way as you would do it with java:
def url = new URL('http://your_rest_endpoint')
def http = url.openConnection()
http.setDoOutput(true)
http.setRequestMethod('PUT')
http.setRequestProperty('User-agent', 'groovy script')
def out = new OutputStreamWriter(http.outputStream)
out.write('data')
out.close()
http.inputStream // read server response from it
import groovyx.net.http.RESTClient
import static groovyx.net.http.ContentType.JSON
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
url = "http://restapi3.apiary.io"
#Grab (group = 'org.codehaus.groovy.modules.http-builder', module = 'http-builder', version = '0.5.0')
def client = new RESTClient(url)
def jsonObj = new JsonSlurper().parseText('{ "title": "Pick-up posters from Post-Office" }')
def response = client.put(path: "/notes/id",
contentType: JSON,
body: jsonObj,
headers: [Accept: 'application/json'])
println("Status: " + response.status)
if (response.data) {
println("Content Type: " + response.contentType)
println("Headers: " + response.getAllHeaders())
println("Body:\n" + JsonOutput.prettyPrint(JsonOutput.toJson(response.data)))
}
Related
here is my problem. I can't seem to use gatling for aggregation. I have this error: "invalid basic authentication header encoding" HTTP code 401.
here is my simplified code:
package app
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
import java.util.Base64
class Aggregation extends Simulation {
val httpConf = http
.baseUrl("http://localhost:9200")
.acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
val body = StringBody("""{
"aggs": {
"genres": {
"terms": { "field": "genre" }
}
}
}""".stripMargin.replaceAll("\n", " "))
// surely here there is an error but I don't know why
val auth = Base64.getEncoder.encodeToString("elastic:changeme".getBytes())
val scn = scenario("Test aggregation")
.exec(
http("Aggregation")
.get("/_search")
.header("Authorization", "Basic " + auth)
.body(body).asJson
.check(status.is(200)))
var users: Integer = 1
var duration: Integer = 1
setUp(
scn.inject(rampUsers(users) during (duration seconds))
).protocols(httpConf)
}
If your auth scheme is really Basic, you should use Gatling's built-in support instead of crafting the header yourself, see https://gatling.io/docs/gatling/reference/current/http/request/#authentication
http("Aggregation")
.get("/_search")
.basicAuth("elastic", "changeme")
.body(body).asJson
.check(status.is(200)))
Good Day, I have an Issue uploading Jobs to Flink API using Scala
All Get request seem to work
import scalaj.http._
val url: String = "http://127.0.0.1:8081"
val response: HttpResponse[String] = Http(url+"/config").asString
return response
When I try Uploading a JAR file through CURL (works)
curl -vvv -X POST -H "Expect:" -F "jarfile=#/home/Downloads/myJob.jar" http://127.0.0.1:8081/jars/upload
Now I would Like to upload using SCALA
The documentation does not provide a working example and I am fairly new to this type of post: https://ci.apache.org/projects/flink/flink-docs-release-1.3/monitoring/rest_api.html#submitting-programs
Currently my code is (Does not Work):
Taken from : https://github.com/Guru107/flinkjobuploadplugin/tree/master/src/main/java/com/github/guru107 - Edited to my needs
// Ideal Case is to upload a Jar File as a multipart in Scala
import java.io.IOException
import org.apache.http.client.methods.HttpPost
import org.apache.http.entity.mime.MultipartEntityBuilder
import org.apache.http.impl.client.{HttpClients, LaxRedirectStrategy}
import org.apache.http.message.BasicHeader
import org.apache.http.util.EntityUtils
val requestUrl = "http://localhost:8081/jars/upload"
val jarPath = "#/home/Downloads/myJob.jar"
val httpClient: CloseableHttpClient = HttpClients.custom.setRedirectStrategy(new LaxRedirectStrategy).build
val fileToUpload: File = new File(jarPath)
val uploadFileUrl: HttpPost = new HttpPost(requestUrl)
val builder: MultipartEntityBuilder = MultipartEntityBuilder.create
builder.addBinaryBody("jarfile", fileToUpload)
val multipart: HttpEntity = builder.build
var jobUploadResponse: JSONObject = null
uploadFileUrl.setEntity(multipart)
var response: CloseableHttpResponse = null
try {
response = httpClient.execute(uploadFileUrl)
println("response: " + response)
response.setHeader(new BasicHeader("Expect", ""))
response.setHeader(new BasicHeader("content-type", "application/x-java-archive"))
val bodyAsString = EntityUtils.toString(response.getEntity, "UTF-8")
println("bodyAsString: " + bodyAsString)
jobUploadResponse = new JSONObject(bodyAsString)
println("jobUploadResponse: " + jobUploadResponse)
}
It fails to upload file.
Please provide a working example or link of scala example to upload a job/jar file to flink in scala
Thanks in Advance
You can use the client code from com.github.mjreid.flinkwrapper
And upload jar file with scala code:
val apiEndpoint: String = as.settings.config.getString("flink.url") //http://<flink_web_host>:<flink_web_port>
val client = FlinkRestClient(apiEndpoint, as)
client.runProgram(<jarId>)
I send a post to my playframework backend and when I want to print the body I got the Message AnyContentAsEmpty
My controller lools like this:
def createProcess = Action(parse.multipartFormData) { implicit request =>
println(request.body)
Ok("s")
}
my route looks like this
POST /process #controllers.ProcessesController.createProcess()
OPTIONS /process #controllers.ProcessesController.createProcess()
Whats the problem?
Solution is:
in application.conf
# Global fliters
play.http.filters=helpers.Filters
play.filters.cors {
pathPrefixes = ["/"]
allowedOrigins = null
allowedHttpMethods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
allowedHttpHeaders = null
preflightMaxAge = 3 days
}
in filters.scala
package helpers
import javax.inject.Inject
import play.api.http.DefaultHttpFilters
import play.filters.cors.CORSFilter
class Filters #Inject()(corsFilter: CORSFilter)
extends DefaultHttpFilters(corsFilter)
------Update
Was able to fix it by using the UsernamePasswordCredentials class
The code looks like below
val client = new DefaultHttpClient
client.getCredentialsProvider().setCredentials(AuthScope.ANY,new UsernamePasswordCredentials("user","password"));
i am trying to make a HttpPost call to a Restful API, its expecting a username/password, how to pass those parameters? I tried 2 ways
post.addHeader("Username","user")
post.addHeader("Password","clear pwd")
and
post.addHeader("Authorization","Basic base64encoded username:password")
nothing works, I get response text as
Response Text = HTTP/1.1 401 Unauthorized [WWW-Authenticate: Digest realm="API Realm", domain="/default-api", nonce="pOxqalJKm5L5QXiphgFNmrtaJsh+gU", algorithm=MD5, qop="auth", stale=true, Content-Type: text/html; charset=ISO-8859-1, Cache-Control: must-revalidate,no-cache,no-store, Content-Length: 311] org.apache.http.conn.BasicManagedEntity#5afa04c
Below is my code
val url = "http://restapi_url";
val post = new HttpPost(url)
//post.addHeader("Authorization","Basic QWBX3VzZXI6Q0NBQGRidHMxMjM=")
post.addHeader("Username","user_user")
post.addHeader("Password","clear pwd")
post.addHeader("APPLICATION_NAME","DO")
val fileContents = Source.fromFile("input.xml").getLines.mkString
post.setHeader("Content-type", "application/xml")
post.setEntity(new StringEntity(fileContents))
val response = (new DefaultHttpClient).execute(post)
println("Response Text = "+response.toString())
// print the response headers
println("--- HEADERS ---")
response.getAllHeaders.foreach(arg => println(arg))
Here the authorization header should be calculated like this:
httpPost.addHeader("Authorization", "Basic " + Base64.getEncoder.encodeToString("[your-username]:[your-password]".getBytes))
Instead of getUrlEncoder(), it should be getEncoder().
you can write like this, it works in my program
import java.util.Base64
httpPost.addHeader("Authorization", "Basic " + Base64.getUrlEncoder.encodeToString("[your-username]:[your-password]".getBytes))
DefaultHttpClient is deprecated. You should use BasicCredentialsProvider instead. Example code below:
val username = "your_username"
val password = "your_password"
val credentialsProvider = new BasicCredentialsProvider()
credentialsProvider.setCredentials(
AuthScope.ANY,
new UsernamePasswordCredentials(username, password)
)
val httpClient = HttpClientBuilder.create().setDefaultCredentialsProvider(credentialsProvider).build()
I'm creating some tests in SoapUI. SOAP request, that i want to test has attachment. When I'm setting it manualy, everything is ok:
But in my case, i need to set attachment dynamically. I'm trying to made it by properties to hold file path, and groovy script to set attachment. but it's not work at all:
// get request
def request = testRunner.testCase.getTestStepByName( "UploadRoutingCodes" ).testRequest
// clear existing attachments
for( a in request.attachments ) {
request.removeAttachment( a )
}
// get file to attach
//def fileName = context.expand( '${Source of data#PathToXRC File data name }' )
def fileName = context.expand( '${#TestCase#XRC_file_name}' )
def filePath = context.expand( '${#Project#XRC_files_path}' )
log.info "file: " + filePath + fileName
def file = new File(filePath + fileName )
if ( file == null) {
log.error "bad filename"
}
else
{
// attach and set properties
def attachment = request.attachFile( file, true )
attachment.contentType = "application/octet-stream"
def list = fileName.tokenize("\\");
attachment.setPart(list.last())
}
After run this script, request look like this:
Documentation to SoapUI is not helpful at all.
So, my question is: what i'm doing wrong?
I found the answer:
def holder2 = groovyUtils.getXmlHolder( "UploadRoutingCodes#Request" ) // Get Request body
def startDate2 = holder2.setNodeValue( "//blac:FileByteStream","cid:"+list.last()); //Set "link" to attachment in request body
holder2.updateProperty() //and update
attachment.setPart(list.last()); //set attachment
Thaven, thank you for your answer. It helped. I will attach my full groovy script as I spent some time to fully assembled your parts, but anyhow all tributes goes to you.
Please note that:
//FileNamePath
def fileNamePath = testCase.getTestStepAt(testRunner.testCase.getTestStepIndexByName("FileNameProperties")).getProperty("FileNamePath")
//FileName
def fileName = testCase.getTestStepAt(testRunner.testCase.getTestStepIndexByName("FileNameProperties")).getProperty("FileName")
are the test step properties defined inside the test case. Filename: my_sample_filename.xml and FileNamePath: C:\samples\my_sample_filename.xml accordingly.
import groovy.xml.MarkupBuilder
import org.custommonkey.xmlunit.*
import java.util.Random
import java.security.MessageDigest
import java.nio.file.*
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def projectPath = groovyUtils.projectPath
log.info projectPath
def project = testRunner.testCase.testSuite.project
log.info "Project: " + project.name
def myTestSuite = testRunner.testCase.testSuite;
log.info "TestSuite: " + myTestSuite.name
def testCase = testRunner.testCase
log.info "TestCase: " + testCase.name
def testStepUploadDataAfterCheck = testCase.getTestStepByName("UploadDataAfterCheck")
def request= testStepUploadDataAfterCheck.testRequest
log.info "TestStep: " + testStepUploadDataAfterCheck.name
// clear existing attachments
for( a in request.attachments ) {
request.removeAttachment( a )
}
//FileNamePath
def fileNamePath = testCase.getTestStepAt(testRunner.testCase.getTestStepIndexByName("FileNameProperties")).getProperty("FileNamePath")
//FileName
def fileName = testCase.getTestStepAt(testRunner.testCase.getTestStepIndexByName("FileNameProperties")).getProperty("FileName")
// get file to attach
log.info "file to attach: " + fileNamePath.getValue()
def file = new File(fileNamePath.getValue() )
if ( file == null) {
log.error "bad filename"
}
else
{
// attach and set properties
def attachment = request.attachFile( file, true )
attachment.contentType = "application/octet-stream"
attachment.setPart(fileName.getValue())
def holder2 = groovyUtils.getXmlHolder( "UploadDataAfterCheck#Request" ) // Get Request body
holder2.setNodeValue( "//upl:UploadDataAfterCheckRequest/uploadedData","cid:"+fileName.getValue()); //Set "link" to attachment in request body
holder2.updateProperty() //and update
log.info "file attached succesfully"
}
And here is my soap request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:upl="http://www.acer.europa.eu/aris/upload">
<soapenv:Header/>
<soapenv:Body>
<upl:UploadDataAfterCheckRequest>
<uploadedData>cid:my_sample_filename.xml</uploadedData>
</upl:UploadDataAfterCheckRequest>
</soapenv:Body>
</soapenv:Envelope>