.Net/C# Google ML/Translation Exception: failed to connect to all addresses - c#

I am writing to you because i got error during using the AutoML API from google.cloud.
Documentation website:
https://cloud.google.com/translate/automl/docs/predict#automl_translate_predict-csharp
public async Task<IActionResult> UploadToTranslate(IFormFile excelFile)
{
//rest of code...
string credential_path = #"xxxx.json";
System.Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", credential_path);
var client = PredictionServiceClient.Create();
var modelName = ModelName.Format(_config.GetValue<string>("ValuesEnPl:projectId"), _config.GetValue<string>("ValuesEnPl:location"), _config.GetValue<string>("ValuesEnPl:modelId"));
var predictionRequest = new PredictRequest
{
Name = modelName,
Payload = new ExamplePayload
{
TextSnippet = new TextSnippet
{
Content = "Tom goes home"
},
},
};
try
{
var response = client.Predict(predictionRequest, CallSettings.FromCallTiming(CallTiming.FromDeadline(DateTime.UtcNow.AddSeconds(100))));
foreach (var payload in response.Payload)
{
Console.Write($"Translated Content: {payload.Translation.TranslatedContent.Content}");
}
}
catch (RpcException ex)
{
}
//rest of code...
}
Exception: Message = "Status(StatusCode=Unavailable, Detail=\"failed
to connect to all addresses\")"

Related

How to get proper http status codes from Amazon API gateway integrated with C# lambda (not proxy integration)?

I am using a C# lambda to integrate with API gateway. I want API gateway to return proper error codes like 400, 404, 500 etc.
API gateway module tf file
provider "aws" {
version = "<= 2.70.0"
region = "${var.aws_region}"
profile = "${var.aws_profile}"
}
terraform {
# The configuration for this backend will be filled in by Terragrunt
backend "s3" {}
}
data "terraform_remote_state" "api_state" {
backend = "s3"
config {
region = "${var.aws_region}"
profile = "${var.aws_profile}"
bucket = "${var.s3_remote_state_bucket_name}"
key = "${var.s3_remote_state_key_name_api}"
}
}
data "terraform_remote_state" "resource_state"{
backend = "s3"
config {
region = "${var.aws_region}"
profile = "${var.aws_profile}"
bucket = "${var.s3_remote_state_bucket_name}"
key = "${var.s3_remote_state_key_name_resource}"
}
}
data "terraform_remote_state" "lambda_alias"{
backend = "s3"
config {
region = "${var.aws_region}"
profile = "${var.aws_profile}"
bucket = "${var.s3_remote_state_bucket_name}"
key = "${var.s3_remote_state_key_name_lambda}"
}
}
resource "aws_api_gateway_method" "http-method" {
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
http_method = "GET"
authorization = "CUSTOM"
authorizer_id = "${data.terraform_remote_state.api_state.Authorizers[var.Authorizer]}"
request_parameters = "${var.api_request_params_required}"
}
resource "aws_api_gateway_integration" "integration_GET" {
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
http_method = "${aws_api_gateway_method.http-method.http_method}"
integration_http_method = "POST"
type = "AWS"
uri = "arn:aws:apigateway:${var.aws_region}:lambda:path/2015-03-31/functions/${data.terraform_remote_state.lambda_alias.alias_lambda_arn}/invocations"
passthrough_behavior = "WHEN_NO_TEMPLATES"
request_templates = {
"application/json" = "${file("api_gateway_body_mapping.template")}"
}
}
resource "aws_api_gateway_model" "error_response" {
rest_api_id = "${aws_api_gateway_rest_api.api_gateway_rest_api.id}"
name = "ErrorResponse"
description = "The error respone object for all endpoints"
content_type = "application/json"
schema = <<EOF
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type" : "object",
"properties": {
"body": {
"type": "string"
},
"statusCode" : {
"type": "number"
}
}
}
EOF
}
resource "aws_api_gateway_method_response" "method_response" {
depends_on = ["aws_api_gateway_method.http-method"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "200"
}
resource "aws_api_gateway_method_response" "method_bad_request" {
depends_on = ["aws_api_gateway_method.http-method"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "400"
response_models {
"application/json" = "${aws_api_gateway_model.error_response}"
}
}
resource "aws_api_gateway_method_response" "method_not_found" {
depends_on = ["aws_api_gateway_method.http-method"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "404"
response_models {
"application/json" = "${aws_api_gateway_model.error_response}"
}
}
resource "aws_api_gateway_method_response" "method_error" {
depends_on = ["aws_api_gateway_method.http-method"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "500"
response_models {
"application/json" = "${aws_api_gateway_model.error_response}"
}
}
resource "aws_api_gateway_integration_response" "get_integration_response_success" {
depends_on = ["aws_api_gateway_method_response.method_response", "aws_api_gateway_integration.integration_GET"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "${aws_api_gateway_method_response.method_response.status_code}"
response_templates {
"application/json" = ""
}
}
resource "aws_api_gateway_integration_response" "get_integration_response_error" {
depends_on = ["aws_api_gateway_method_response.method_error", "aws_api_gateway_integration.integration_GET"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "${aws_api_gateway_method_response.method_error.status_code}"
selection_pattern = ".*statusCode['\"]\\s*:\\s*['\"]?500.*"
response_templates {
"application/json"="${file("api_gateway_exception_mapping.template")}"
}
}
resource "aws_api_gateway_integration_response" "get_integration_response_bad_request" {
depends_on = ["aws_api_gateway_method_response.method_bad_request", "aws_api_gateway_integration.integration_GET"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "${aws_api_gateway_method_response.method_bad_request.status_code}"
selection_pattern = ".*statusCode['\"]\\s*:\\s*['\"]?400.*"
response_templates {
"application/json"="${file("api_gateway_exception_mapping.template")}"
}
}
resource "aws_api_gateway_integration_response" "get_integration_response_not_found" {
depends_on = ["aws_api_gateway_method_response.method_not_found", "aws_api_gateway_integration.integration_GET"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "${aws_api_gateway_method_response.method_not_found.status_code}"
selection_pattern = ".*statusCode['\"]\\s*:\\s*['\"]?404.*"
response_templates {
"application/json"="{}"
}
}
api_gateway_exception_mapping.template:
#set($inputRoot = $util.parseJson($input.path('$.errorMessage')))
{
"Error":"$inputRoot.body"
}
The integration response mapping is as in below snapshot
We have create APIs with lambda integration in python where I threw a custom APIException as below and it worked.
class ApiException(Exception):
"""Our custom APIException class which derives from the built-in Exception class"""
def __init__(self, status_code, message: str, **kwargs):
self.status_code = status_code
self.message = message
kwargs["statusCode"] = status_code
kwargs["body"] = message
super().__init__(json.dumps(kwargs))
Inside the lambda handler:
from .utils import ApiException
def lambda_handler(event, context):
try:
"""
CODE FOR LAMBDA HANDLER
"""
except Exception:
ex = ApiException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
message='Internal Error')
print("exception string: %s", ex)
raise ApiException(
status_code=500,
message='Internal server error')
When I logged the exception, I got the following output
{
"statusCode": 500,
"body": "Internal Server Error"
}
I also referred this stackoverflow answer on how to get proper error codes in API Gateway response. I modified that a little bit to throw an exception instead of just returning a json with statusCode, response body and headers as I am not using AWS_PROXY integration type
APIException.cs
public class APIException : Exception
{
public int statusCode;
public string body;
public APIException() : base() {}
public APIException(int statusCode, string message): base(message) {
this.statusCode = statusCode;
JObject json = JObject.Parse(message);
this.body = json["body"].ToString();
}
}
Lambda handler:
namespace LambdaFunction
{
public class Function
{
public async Task<JObject> FunctionHandler(JObject events, ILambdaContext context)
{
try
{
ValidateQueryParams(events, context);
JObject response = JObject.Parse(#"{
'mesage': 'success',
}");
return response;
}
catch(HttpListenerException ex)
{
string err = (new JObject(
new JProperty("statusCode", ex.ErrorCode),
new JProperty("body", ex.Message)
)).ToString();
return new APIException(ex.ErrorCode, err);
}
catch(Exception ex)
{
int err_code = (int)HttpStatusCode.InternalServerError
string err = (new JObject(
new JProperty("statusCode", err_code),
new JProperty("body", "Internal Server Error")
)).ToString();
var err_ex = new APIException(err_code, err);
context.Logger.LogLine("Unhandled exception occurred: " + ex.ToString());
return err_ex;
}
}
}
}
I've logged the exception before throwing it to see what we are getting and this is what I got
{
"statusCode": 500,
"body": "Internal Server Error",
"StackTrace": null,
"Message": "{\n \"statusCode\": 500,\n \"body\": \"Internal Server Error\"\n}",
"Data": {},
"InnerException": null,
"HelpLink": null,
"Source": null,
"HResult": -2146233088
}
But with the above code, I'm still just getting response code as 200 with below response body
{
"errorType": "APIException",
"errorMessage": "{\n \"statusCode\": 500,\n \"body\": \"Internal Server Error\"\n}",
"stackTrace": [
"..."
]
}
I am not sure where I am going wrong. Any help will be appreciated. Thanks.
I've figured out the issue. C#'s .ToString() function which converts JObject into a string is formatting the string and adding new line characters \n by default. But the regex used in API gateway to identify error codes does not consider new line characters. The fix was pretty simple. We need to tell the .ToString() function that it shouldn't do any formatting. So, instead of
new JObject(
new JProperty("statusCode", err_code),
new JProperty("body", "Internal Server Error")
)).ToString();
You need to do
new JObject(
new JProperty("statusCode", err_code),
new JProperty("body", "Internal Server Error")
)).ToString(Formatting.None);
And it worked.

InvalidOperationException in Memory Streams

I am trying to upload an image to cloudinary cloud. The file converts fine to memory stream but when I try to call upload method of cloudinary to upload the image, I get InvlalidOperationException. What I think is, there is something wrong with converting file to stream.See the image showing error
[HttpPost]
public async Task<IActionResult> AddPhotoForUser(int userId, [FromForm] AddPhotoDto addPhotoDto)
{
try
{
if (userId != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
{
return Unauthorized();
}
var userFromRepo = await _datingRepository.GetUser(userId);
var file = addPhotoDto.File;
var uploadResult = new ImageUploadResult();
if (file.Length > 0)
{
using (var stream = file.OpenReadStream())
{
var uploadParams = new ImageUploadParams()
{
File = new FileDescription(file.Name, stream),
Transformation = new Transformation()
.Width(500).Height(500).Crop("fill").Gravity("face")
};
uploadResult = _cloudinary.Upload(uploadParams);
}
}
addPhotoDto.Url = uploadResult.Url.ToString();
addPhotoDto.PublicId = uploadResult.PublicId;
var photo = _mapper.Map<Photo>(addPhotoDto);
if (!userFromRepo.Photos.Any(p => p.IsMain))
{
photo.IsMain = true;
}
userFromRepo.Photos.Add(photo);
if (await _datingRepository.SaveAll())
{
var photoToReturn = _mapper.Map<ReturnPhotoDto>(photo);
return CreatedAtRoute("GetPhoto", new { id = photo.Id }, photoToReturn);
}
return BadRequest("Could not add photo");
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
Can you please share why do you use open stream? You can try:
var imageuploadParams = new ImageUploadParams () {
File = new FileDescription (#"https://res.cloudinary.com/demo/image/upload/v1561532539/sample.jpg"),
PublicId = "myimage",
Transformation = new Transformation().Width(500).Height(500).Crop("fill").Gravity("face")
};
var ImageuploadResult = cloudinary.Upload (imageuploadParams);

create a file and upload the chunks to the in team drive from C#

I Have to Upload the file to my teamdrive, the file has been created to team drive but I can not upload the file chunks to it. So, please help to solve it.
On Writing a Chunk I am facing the Error of "The remote server returned an error: (404) Not Found."
I am getting the Teamdrive ID and the File ID which has been created.
/*** Creation of a File to Team Drive ***/
f_ObjFile.TeamDriveId = "/*TeamDrive ID*/";
try
{
f_ObjNewFile.Parents = f_ObjFile.Parents; // f_ObjFile = <Team Driv ID>
f_ObjNewFile.Name = f_ObjFile.Name;
f_ObjNewFile.MimeType = f_ObjFile.MimeType;
f_ObjNewFile.TeamDriveId = f_ObjFile.TeamDriveId;
f_CreateRequest = GoogleHelper.InvokeApiCall(() => { return this.DriveServiceObj.Files.Create(f_ObjNewFile); }, this);
if (f_CreateRequest != null)
{
f_CreateRequest.SupportsTeamDrives = true;
f_CreateRequest.Fields = "*";
f_ObjNewFile = GoogleHelper.InvokeApiCall(() => { return f_CreateRequest.Execute(); }, this);
}
f_ObjDocumentItem = new DocumentItem(UserEmailID, f_ObjNewFile);
f_ObjDocumentItem.ItemID = f_ObjNewFile.Id;
string f_Url = GoogleHelper.CreateChunkURL("https://www.googleapis.com/upload/drive/v3/files/{0}?uploadType=resumable", f_ObjNewFile.Id);
f_ObjDocumentItem.ChunkUploadURL = InitiateResumeRequest(f_Url, f_ObjNewFile.Id);
}
catch(Exception ex) { }
finally
{
f_ObjNewFile = null;
f_CreateRequest = null;
}
/* Writing the chunks to the file in TeamDrive */
try
{
httpRequest = GoogleHelper.CreateHttpWebRequestObj(f_ObjChunkData.ChunkUploadURL,true);
httpRequest.Method = GoogleConstant.PATCH;
httpRequest.ContentLength = f_ObjChunkData.FileData.Length;
httpRequest.SendChunked = true;
httpRequest.Headers["Content-Range"] = "bytes " + f_ObjChunkData.StartOffset +
"-" +
f_ObjChunkData.EndOffset + "/" +
f_ObjChunkData.FileSize.ToString();
using (System.IO.Stream f_ObjHttpStream = GoogleHelper.InvokeApiCall(() => { return httpRequest.GetRequestStream(); }, this))
{
if (f_ObjHttpStream != null)
{
System.IO.MemoryStream f_ChunkStream = null;
f_ChunkStream = new System.IO.MemoryStream(f_ObjChunkData.FileData);
f_ChunkStream.CopyTo(f_ObjHttpStream);
f_ObjHttpStream.Flush();
f_ObjHttpStream.Close();
f_ChunkStream.Close();
f_ChunkStream = null;
}
}
using (HttpWebResponse httpResponse = GoogleHelper.InvokeApiCall(() => { return (HttpWebResponse)(httpRequest.GetResponse()); }, this))
{
if (httpResponse != null)
{
if (httpResponse.StatusCode == HttpStatusCode.OK)
{
httpResponse.Close();
}
}
}
}
catch (Exception ex) { }
In Followin Line :
string f_Url = GoogleHelper.CreateChunkURL("https://www.googleapis.com/upload/drive/v3/files/{0}?uploadType=resumable", f_ObjNewFile.Id);
Insted Of
"https://www.googleapis.com/upload/drive/v3/files/{0}?uploadType=resumable"
Use following URL :
https://www.googleapis.com/upload/drive/v3/files/{0}?uploadType=resumable&supportsTeamDrives=true
and its Done...
Now you can upload the chunks...

Read metadata in grpc on the server side c#

I am sending token in metadata from the client side
Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure);
ItemQuery item = new ItemQuery() { Id = "abc" };
var client = new MyService.MyServiceClient(channel);
Metadata data = new Metadata
{
{ "token", "Bearer xhrttt" }
};
var reply = client.GetItem(item, data);
But not able to find a way to fetch it in server side, Any help is appreciated
below is an example of how my server-side code looks(i tried certain other ways also)
public override Task<ItemResponse> GetItem(ItemQuery request , ServerCallContext context)
{
try
{
var a = context.RequestHeaders["token"]; // not working
ItemResponse itmRes = new ItemResponse();
if (request.Id == "foo")
{
itmRes.Items.Add(new Item() { Id = "foo", Name = "foobar" });
}
return Task.FromResult(itmRes);
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
return null;
}
Below is the code to fetch metadata in c#
Metadata.Entry metadataEntry = context.RequestHeaders.FirstOrDefault(m =>
String.Equals(m.Key, "token", StringComparison.Ordinal));
if (metadataEntry.Equals(default(Metadata.Entry)) || metadataEntry.Value == null)
{
return null;
}
Console.WriteLine("Token value is {0}", metadataEntry.Value);
for more details refer https://csharp.hotexamples.com/examples/Grpc.Core/ServerCallContext/-/php-servercallcontext-class-examples.html
Based on this tutorial, this and this, getting and setting metadata can be summarized:
GreeterService.cs (GrpcGreeter.csproj)
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
context.WriteResponseHeadersAsync(
new Metadata() { { "server_header", "nice to see you too" } });
context.ResponseTrailers.Add(
new Metadata.Entry("server_trailer", "see you later") { });
string? client_header = context.RequestHeaders.GetValue("client_header");
return Task.FromResult(new HelloReply
{
Message = $"i got your header, {request.Name}. it reads: {client_header}"
});
}
Program.cs (GrpcGreeterClient.csproj)
// The port number must match the port of the gRPC server.
using var channel = GrpcChannel.ForAddress("https://localhost:7143");
Greeter.GreeterClient client = new Greeter.GreeterClient(channel);
var call = client.SayHelloAsync(
new HelloRequest { Name = "GreeterClient" },
new Metadata() { { "client_header", "hey there" } });
Metadata headers = await call.ResponseHeadersAsync;
Console.WriteLine($"Server Header: {headers.GetValue("server_header")}");
HelloReply rsp = await call.ResponseAsync;
Console.WriteLine($"Server Response: {rsp.Message}");
Metadata trailers = call.GetTrailers();
string? myTrailer = trailers.GetValue("server_trailer");
Console.WriteLine($"Server Trailers: {myTrailer}");
Output:
Server Header: nice to see you too
Server Response: i got your header, GreeterClient. it reads: hey there
Server Trailers: see you later

Pushsharp 4.0.10.0 ApnsConfiguration connection error for iOS device tokens

I am using PushSharp 4.0.10.0 library to send the notification on iOS devices but it's not working. I have debugged it and found there is some ApnsConfiguration connection problem.
I am using this code to send the notificaiton:
public IHttpActionResult Notify()
{
HttpResponseMessage response = new HttpResponseMessage();
HttpContent requestContent = Request.Content;
string errorMessage = "Some error occured.please try again later";
HttpStatusCode responseCode = HttpStatusCode.Unauthorized;
string requestParameter = requestContent.ReadAsStringAsync().Result;
string tokan = "";
var r = Request;
var header = r.Headers;
try
{
if (requestParameter != null)
{
PushNotificationModel complaintModel = JsonConvert.DeserializeObject<PushNotificationModel>(requestParameter);
JsonConvert.DeserializeObject<PushNotificationModel>(requestParameter);
var appleCert = File.ReadAllBytes(HttpContext.Current.Server.MapPath("~/Images/User/xyz.pem"));
var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Production,
appleCert, "xyz");
// Create a new broker
var push = new ApnsServiceBroker(config);
int DeviceType = 1;
string deviceId = Convert.ToString(complaintModel.deviceToken);
string message = "New notification!!";
Guid complaintId = complaintModel.ComplaintId;
string detail = complaintModel.detail;
try
{
//System.Web.Hosting.HostingEnvironment.MapPath("~/Images/User/")
// var appleCert = File.ReadAllBytes(HttpContext.Current.Server.MapPath("~/Images/User/CTPwd.pem"));
push.OnNotificationFailed += (notification, aggregateEx) =>
{
aggregateEx.Handle(ex =>
{
// See what kind of exception it was to further diagnose
if (ex is ApnsNotificationException)
{
message = ex.Message;
}
else
{
message = "Not an APNSException";
}
// Mark it as handled
return true;
});
};
try
{
push.OnNotificationSucceeded += (notification) =>
{
message = "New Notification";
};
push.Start();
string appleJsonFormat = "{\"aps\": {\"alert\":" + '"' + message + '"' + ",\"sound\": \"default\"}}";
//string appleJsonFormat = "{\"aps\": {\"alert\": " + "Hello World" + ",\"sound\": \"default\"}}";
push.QueueNotification(new ApnsNotification
{
DeviceToken = deviceId,
Payload = JObject.Parse(appleJsonFormat)
});
push.Stop();
}
catch(Exception ex)
{
}
I have searched on google, but did not find any relevant answer. Is there any syntax problem ?
Thanks in advance.
Please use .P12 file format for push notification happy coding:)

Categories