How to execute a from statement inside a rest component in camel? - amazon-web-services

I am using apache camel for this.I have an http server. When I do a get request on a url it should fetch a file from a bucket in aws s3 and then create a file in my local directory.
public static class HelloRoute extends RouteBuilder {
#Override
public void configure() {
rest("/")
.get("file-from-s3")
.route()
.from("aws2-s3://bucketname?accessKey=INSERT&secretKey=INSERT&region=us-east-1&prefix=hello.txt")
.to("file:/tmp/")
.endRest();
}
I wrote the above code for this but it looks like it's ignoring the "from" statement and directly executing the "to" statement and hence creating an empty file in my tmp directory. Is there some other way to do this?

Related

Swashbuckle: Customize endpoint path (AspNetCore)

I have this setup where I want to organize multiple APIs served by the same application
.
For each api I get the prefix from the subdomain and redirect it to the application server, example:
user.api.example.com/v1/profile --> api.example.com/user/v1/profile
admin.api.example.com/v1/companies --> api.example.com/admin/v1/companies
With this setup, I need to remove the path prefix ("/user", "/admin") when generating the swagger json file.
Is it possible to configure a function that will manipulate the path for each endpoint before generating the json file?
I only want to alter what goes into the swagger json file, not the actual endpoint path!
Document Filters were the answers to that particular need:
public class PathPrefixDocumentFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
var editedPaths = new OpenApiPaths();
foreach(var kv in swaggerDoc.Paths)
{
var newKey = string.Join("/", kv.Key.Split('/').Skip(2));
editedPaths.Add("/"+newKey, kv.Value);
}
swaggerDoc.Paths = editedPaths;
var a = swaggerDoc.Paths;
}
}

How to send the contents of a file downloaded from aws s3 using apache camel in json format?

I have a rest api using apache camel. When I hit a post request on a route, it gets a file from S3. Here is the code for that ->
public static class HelloRoute extends RouteBuilder {
#Override
public void configure() {
rest("/")
.post("file-from-s3")
.route()
.setHeader(AWS2S3Constants.KEY, constant("filename"))
.to("aws2-s3://bucketname?accessKey=INSERT&secretKey=INSERT&region=INSERT&operation=getObject")
.endRest();
}
}
This gives the content of the file in Postman. I want the response in a json format where the contents of the file will be in the content key of json. How to do this?
Make sure you have binding mode enabled (auto|json) in your REST configuration and the consumes/produces set on your route. Now write your processor to build your response object and set it in the body. Camel will handle the rest for you.
public static class HelloRoute extends RouteBuilder {
restConfiguration().component("netty-http").host("localhost").port(portNum).bindingMode(RestBindingMode.auto);
#Override
public void configure() {
rest("/")
.post("file-from-s3")
.consumes("application/json").type(YourRequest.class)
.produces("application/json").outType(YourResponse.class)
.route()
.setHeader(AWS2S3Constants.KEY, constant("filename"))
.to("aws2-s3://bucketname?accessKey=INSERT&secretKey=INSERT&region=INSERT&operation=getObject")
//.process("responseBuilderProcessor")
.endRest();
}
}

Set the AWS S3 Key header in the URI only

I have a rest api using apache camel. When I hit a post request on a route, it should get a file from S3. I am sending json data(filename, bucketName, accesskey, secretkey, region) in order to extract the file from s3. Here is the code for that ->
public static class HelloRoute extends RouteBuilder {
#Override
public void configure() {
rest("/")
.post("file-from-s3")
.route()
.setHeader(AWS2S3Constants.KEY, constant("filename"))
.to("aws2-s3://bucketnameaccessKey=INSERT&secretKey=INSERT&region=INSERT&operation=getObject")
.to("file:/tmp/")
The issue is that I don't want the .setHeader(AWS2S3Constants.KEY, constant("filename"))
part. Is there a way to remove that and put an alternate to that in the URI itself. I tried something like this ->
public static class HelloRoute extends RouteBuilder {
#Override
public void configure() {
rest("/")
.post("file-from-s3")
.route()
.to("aws2-s3://bucketnameaccessKey=INSERT&secretKey=INSERT&region=INSERT&filename=hello.txt&operation=getObject")
.to("file:/tmp/")
But this is giving me an error java.lang.IllegalArgumentException: AWS S3 Key header missing.. Is there some other way to do this?
Sometimes build an AWS Request can be complex, because of multiple options. We introduce the possibility to use a POJO as body.
Take a look at: https://camel.apache.org/components/latest/aws2-s3-component.html#_using_a_pojo_as_body

simple azure web service, http404 error on publish when adding /dowork to URL

I am trying my first web app service using Azure services. I've created it in VS, and it works locally. All it does it return a string that says "hello user" is JSON.
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1
{
// To use HTTP GET, add [WebGet] attribute. (Default ResponseFormat is WebMessageFormat.Json)
// To create an operation that returns XML,
// add [WebGet(ResponseFormat=WebMessageFormat.Xml)],
// and include the following line in the operation body:
// WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
[OperationContract]
[WebGet(UriTemplate = "/DoWork")]
public string DoWork()
{
// Add your operation implementation here
return "hello user";
}
// Add more operations here and mark them with [OperationContract]
}
}
Problem is when I publish it, says successful. I can see it running on portal.
When I goto published site I get the standard THIS WEB APP HAS BEEN SUCCESSFULLY CREATED, but... when I add the /DoWork to the URL I get HTTP error 404.
I know I must be missing something simple...
any ideas?
you're missing the name of the service. In your case would be something like:
http://engineappservicev001.azurewebsites.net/something.svc/dowork
More info in here:
http://www.codeproject.com/Articles/571813/A-Beginners-Tutorial-on-Creating-WCF-REST-Services

How can you call a URL without opening a browser in C/Side?

We are using C/Side on one server to try to call a URL to a PHP script on another server without opening a browser window. We want the script to run as a background process. So far, everything we've tried opens a browser. Any suggestions?
I used HttpClient to do this. But it's not that straight forward in Nav, since you cannot call an asynchronous method and assign its return value to a variable. So I created a wrapper class in c#.
public class NavHttpClient
{
private HttpResponseMessage responseMsg;
public HttpResponseMessage ResponseMsg
{
get { return responseMsg; }
}
public async Task GetAsync(string requestUri)
{
HttpClient client = new HttpClient();
responseMsg = await client.GetAsync(requestUri);
}
}
Then I exported this class in a class library. Now I can use it Nav this way:
NavWebClient : DotNet NavWebClient.NavHttpClient.'NavWebClient, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
NavWebClient := NavWebClient.NavHttpClient;
NavWebClient.GetAsync('http://localhost').Wait;
IF NavWebClient.ResponseMsg.IsSuccessStatusCode THEN
...
Is this solution suits your needs? Inside there is link to codeunit for Nav 2013 that allows to work with web services in Nav style.