In my GAE, I have the following segment of code:
accountId := r.Header.Get("user_id")
if accountId == "" {
accountId = r.FormValue("user_id")
if accountId == "" {
utility.CreateErrorResponse(w, "User ID is missing from request")
return
}
}
the code basically try to read "user_id" from Header but the accountId is empty making the program to return early unexpected.
Here is my C# client code:
...
HttpWebRequest req = (HttpWebRequest) WebRequest.Create(data);
req.Method = "GET";
req.KeepAlive = false;
foreach (ExtraAttribute att in mAttributes)
{
req.Headers.Add( att.mKey, att.mValue);
}
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
...
where the foreach help me add the "user_id" attribute to the Request Header.
(And I have confirmed the existence of "user_id" entry in Fiddler)
What is the next thing I should do to find out whats going on?
Thanks
I just found that after i changed the attribute name from "user_id" to "UserId" and everything works now...
Don't know if its the capital case or the underscore problem.
Related
I am new to gatling
I am trying to loop on json response, find the country code that I am looking for and take the id coressponding the that coutry code.
Sample algorithm:
list.foreach( value => { if (value.coutrycode == "PL") then store value.id })
on Gatling:
def getOffer() = {
exec(
http("GET /offer")
.get("/offer")
.check(status.is(Constant.httpOk))
.check((bodyString.exists),
jsonPath("$[*]").ofType[Map[String,Any]].findAll.saveAs("offerList")))
.foreach("${offerList}", "item"){
exec(session => {
val itemMap = session("item").as[Map[String,Any]]
val countryCodeId = itemMap("countryCode")
println("****" + countryCodeId)
// => print all the country code on the list
if (countryCodeId =="PL"){ // if statement condition
println("*************"+ itemMap("offerd")); // print the id eg : "23"
session.set("offerId", itemMap("offerId")); // set the id on the session
}
println("$$$$$$$$$$$$$$" + session("offerId")) // verify that th session contains the offerId but is not
session
})
}
}
When I try to print the session("offerId"), it's print "item" and not the offerId.
I looked on the documentation but I didn't understand the behaviour. Could you please explain it to me ?
It's all in the documentation.
Session instances are immutable!
Why is that so? Because Sessions are messages that are dealt with in a
multi-threaded concurrent way, so immutability is the best way to deal
with state without relying on synchronization and blocking.
A very common pitfall is to forget that set and setAll actually return
new instances.
val session: Session = ???
// wrong usage
session.set("foo", "FOO") // wrong: the result of this set call is just discarded
session.set("bar", "BAR")
// proper usage
session.set("foo", "FOO").set("bar", "BAR")
So what you want is:
val newSession =
if (countryCodeId =="PL"){ // if statement condition
println("*************"+ itemMap("offerd")); // print the id eg : "23"
session.set("offerId", itemMap("offerId")); // set the id on the session
} else {
session
}
// verify that the session contains the offerId
println("$$$$$$$$$$$$$$" + newSession("offerId").as[String])
newSession
I hope someone can point me into the right direction!
I try to run one scenario which has several steps that have to be executed in order and each with the same user session to work properly. The below code works fine with one user but fails if I use 2 or more users...
What am I doing wrong?
val headers = Map(
Constants.TENANT_HEADER -> tenant
)
val httpConf = http
.baseURL(baseUrl)
.headers(headers)
val scen = scenario("Default Order Process Perf Test")
.exec(OAuth.getOAuthToken(clientId))
.exec(session => OAuth.createAuthHHeader(session, clientId))
.exec(RegisterCustomer.registerCustomer(customerMail, customerPassword,
tenant))
.exec(SSO.doLogin(clientId, customerMail, customerPassword, tenant))
.exec(session => OAuth.upDateAuthToken(session, clientId))
.exec(session =>
UpdateCustomerBillingAddr.prepareBillingAddrRequestBody(session))
.exec(UpdateCustomerBillingAddr.updateCustomerBillingAddr(tenant))
.exec(RegisterSepa.startRegisterProcess(tenant))
.exec(session => RegisterSepa.prepareRegisterRequestBody(session))
.exec(RegisterSepa.doRegisterSepa(tenant))
setUp(
scen
.inject(atOnceUsers(2))
.protocols(httpConf))
object OAuth {
private val OBJECT_MAPPER = new ObjectMapper()
def getOAuthToken(clientId: String) = {
val authCode = PropertyUtil.getAuthCode
val encryptedAuthCode = new
Crypto().rsaServerKeyEncrypt(authCode)
http("oauthTokenRequest")
.post("/oauth/token")
.formParam("refresh_token", "")
.formParam("code", encryptedAuthCode)
.formParam("grant_type", "authorization_code")
.formParam("client_id", clientId)
.check(jsonPath("$").saveAs("oauthToken"))
.check(status.is(200))
}
def createAuthHHeader(session: Session, clientId: String) = {
val tokenString = session.get("oauthToken").as[String]
val tokenDto = OBJECT_MAPPER.readValue(tokenString,
classOf[TokenDto])
val session2 = session.set(Constants.TOKEN_DTO_KEY, tokenDto)
val authHeader = AuthCommons.createAuthHeader(tokenDto,
clientId, new util.HashMap[String, String]())
session2.set(Constants.AUTH_HEADER_KEY, authHeader)
}
def upDateAuthToken(session: Session, clientId: String) = {
val ssoToken = session.get(Constants.SSO_TOKEN_KEY).as[String]
val oAuthDto = session.get(Constants.TOKEN_DTO_KEY).as[TokenDto]
val params = new util.HashMap[String, String]
params.put("sso_token", ssoToken)
val updatedAuthHeader = AuthCommons.createAuthHeader(oAuthDto,
clientId, params)
session.set(Constants.AUTH_HEADER_KEY, updatedAuthHeader)
}
}
def createAuthHHeader(session: Session, clientId: String) = {
val tokenString = session.get("oauthToken").as[String]
val tokenDto = OBJECT_MAPPER.readValue(tokenString,
classOf[TokenDto])
val session2 = session.set(Constants.TOKEN_DTO_KEY, tokenDto)
val authHeader = AuthCommons.createAuthHeader(tokenDto,
clientId, new util.HashMap[String, String]())
session2.set(Constants.AUTH_HEADER_KEY, authHeader)
}
So I did add the two methods that dont work along as expected. In the first part I try to fetch a token and store in the session via check(jsonPath("$").saveAs("oauthToken")) and in the second call I try to read that token with val tokenString = session.get("oauthToken").as[String] which fails with the exception saying that there is no entry for that key in the session...
I've copied it and removed/mocked any missing code references, switched to one of my apps auth url and it seems to work - at least 2 firsts steps.
One thing that seems weird is jsonPath("$").saveAs("oauthToken") which saves whole json (not single field) as attribute, is it really what you want to do? And are you sure that getOAuthToken is working properly?
You said that it works for 1 user but fails for 2. Aren't there any more errors? For debug I suggest changing logging level to TRACE or add exec(session => {println(session); session}) before second step to verify if token is properly saved to session. I think that something is wrong with authorization request (or building that request) and somehow it fails or throws some exception. I would comment out all steps except 1st and focus on checking if that first request is properly executed and if it adds proper attribute to session.
I think your brackets are not set correctly. Change them to this:
setUp(
scn.inject(atOnceUsers(2))
).protocols(httpConf)
This is pretty basic. Based on what I've read, this should work. I have a more complex version of this as well.
The To parameter listed below is a List of strings. From and Body are strings.
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint('https://api.testdomain.com/batchemail');
request.setHeader('Authorization', 'Bearer ' + token);
request.setMethod('POST');
request.setHeader('Accept', '*/*');
request.setHeader('Content-Type', 'application/json;charset=UTF-8');
// Set the body as a JSON object
request.setBody('{"To": ["to#email.com"]}');
request.setBody('{"From": "from#email.com"}');
request.setBody('{"Body": "Test message"}');
HttpResponse response = http.send(request);
Here is an example of the JSON that the API accepts.
{
"to": ["to#email.com"],
"from": "from#email.com",
"body": "Test message"
}
The endpoint has been added in Remote Site Settings.
Any idea why this isn't working? Any help is much appreciated. Thanks!
UPDATE 1 (this works)
request.setBody('{"To": ["to#email.com"], "From": "from#email.com", "Body": "Test message." }');
UPDATE 2 (this works too)
JSONGenerator gen = JSON.createGenerator(true);
// Write data to the JSON string.
gen.writeStartObject();
gen.writeObjectField('to', emailList);
gen.writeStringField('from', 'from#email.com');
gen.writeStringField('body', message);
gen.writeEndObject();
// Get the JSON string.
String pretty = gen.getAsString();
request.setBody(pretty);
Update 3 (this also works)
Gareth Jordan's Solution works as well.
Why not just make a simple class (or inner class) for your body and use JSON.serialize(payload). It makes it cleaner and clearer.
class Payload{
String[] to;
String sender;
String body;
public Payload(String[] recipients, String sender, String message){
this.to = recipients;
this.sender = sender;
this.body = message;
}
}
Then your code would be
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint('https://api.testdomain.com/batchemail');
request.setHeader('Authorization', 'Bearer ' + token);
request.setMethod('POST');
request.setHeader('Accept', '*/*');
request.setHeader('Content-Type', 'application/json;charset=UTF-8');
Payload body = new Payload(emailList, 'from#email.com','Test Message');
request.setBody(JSON.serialize(body).replace('"sender"','"from"'));
HttpResponse response = http.send(request);
For the first part, call setBody once, your 3 calls to setBody are just overwriting each other.
for the json generator part, you are double encoding, the variable pretty contains the valid generated json, no need to call json.serialize it.
I have created a method to update the records in a case.
#RestResource(urlMapping= '/FieldCases/*')
global with sharing class RestCaseController {
#HttpPatch
global static String caseUpdate(String caseId, String caseStatus, String caseNote){
Case companyCase = [SELECT Id, Subject, Status, Description FROM Case WHERE Id = :caseId];
companyCase.Status = caseStatus;
companyCase.Description += caseNote;
update companyCase;
Return 'Updated';
}
}
and in work bench I am using
/services/apexrest/FieldCases
{"caseId" : "0037F00000bQYIjQAO",
"caseStatus" : "Working",
"caseNote" : "updating from the work bench"}
but I am getting the below error
HTTP Method 'PATCH' not allowed. Allowed are POST,DELETE,GET,HEAD
It worked alright for me. Here's a screenshot of the request in workbench:
How do I get the full message and not just the metadata using gmail api?
I have a service account and I am able to retrieve a message but only in the metadata, raw and minimal formats. How do I retrieve the full message in the full format? The following code works fine
var request = service.Users.Messages.Get(userId, messageId);
request.Format = UsersResource.MessagesResource.GetRequest.FormatEnum.Metadata;
Message message = request.Execute();
However, when I omit the format (hence I use the default format which is FULL) or I change the format to UsersResource.MessagesResource.GetRequest.FormatEnum.Full
I get the error: Metadata scope doesn't allow format FULL
I have included the following scopes:
https://www.googleapis.com/auth/gmail.readonly,
https://www.googleapis.com/auth/gmail.metadata,
https://www.googleapis.com/auth/gmail.modify,
https://mail.google.com/
How do I get the full message?
I had to remove the scope for the metadata to be able to get the full message format.
The user from the SO post have the same error.
Try this out first.
Go to https://security.google.com/settings/security/permissions
Choose the app you are working with.
Click Remove > OK
Next time, just request exactly which permissions you need.
Another thing, try to use gmailMessage.payload.parts[0].body.dataand to decode it into readable text, do the following from the SO post:
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
System.out.println(StringUtils.newStringUtf8(Base64.decodeBase64(gmailMessage.payload.parts[0].body.data)));
You can also check this for further reference.
try something like this
public String getMessage(string user_id, string message_id)
{
Message temp =service.Users.Messages.Get(user_id,message_id).Execute();
var parts = temp.Payload.Parts;
string s = "";
foreach (var part in parts) {
byte[] data = FromBase64ForUrlString(part.Body.Data);
s += Encoding.UTF8.GetString(data);
}
return s
}
public static byte[] FromBase64ForUrlString(string base64ForUrlInput)
{
int padChars = (base64ForUrlInput.Length % 4) == 0 ? 0 : (4 - (base64ForUrlInput.Length % 4));
StringBuilder result = new StringBuilder(base64ForUrlInput, base64ForUrlInput.Length + padChars);
result.Append(String.Empty.PadRight(padChars, '='));
result.Replace('-', '+');
result.Replace('_', '/');
return Convert.FromBase64String(result.ToString());
}