I am trying to integrate PubNub with KaaIoT platform where the publish API is throwing the following error/exception:
Following is the code showing a sample message that I am trying to publish:
PNConfiguration pnConfiguration = new PNConfiguration();
pnConfiguration.setSubscribeKey("sub-c-7c052466-04ea-11e5-aefa-0619f8945XXX");
pnConfiguration.setPublishKey("pub-c-12a0e504-b46c-4c9c-ba5d-089ae589bYYY");
PubNub pubNub = new PubNub(pnConfiguration);
try {
HashMap<String, String> data = new HashMap<String, String>();
data.put("value", "39");
data.put("since", "07:00 AM");
pubNub.publish()
.message(data)
.channel("TEMP")
.sync();
System.exit(0);
} catch(Exception ex) {
System.out.println("Got PubNubException..." + ex.toString());
throw ex;
}
If I try this above sample code as a standalone application, it is working fine. However, inside kaaiot, it is not working. And, I am not able to make out much from the log.
Any idea what might be causing the sync method to fail?
Can you call any other rest based endpoint? The SDK is making rest calls under the covers. The log, although not very informative, seems to point to not being able to make a rest call.
It also maybe kaaiot, do they allow generic http request?
Related
How do we convert the Flux<DataBuffer> of ClientHttpResponse to Mono<SomeDto>. Also, can we get access to MessageHeaders in the bodyExtractor. Please suggest.
.handle(WebFlux.outboundGateway(apiUrl, webClient)
.httpMethod(POST)
.mappedRequestHeaders(CONTENT_TYPE)
.bodyExtractor((clientHttpResponse, context) -> validateAPIResponse(clientHttpResponse)))
private Mono<Object> validateAPIResponse(final ClientHttpResponse clientHttpResponse) {
var httpStatus = clientHttpResponse.getStatusCode();
// check for 500
if (httpStatus.is5xxServerError())
throw new SomeException(.......);
var responseMono = new Jackson2JsonDecoder().decodeToMono(clientHttpResponse.getBody(), ResolvableType.forClass(SomDto.class), null,
null);
// check for any other than 200
if (!httpStatus.is2xxSuccessful())
return responseMono.map(response -> {
throw new SomeOtherException(response.getSomeField(), httpStatus);
});
You can just delegate to BodyExtractors.toFlux(SomDto.class). I'm not sure if you really need a custom BodyExtractor, if just expectedResponseType(SomDto.class) should be enough for you produce such a Mono. Not sure also if you need to handle those errors yourself: the framework does a decent job on the matter.
Yes, you cannot get access to MessageHeaders in this BodyExtractor context since it has nothing to do with messaging.
You can get access to those headers a bit downstream when you already got a reply from this WebFlux gateway. If your reply is really very tied to headers, then you need to look into producing a generic reply (like that Flux<DataBuffer>) and then convert it appropriately downstream in a transformer where you already get access to the whole request message and its headers.
See also this in docs:
Spring Integration provides ClientHttpResponseBodyExtractor as a identity function to produce (downstream) the whole ClientHttpResponse and any other possible custom logic.
I have created a c# based web hook in an azure function app, based on Adrian Halls excellent book on github.io
The web hook and app is running successfully when tested in portal.
When i call the webhook from my controller i can see i have the correct parameters and uri. But for some reason my function app never enters my method and give me an error saying:
The 'code' query parameter provided in the HTTP request did not match the expected value
My problem is that i do have my code query parameter in the request.
Basically i just want to trigger the webhook when a new todoitem is inserted in my database.
Anybody know what could be the problem?
Code:
Call from api controller to webhook method in backend
// POST tables/TodoItem
public async Task<IHttpActionResult> PostTodoItem(TodoItem item)
{
TodoItem current = await InsertAsync(item);
Webhook.SendAsync<TodoItem>(new Uri(WebhookUri), current);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
Webhook method in backend
public static async Task<HttpStatusCode> SendAsync<T>(Uri uri, T data)
{
var httpClient = new HttpClient();
httpClient.BaseAddress = uri;
var response = await httpClient.PostAsJsonAsync<T>("",data);
return response.StatusCode;
}
Function in azure
#r "Newtonsoft.Json"
using System;
using System.Net;
using Newtonsoft.Json;
public static async Task<object> Run(HttpRequestMessage req, TraceWriter log)
{
log.Info("Webhook triggered");
string jsonContent = await req.Content.ReadAsStringAsync();
dynamic data = JsonConvert.DeserializeObject(jsonContent);
log.Info($"Created New Todo ({data.Text}, {data.Complete})");
return req.CreateResponse(HttpStatusCode.OK);
}
Had the same issue today. Go to the Manage panel of your Azure Function. There you can copy the "default" key which works
Anders,
There are indeed some issues with the key management UI on the portal and those are being addressed (you can track one that was likely impacting you here
A workaround, at the moment, is to make sure you're using the appropriate key by opening the "keys" panel for the function and selecting the "default" function key, using that as the code.
There is also an API you can use to request the keys directly from the runtime, here's an example of invoking that API to retrieve the keys for a given function:
https://<functionappname>.azurewebsites.net/admin/functions/<functionname>/keys?code=<your admin key>
This must be a bug in azure functions app.
I created a couple of web hook functions more to see if i could hit one of those.
No success same error as before.
But then i went back to my old function and suddenly it worked. I don't know why one of my new web hooks i tested on is a copy of the old one and it is still not working. Maybe an azure functions expert know more about this.
I started to work with SignalR on Visual Studio 2012, so far I got the basic hang of it, I guided myself through this example (You can browse the code in the page). I decided I wanted to add a REST service to said example, so I added a basic service to it and it worked.
The next step I wanted to take was to add a communication between the service and SignalR, so according to what the example showed to me, I only needed to create a HubConnection through the url in my project (in this case, the example uses the url http:localhost:4200). You can check the WorkerRoleHubConfiguration class, it has a method that has the next line:
return RoleEnvironment.GetConfigurationSettingValue("GUI_URL");
Where GUI_URL is http:localhost:4200.
In my service class then I just added a method with the following:
var url = RoleEnvironment.GetConfigurationSettingValue("http://localhost:4200");
try
{
HubConnection _connection = new HubConnection(url);
IHubProxy _hub = _connection.CreateProxy("SiteMonitR");
_hub.Invoke("displayResult");
}
catch (Exception ex)
{
error = ex.ToString();
}
But that throws an exception, this one.
I don't undertand why I can get the url in the same way the example does, as I'm doing everything as it's done on the Server class.
The goal I'm trying to achieve is that when an endpoint is accesed and something changes in my system, SignalR notifies to the clients connected to it.
I hope anyone can help me understand what's wrong with my work.
EDIT
I'm adding my ServiceConfiguration.Local.cscfg, my ServiceConfiguration.Cloud.cscfg and ServiceDefinition.csdef files as reference here, I think the problem should be around there but to be honest I got no idea as to why this isn't working.
EDIT 2
I'm getting the following exception at this line var url = RoleEnvironment.GetConfigurationSettingValue("http://localhost:4200");
The exception is:
SEHExcetion occurred. External component has thrown an exception.
The URL is for a GUI - it has to be a web interface for signalr to negotiate the hub connection. In the example, the hub (server) sends updates to connections coming from the configured URL - again a web interface (html page).
The logic to communicate needs to reside in the Server class and be called from the worker role. For example, after making a call to your service in the worker role, then call server.DoSomething("message") to invoke a message to the server. THat code would look something like:
public Class Server
{ ...
public void DoSomething(string message)
{
_hub.Invoke("doSomething", message);
}
...
}
Then in Server.Run() add:
// whenever a DoSomething is called
_hub.On<string>("doSomething", (message) => _hub.Invoke("doSomething", message));
And in SiteMonitRNotificationHub
public class SiteMonitRNotificationHub : Hub
{
...
public void DoSomething(string address)
{
Clients.doingSomething(address);
}
...
}
Finally in the controller script in the web gui:
c.siteMonitorHub
...
.on('doingSomething', function (message) {
c.doSomething(message);
})
and...
this.doSomething= function (message) {
// do something in your web page with message
};
I'm trying to get a minimal app working using ServiceStack.Razor, and I'm having trouble getting a CustomHttpHandler to work. I've followed the instructions here and here, but it's not working right.
I'm using the following code to register a custom http handler for HttpStatusCode.BadRequest:
public override void Configure(Container container)
{
this.Plugins.Add(new RazorFormat());
this.SetConfig(new EndpointHostConfig
{
CustomHttpHandlers =
{
{ HttpStatusCode.NotFound, new RazorHandler("/notfound") },
{ HttpStatusCode.BadRequest, new RazorHandler("/error") }
},
DebugMode = true
});
}
The thing is, the /notfound handler works perfectly for 404s, but no matter what I do, I can't get the /error razor file to display whenever an ArgumentNullException is thrown.
My service method looks like this:
public object Any(Hello request)
{
if (string.IsNullOrEmpty(request.Name))
{
throw new ArgumentNullException("Name");
}
return new HelloResponse { Result = "Hello " + request.Name };
}
ServiceStack returns a 400 status, which is fine, but it still displays the view I have for HelloResponse:
What am I missing? Am I misunderstanding how CustomHttpHandlers are supposed to work?
For reference, I put the project up on github.
Yeah the CustomHttpHandlers are just meant for handling un-handled system generated errors. Currently they're limited to:
NotFound (404) for un-handled requests
Forbidden (403) when a request is made to an forbidden file or resource
These are the errors happen outside of ServiceStack and so isn't able to be handled by existing ServiceStack's event hooks or user-defined custom logic, so we allow users to modify the behavior in this case via CustomHttpHandlers.
The Error Handling wiki describes how to handle errors in ServiceStack.
Though it might make sense (since it's opt-in) to allow a fallback after the exception is handled to allow it to be further handled by rendering it to a user-specified page, that you're expecting to do here.
We'll look at trying to explore something like this in the future. Feel free to add future feature requests like these to ServiceStack's issue list so we don't forget.
Is there a way to log the validation results which get populated in the ResponseStatus when you have the ValidationFeature plugin enabled?
From what i can understand, any requests coming in get validated and if the validation passes then it goes to the service. Using request filters i can log the requests coming in however using the response filters i can only log valid requests.
I trying to log all responses especially HttpStatus 400 (Bad request) which is returned as a result of a validation error.
I have also tried to play a bit with the RequestLog plugin but from what i understood what gets logged are only valid request (i.e requests that went to the service).
I hope you understand what i am trying to say.
Look to see how 7digital have customized ServiceStack's Validation Feature to support logging.
Related Features
The new API supports the concept of a ServiceRunner you can override to add your own event and exception hooks you can read about in the wiki.
There is also the built-in Request Logger that lets you expect details of the more recently processed requests.
Create an issue on the GitHub project if you want to see logging in the validation feature.
A quick way to log errors from the ValidationFeature plugin is simply thus:
public override void Configure(Container container)
{
...etc...
Plugins.Add(new RequestLogsFeature() { etc });
Plugins.Add(new ValidationFeature()
{
ErrorResponseFilter = MyValidationError
});
...etc...
}
public object MyValidationError(ValidationResult validationResult, object errorDto)
{
Container.Resolve<IRequestLogger>().Log(null, null, errorDto, TimeSpan.Zero);
return errorDto;
}
However, in my case, I realized that logging validation errors in the service itself is not the proper place; I instead log these errors in the applications that consume the service.