axios put request for elasticsearch - elasticsearch

I have been battling for a few days to follow an article . This is not new to me but not my strong point.
Ive managed to get my http request working but I think I need to add auth to it. here is the code.
const axios = require('axios');
const host = 'https://search-data-ds-42456788224444444444444444.us-west-1.es.amazonaws.com';
const index = 'msgsdatastream';
const type = 'msgs';
const url = `${host}/${index}/${type}/`;
const headers = { 'Content-Type': 'application/json' };
exports.handler = async (event, context) => {
let count = 0;
for (const record of event.Records) {
const id = 1;
if (record.eventName == 'REMOVE') {
await axios.delete(url + id);
return 'Item removed';
} else {
const document = record.dynamodb.NewImage;
console.log('Adding document');
console.log(document);
await axios.put(url + id, document);
}
count += 1;
}
return `Successfully processed ${count} records.`;
};
This is inside my Lambda function
Here is the cloudwatch logs.
2021-02-05T12:52:05.386Z 13782564-f0fc-4a6d-892a-c00c9e880bd1 ERROR Invoke Error {
"message": "Request failed with status code 403",
"name": "Error",
"stack": "Error: Request failed with status code 403\n at createError (/var/task/node_modules/axios/lib/core/createError.js:16:15)\n at settle (/var/task/node_modules/axios/lib/core/settle.js:17:12)\n at IncomingMessage.handleStreamEnd (/var/task/node_modules/axios/lib/adapters/http.js:260:11)\n at IncomingMessage.emit (events.js:326:22)\n at endReadableNT (_stream_readable.js:1241:12)\n at processTicksAndRejections (internal/process/task_queues.js:84:21)",
"config": {
"url": "https://search-msgs-ds-rt5io3veb4k4m5vtglmg43frxu.us-east-1.es.amazonaws.com/msgsdatastream/msgs/1",
"method": "put",
"data": "{\"Area\":{\"S\":\"Lotus\"},\"id\":{\"S\":\"2\"},\"Name\":{\"S\":\"Romano\"}}",
"headers": {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=utf-8",
"User-Agent": "axios/0.21.1",
"Content-Length": 59
},
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1
}
}
I am failing forward on this one. editing as I go along. Please could you direct me in how to resolve this?

Related

Unable to upload pdf file in POST request using Cypress 6.4.0 & TypeScript

I am writing API tests using Cypress 6.4.0 & TypeScript where I need to upload a pdf file in the request body.
My code for the request is:
My code for the request body is:
public async createAssetDocTest() {
let url = sharedData.createAsset_url + sharedData.assetA;
let response = await fetch(url
,
{
method: 'POST',
body: await requestbody.createAssetDocBody(),
headers: {
Authorization: sharedData.bearer + " " + adminTokenValue,
Accept: sharedData.accept,
'Content-type': sharedData.docReqContent,
},
}
);
expect(response.status).to.equal(200);
public async createAssetDocBody(): Promise<any> {
const file = sharedData.doc;
cy.fixture(file).then((pdfDoc) => {
Cypress.Blob.binaryStringToBlob(
pdfDoc,
sharedData.contentTypeValue
).then(async (blob: string | Blob) => {
const formData = new FormData();
formData.set(sharedData.document, blob, file);
const body = {
formdata: {
document: {
value: pdfDoc,
options: {
filename: sharedData.document,
contentType: null,
},
},
},
};
return body;
});
});
}
However, the file does not upload the file & the request fails with error 400. Is there a better way to upload files in the body of the POST request?
enter image description here
Resolved this issue!
The main issue was that my Cypress version was too old. Upgraded to 9.7.0
Then added the following code:
public async createAssetDoc(): Promise<any> {
cy.fixture("pic location", "binary")
.then((file) => Cypress.Blob.binaryStringToBlob(file))
.then((blob) => {
var formdata = new FormData();
formdata.append("document", blob, "pic location");
const url = "your url";
cy.request({
url,
method: "POST",
body: formdata,
headers: {
Authorization:
"bearer" + " " + token,
Accept: "application/json",
"Content-Type": "multipart/form-data",
},
}).then((response) => {
expect(response.status).to.equal(201);
expect(response.statusText).to.equal(
sharedData.fileUploadStatusText
);
const finalResponse = String.fromCharCode.apply(
null,
new Uint8Array(response.body)
);
return finalResponse;
});
});
}

React custom hook for different API task with unique state and handling management in each?

I had already written custom API fetch hooks before, but now I have complex API call functions with different features and couldn't wrap my head around how to create a single custom hook and use all of them.
Each of them got different states, methods, wrappers etc some with a single promise some with promise.all()
1st call:
const handleGetReportsList = async () => {
setIsLoading(true);
try {
const response = await axios(reportURL, {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token
}
});
setReportsList(response.data);
} catch (err) {
if (axios.isAxiosError(err)) {
console.log(err.response);
notify(
{
width: "auto",
message: `Rapor verileri listelenemiyor.
${err.response?.data.message}
Hata kodu: ${err.response?.status}`,
position: {}
},
"error",
6000
);
console.error(
(err instanceof Error && err.message) || "Something's Wrong"
);
} else {
notify("Hata! Çıkış yapıp tekrar deneyin", "error", 6000);
}
}
setIsLoading(false);
};
2nd call:
const handleGetReportData = async (e: ClickEvent) => {
const validationResult = e.validationGroup.validate();
if (validationResult.isValid) {
setIsLoading(true);
setIsDataGridVisible(false);
try {
const response = await axios(reportURL, {
method: "POST",
data: JSON.stringify(reportParams),
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token
}
});
setReportData(response.data);
setIsDataGridVisible(true);
} catch (err) {
setIsLoading(false);
if (axios.isAxiosError(err)) {
notify(
{
width: "auto",
message: `Rapor verileri listelenemiyor.
Lütfen tekrar deneyin.
Hata kodu: ${err.response?.status}`
},
"error",
6000
);
console.error(
(err instanceof Error && err.message) || "Something's Wrong"
);
} else {
notify("Hata! Çıkış yapıp tekrar deneyin", "error", 6000);
}
}
}
};
3rd call:
const handleGetFilterData = async () => {
setIsLoading(true);
setIsFilterButtonVisible(false);
try {
const response = await axios(filterURL, {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token
}
});
// eslint-disable-next-line #typescript-eslint/no-explicit-any
dispatchFilterData(response.data);
setIsFilterButtonVisible(true);
} catch (err) {
if (axios.isAxiosError(err)) {
notify(
{
width: "auto",
message: `Rapor verileri listelenemiyor.
Lütfen tekrar deneyin.
Hata kodu: ${err.response?.data.message}`
},
"error",
6000
);
console.error(
(err instanceof Error && err.message) || "Something's Wrong"
);
} else {
notify("Hata! Çıkış yapıp tekrar deneyin", "error", 6000);
}
}
setIsLoading(false);
};
4th call:
const getDashboardData = async () => {
const apiSettings: AxiosRequestConfig<IApiSettings> = {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token
}
};
setIsLoading(true);
try {
const response = await Promise.all([
axios(`${dashboardURL}TOPLAM/${period}/`, apiSettings),
axios(`${dashboardURL}ADET/${period}/`, apiSettings)
]);
const responseData = response.map(item => {
return item.data;
});
setDashboardData(responseData);
} catch (err) {
if (axios.isAxiosError(err)) {
console.log(err.response);
notify(
{
width: "auto",
message: `Özet verileri listelenemiyor.
${err.response?.data.message}
Hata kodu: ${err.response?.status}`,
position: {
offset: "0 -100"
}
},
"error",
6000
);
console.error(
(err instanceof Error && err.message) || "Something's Wrong"
);
} else {
notify("Hata! Çıkış yapıp tekrar deneyin", "error", 6000);
}
}
setIsLoading(false);
};
As the calls are pretty similar I want to create and use hooks.
Cheers

FormData upload on Expo

Using expo, whenever I run a post request with a FormData object with an appended JSON and a image file, I get
"error": "Unsupported Media Type",
"message": "Content type 'application/octet-stream' not supported",
"path": "/visitas/",
"status": 415,
[…]
as a response from the backend (which runs Spring Boot), but whenever I replicate the request into a HTTP Client (Insomnia on this case) the request follow as it should, and I can retrieve and see the image back as I should.
Code
Visitas.js
[…]
async function startVisita(checkin) {
// Checkin contains file uri and some other things
try {
const location = await getLocation();
const formData = new FormData();
formData.append('object',
JSON.stringify({
longitude: location.coords.longitude,
latitude: location.coords.latitude,
checkin: new Date(),
loja: {id: loja.id},
})
);
// object gets filled accondingly
formData.append('imagecheckin', {
uri: checkin.uri,
name: 'imagem.jpg', // I know the image is .jpg
type: 'image/jpg',
});
// imagecheckin is a object inside formData (not a readStream as it normally would)
console.log(formData);
try {
const response = await fetch(`${Endpoint.baseAddr}${Endpoint.visitas}`, {
body: formData,
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
'Authorization': 'Bearer ' + await AsyncStorage.getItem('jwt'),
},
})
.then(res => res.json());
console.log(response);
} catch (err) {
console.error('Erro ao postar a visita! Erro causado:', err);
console.log(err.res, err.response);
}
} catch (err) {
console.error('Erro ao criar a visita! Erro causado:');
console.error(err);
}
}
[…]
ControllerImagens.java
[…]
#PostMapping
public ResponseEntity<T> adicionarCheckin(
#RequestPart(name = "imagecheckin", required = true) MultipartFile file,
#RequestPart(name = "object", required = true) T objeto,
#RequestHeader("authorization") String token) {
// Calls constructors, validators and stuff
[…]
And the formdata I get from the log is
FormData {
"_parts": Array [
Array [
"object",
"{\"longitude\":-40.3097038,\"latitude\":-20.3758293,\"checkin\":\"2020-04-29T18:06:22.994Z\",\"loja\":{\"id\":1}}",
],
Array [
"imagecheckin",
Object {
"name": "imagem.jpg",
"type": "image/jpg",
"uri": "file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252Fproatend-f576a9db-3f86-4238-8677-3ebbd056f4ea/Camera/1f2192a7-fe81-40d1-8efd-9ff6a98a32a3.jpg",
},
],
],
}

DynamoDB update data works but return Internal Server Error

I am using API server with AWS Lambda and DynamoDB
I've created an API for Update data.
export const updateD = async(event, context, callback)=>{
const {email, uid} = JSON.parse(event.body);
let unique = await getUnique();
const updateParams = {
TableName: "MY_TABLE",
Key: {
email: email,
uid: uid
},
UpdateExpression: "set code = :code, expiredAt = :now", //expiredAt is TTL
ExpressionAttributeValues: {
":isVerified": unique,
":now": moment().add(10, "minutes").unix()
},
ReturnValues: "ALL_NEW"
}
DYNAMO_DB.update(updateParams, (err, data) => {
if(err) {
const r = {
statusCode: 500,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify(err)
}
callback(null, r);
}
const r = {
statusCode: 200,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify({msg: "success"})
}
callback(null, r);
});
}
When I called this API, the data is updated successfully by it, but I can receive only
{
"message": "Internal server error"
}
What I missed in my code??
Your handler is defined as an async function due to which lambda is expected to return a response.
However the function body follows non-async pattern passing the response to the callback instead of returning it.
If you want to use async/await you should update your function by using the promisified version of update operation instead of callback, it may like look like as follows:
export const updateD = async (event) => {
const {email, uid} = JSON.parse(event.body);
let unique = await getUnique();
const updateParams = {
TableName: "MY_TABLE",
Key: {
email: email,
uid: uid
},
UpdateExpression: "set code = :code, expiredAt = :now", //expiredAt is TTL
ExpressionAttributeValues: {
":isVerified": unique,
":now": moment().add(10, "minutes").unix()
},
ReturnValues: "ALL_NEW"
};
try {
const data = await DYNAMO_DB.updateItem(updateParams).promise();
return {
statusCode: 200,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify({msg: "success"})
}
} catch (err) {
return {
statusCode: 500,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify(err)
}
}
};

Error during upload image to imgur - inavlid URL

i have some troubles with imgur api. I converted image to base64 code and tried upload it to imgur api. Unfortuatelly I'm receiving an error:
"error": "Invalid URL (data:image/png;base64,iVBORw0KGgoAA..."
Here's my function:
uploadImageToImgur: function (file) {
const url = 'https://api.imgur.com/3/image',
reader = new FileReader();
reader.onloadend = async function () {
let { result } = reader;
try {
const request = await fetch(url, {
method: 'POST',
headers: {
"Authorization": 'my client key',
},
body: result
});
const response = await request.json();
console.log(response);
} catch (e) {
throw new Error(e);
}
}
if (file) {
reader.readAsDataURL(file);
}
}
You need to cut this part out.
You are missing some parameters. Also, make sure your headers have the Client-ID key.
const request = await fetch(url, {
method: 'POST',
headers: {
"Authorization": 'Client-ID {yourKey}',
},
form: {
"image": result,
"type": "base64"
}
});

Resources