ContentSize cannot be null error for Attachment in Rally Webservices API - web-services

I am trying to upload attachments in test results using Rally Webservices API. As i am only familiar with RestAssured, i am using that to create my requests. However im getting the following error
Validation error: Attachment.attachments[0].contentSize should not be null. Warning: Ignored JSON element Attachment.Size during processing of this request.
I have already created an AttachmentContent and TestCaseResult
_ref="https://rally1.rallydev.com/slm/webservice/v2.0/attachmentcontent/<objectid>"
_ref="https://rally1.rallydev.com/slm/webservice/v2.0/testcaseresult/<objectid>"
Next i used the following code to create an attachment
File attachment= new File("<File Location>");
int fileSize= (int)attachment.length();
String payload= "{\"Attachment\":"
+ "{"
+ "\"Content\": \"https://rally1.rallydev.com/slm/webservice/v2.0/attachmentcontent/<objectid>\","
+ "\"TestCaseResult\": \"https://rally1.rallydev.com/slm/webservice/v2.0/testcaseresult/<objectid>\","
+ "\"User\": \"https://rally1.rallydev.com/slm/webservice/v2.0/user/<objectid>\","
+ "\"ContentType\": \"application/octet-stream\","
+ "\"Name\":"+attachment.getName()+","
+ "\"Size\":"+fileSize
+"}"
+"}"
RestAssured.given().log().all()
.header("ZSESSIONID", apiKey)
.header("Content-Type", "application/json")
.body(payload)
.when().log().all()
.post("https://rally1.rallydev.com/slm/webservice/v2.0/attachment/create")
This is the payload i used to create Test Case Result. Let me know if im missing anything
{
"TestCaseResult": {
"Verdict": "Pass",
"Date": <date>,
"Build": "1.0.0",
"Notes": "Test Note",
"TestCase": "<Test case object id>",
"Tester": "<user object id>"
}
}

Related

Getting 400 Bad Request error while trying to move Azure resources via Postman

I am trying to move resources from one resource group to another via Postman.
I got the access token successfully by using below parameters:
https://login.microsoftonline.com/mytenantid/oauth2/v2.0/token
client_id='myclientid'
&scope=https://management.azure.com/.default
&grant_type=client_credentials
&client_secret='appclientsecret'
I am using query like below:
POST
https://management.azure.com/subscriptions/mysubscriptionid/resourceGroups/resourcegroupname/moveResources?api-version=2021-04-01
Request Body
{
"resources" : "/subscriptions/mysubscriptionid/resourceGroups/resourcegroupname/providers/Microsoft.KeyVault/vaults/keyvaultname",
"targetResourceGroup" : "/subscriptions/mysubscriptionid/resourceGroups/targetresourcegroupname"
}
But I got error like below:
{ "error": { "code": "UnsupportedMediaType",
"message": "The content
media type 'text/plain' is not supported. Only 'application/json' is
supported."
} }
After changing the type to JSON, I am getting another error like below:
{ "error": { "code": "InvalidRequestContent", "message": "The request
content was invalid and could not be deserialized: 'Error converting
value
"/subscriptions/mysubscriptionid/resourceGroups/resourcegroupname/providers/Microsoft.KeyVault/vaults/keyvaultname"
to type 'System.String[]'. Path 'resources', line 2, position 143.'."
} }
Can anyone help me to resolve this error?
I tried to reproduce the same in my environment and was able to move resources successfully like below:
Make sure your request body is something like below:
{
"resources" : ["/subscriptions/XXXXXXX/resourceGroups/Test/providers/Microsoft.KeyVault/vaults/testkeyvault549","/subscriptions/XXXXXXXXX/resourceGroups/Test/providers/Microsoft.Storage/storageAccounts/sristackdem01"],
"targetResourceGroup" : "/subscriptions/XXXXXXX/resourceGroups/Demo"
}
When I executed the same query, I got below response:
Please note that resources parameter expects list of resource IDs in [ ]. So, make sure to add them.
When I missed giving [ ] as mentioned above, I got the same error as you like below:
Reference:
Validate Azure Resource Move with Postman - Apostolidis Cloud Corner

Setting label on Google Compute Engine instance disk

I'm going to try to set a disk label on a Google Compute Engine instance. Basically what is documentated here:
https://cloud.google.com/compute/docs/reference/rest/v1/disks/setLabels
Unfortunately also using the simple code provided by Google:
require_once __DIR__ . '/vendor/autoload.php';
$client = new Google_Client();
$client->setApplicationName('Google-ComputeSample/0.1');
$client->useApplicationDefaultCredentials();
$client->addScope('https://www.googleapis.com/auth/cloud-platform');
$service = new Google_Service_Compute($client);
$project = 'my-project';
$zone = 'my-zone';
$resource = 'my-resource'; // here i set the disk name
$requestBody = new Google_Service_Compute_ZoneSetLabelsRequest();
$response = $service->disks->setLabels($project, $zone, $resource, $requestBody);
echo '<pre>', var_export($response, true), '</pre>', "\n";
?>
I always hit a 500 error:
Uncaught Google_Service_Exception: { "error": { "errors": [ { "domain": "global", "reason": "conditionNotMet", "message": "Labels fingerprint either invalid or resource labels have changed", "locationType": "header", "location": "If-Match" } ], "code": 412, "message": "Labels fingerprint either invalid or resource labels have changed" } }
where I suppose that I have the wrong label syntax. But in the label method, I have tried several syntax:
$requestBody->setLabels(array("mylabel"=>"1"));
$requestBody->setLabels(serialize(array("mylabel"=>"1")));
$requestBody->setLabels('"mylabel":"1"');
$requestBody->setLabels('{"mylabel":"1"}');
but none work. And nothing has changed (always 500 error with the same exception). What did I do wrong?
The error response you're receiving indicates that the labelFingerprint is wrong or not set. The request body should contain both the labels and the labelFingerprint and it looks like you're only setting the former:
{
"labels": {
string: string,
...
},
"labelFingerprint": string
}
The documentation you linked explains what the lableFingerprint is:
The fingerprint of the previous set of labels for this resource, used to detect conflicts. The fingerprint is initially generated by Compute Engine and changes after every request to modify or update labels. You must always provide an up-to-date fingerprint hash in order to update or change labels. Make a get() request to the resource to get the latest fingerprint.
A base64-encoded string.

AWS API Gateway: Can't map thrown error from Lambda to Method Response using Integration Response

The issue
Using the Integration Response feature of AWS API Gateway, I can successfully handle errors thrown by Lambda. However, I'm having trouble mapping the Javascript error object to the mapping template. The error object looks like this.
{
"errorMessage": "Error: ABC123",
"errorType": "Error",
"stackTrace": [
"exports.handler (/var/task/index.js:9:11)"
]
}
Here's my Integration Response mapping for application/json
#set($errorMessage = $input.path('$.errorMessage'))
{
"message" : $errorMessage
}
What I've tried
Using this configuration, this is the entire response returned to the client: Unexpected 'E'. This is one string and is not contained in a JSON object.
This E that's referenced in the error is the first character from my thrown error message, which is used to match the Lambda Error Regex. I know this as I briefly changed the first letter to X and I got Unexpected 'X' as the response.
When I change the first line of my mapping template to this (mapping the entire object rather than attempting to just map the errorMessage property)
#set($errorMessage = $input.path('$'))
I get only the stack trace from the Javascript error object.
{
"message" : [
"exports.handler (/var/task/index.js:9:11)"
]
}
This would suggest that either the entire response object being returned to API Gateway is just the stackTrace property from the Javascript error. But to me, this doesn't make sense as something is picking up the errorMessage as thats where the Unexpected 'E' message is coming from.
Similarly, when I try and map the errorType property, I get the same error as it also starts with E. I can only successfully map the message property when I use the entire $ input object, or just the stackTrace property.
What am I doing wrong here?
Other relevant code
Here's the API Gateway Error Model. The message property is clearly marked as a string type yet it only works when I return an array. Note: this is the default code
{
"$schema" : "http://json-schema.org/draft-04/schema#",
"title" : "Error Schema",
"type" : "object",
"properties" : {
"message" : { "type" : "string" }
}
}
Here's the Lambda function code
exports.handler = async (event, context, callback) => {
throw new Error(Error: ABC123);
};
I've figured it out. The solution is to use $input.json() rather than $input.path()
Here's my new mapping template
{
"errorMessage" : $input.json('$.errorMessage')
}

how to use google cloud vision to extract multiple text language in android studio

I am trying to build an android application (in android studio platform) which extracts different text languages from image using google cloud vision, but I have a problem in starting.
I don't know how to use google cloud files. Which files do I need to create or download and how to direct my API to extract multiple languages?
I got the API and this source code :
POST https://vision.googleapis.com/v1/images:annotate?key=YOUR_API_KEY
{
"requests": [
{
"image": {
"content": "/9j/7QBEUGhvdG9zaG9...base64-encoded-image-content...fXNWzvDEeYxxxzj/Coa6Bax//Z"
},
"features": [
{
"type": "TEXT_DETECTION"
}
]
}
]
}
public static void detectText(String filePath, PrintStream out) throws Exception, IOException {
List<AnnotateImageRequest> requests = new ArrayList<>();
ByteString imgBytes = ByteString.readFrom(new FileInputStream(filePath));
Image img = Image.newBuilder().setContent(imgBytes).build();
Feature feat = Feature.newBuilder().setType(Type.TEXT_DETECTION).build();
AnnotateImageRequest request =
AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build();
requests.add(request);
try (ImageAnnotatorClient client = ImageAnnotatorClient.create()) {
BatchAnnotateImagesResponse response = client.batchAnnotateImages(requests);
List<AnnotateImageResponse> responses = response.getResponsesList();
for (AnnotateImageResponse res : responses) {
if (res.hasError()) {
out.printf("Error: %s\n", res.getError().getMessage());
return;
}
// For full list of available annotations, see http://g.co/cloud/vision/docs
for (EntityAnnotation annotation : res.getTextAnnotationsList()) {
out.printf("Text: %s\n", annotation.getDescription());
out.printf("Position : %s\n", annotation.getBoundingPoly());
}
}
}
}
I would suggest you to try your image data on the Cloud Vision Api Explorer [1]. You can try the API directly on the web browser with an Oauth2 authentication. Follow the steps below:
Enable the API on Google Cloud Console -> APIs and Services -> Libraries
Set the scopes on the API Explorer checkbox:
https://www.googleapis.com/auth/cloud-platform
https://www.googleapis.com/auth/cloud-vision
{
"requests": [
{
"features": [
{
"type": "TEXT_DETECTION"
}
],
"image": {
"source": {
"imageUri": "http://dps.usc.edu/files/2015/07/text-alerts.png"
},
},
"imageContext": {
"languageHints": [
"en"
]
}
]
}
Set de “imageContext”. There you can set language hints, but the API might detect the language automatically. Check this [2] for available language hints.
In the source you could use an image from your Google Cloud Storage bucket changing “imageUri” by: "gcsImageUri": "gs://your-bucket/text-alerts.png" as your image uri. Note the change in protocol.
You are using “content” instead of “source”, and this is for setting a base64 encoded string image. You can try to encode an image with Base64 copy the encode as plain text and try on the API Explorer to check that the encode is correct and works. Be careful when copying as you may get noise like \n, \t and things that might break your b64 encode. I share a python code that does the job:
import base64
f = open("text-alerts.png", "rb")
encoded = base64.b64encode(f.read())
print(encoded)
f.close()
fw = open('content.b64', "wb")
fw.write(encoded)
fw.close()
In your request:
{ "requests": [ { "image": { "content": "/9j/7QBEUGhvdG9zaG9...base64-encoded-image-content...fXNWzvDEeYxxxzj/Coa6Bax//Z" }, "features": [ { "type": "TEXT_DETECTION" } ] } ] }
The content tag is the image string in Base64:
"content":“/9j/7QBEUGhvdG9zaG9...base64-encoded-image-content...fXNWzvDEeYxxxzj/Coa6Bax//Z”
You can use a web tool to do the same and check that your Base64 works. You can load the file on the Android Studio.
Here [4] you can find a sample for Android, with a README that explains how to configure your App. You need to create your API Key here [3] and in the MainActivity you have a variable that must be set to your API Key that then is used for the request.
private static final String CLOUD_VISION_API_KEY = "YOUR_API_KEY";
The sample loads an image and converts it to Base64 before sending the request [5]. See the method callCloudVision, inside there is an AsyncTask that retrieves an image and converts it to Base64 before sending the request.
[1] https://cloud.google.com/vision/docs/quickstart
[2] https://cloud.google.com/vision/docs/languages
[3] https://console.cloud.google.com/apis/credentials?project=your-project-id
[4] https://github.com/GoogleCloudPlatform/cloud-vision/tree/master/android
[5] https://github.com/GoogleCloudPlatform/cloud-vision/blob/master/android/CloudVision/app/src/main/java/com/google/sample/cloudvision/MainActivity.java#L192

Obtaining error while using amazon lex "Invalid Lambda Response: Received invalid response from Lambda"

I'm trying to develop a chatbot using AWS Lex. But unfortunately, I'm getting an error while building the chat on Lex. I'm using one intent and 2 slots. For some reason, when the lambda function is connected to the chat, the second value of the slot is saved as null. But when I run it in lambda as a test case, it's successful.
Right now, all I want to do is show a response message after the details of the slot is entered.
This is my code
public class LexBot implements RequestHandler<Map<String, Object>, Object> {
#Override
public Object handleRequest(Map<String, Object> input, Context context) {
// LexRequest lexRequest = LexRequestFactory.createLexRequest(input);
String content = "Request came from the bot: ";
Message message = new Message("PlainText", content);
DialogAction dialogAction = new DialogAction("Close", "Fullfiled", message);
return new LexRespond(dialogAction);
}
}
And this is the error I'm getting in AWS Lex:
An error has occurred: Invalid Lambda Response: Received invalid
response from Lambda: Can not construct instance of Message, problem:
content must not be blank at [Source:
{"dialogAction":{"type":"Close","message":{"contentType":"PlainText","some_respond_message":"Request
came from the bot: "}}}; line: 1, column: 122]
If you are using amazon lexv2, then amazon lex expecting a different JSON response compared to lexv1.
Sample lambda response which is accpeted by lex:
{
"sessionState": {
"dialogAction": {
"type": "Close"
},
"intent": {
"confirmationState": "Confirmed",
"name": "SearchProducts",
"state": "Fulfilled",
},
},
"messages": [
{
"contentType": "PlainText",
"content": "Select from the list",
}
]
}
Check here for the full response structure https://docs.aws.amazon.com/lexv2/latest/dg/lambda.html
According to the docs, below is the correct format for constructing the final response:
{
"sessionAttributes": session_attributes,
"dialogAction":{
"type":"Close",
"fulfillmentState":"Fulfilled",
"message":{
"contentType":"PlainText",
"content":message
}
}
}
Use this format for constructing the response to avoid the error.
You spelled "fulfilled" incorrectly - you typed "Fullfiled" as pasted in below:
DialogAction dialogAction = new DialogAction("Close", "Fullfiled", message);