I'm trying to figure out if it is possible to handle all exceptions that had been thrown by the bunch of microservices in certain one.
For example, i have microservice called ui. It handles all ui related stuff and serves as a Zuul gateway. It contains custom error page. Also i have microservice called foo. When foo throws exception i want ui to handle it i.e show ui's custom error page. I dont want foo or any other service to contain any error pages.
Is there a way to achieve such behavior?
I would suggest using an error controller and then having all your micro services redirect to that uri when experiencing an error.
Check out this tutorial he explains setting up a custom error page pretty well.
http://www.baeldung.com/custom-error-page-spring-mvc
Related
I have a kubernetes cluster and i have more than 15 microservices running in it, Each REST API send me a custom header lets say "version":"1.2.0", i need to check this version from each REST api and throw a custom error if it doesn't match with the value i have.
Suppose i have a mobile app and i have released a new version of the app and redeployed the microservices to match the new app, i want to throw a custom error to users using the old application to download the new app to continue using the application.
Is there a way to achieve this using ingress-nginx or in the kubernetes level instead of repeating logic in each microservice.
With Nginx ingress, you will be able to inject the secret into the request if it's coming outside and forward request to service
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header My-Custom-Header $http_my_custom_header;
since as your all microservices talking internally and routing based on custom header you can use the service mesh istio
for example : https://istio.io/latest/docs/tasks/traffic-management/request-routing/#route-based-on-user-identity
https://dwdraju.medium.com/simplified-header-based-routing-with-istio-for-http-grpc-traffic-ff9be55f83ca
ingress-nginx supports configuration snippets as an annotation.
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($http_version != "1.2.0") {
return 418;
}
You can configure the ingress to capture certain error codes so the default backend app receives these requests and can build a custom error response. Be aware that this captures all listed error codes. So don't use a status code that the rest of your application might or you might hide a real error response.
I'm new to url rewriting process in Marklogic and need help to resolve the below issue.
I have written Xquery implementation to redirect my API endpoints to the respective Xquery modules as /rewriter-ex/rewriter.xqy.
xquery version "1.0-ml";
let $url := xdmp:get-request-url()
return if(fn:matches($url,"/fetchRecord")) then
fn:replace($url,"/fetchRecord","/lib/fetch-record.xqy$1")
else if(fn:matches($url,"/saveRecord")) then
fn:replace($url,"/saveRecord$","/lib/save-record.xqy")
else (xdmp:set-response-code(404, "Not found"),"/no/such/resource")
And the url-rewriter path in the App server configuration is set to /rewriter-ex/rewriter.xqy and rewrite resolves globally parameter is set to true in App server.
I'm able to redirect my API urls to the respective endpoints.But I'm not able to use predefined ML Res-API endpoints like /v1/documents,it is showing 404 error as returned in the rewriter.xqy.
Is there a way I can implement rewriter to support both rest api endpoints as well as custom API endpoints?
If you'd like to create your own RESTful API on top of MarkLogic, with your own custom end-points. Please check out XQuery API for RESTful Services (XQRS).
declare
%rest:path("/fetchRecord/{$record-id}")
%rest:GET
function fetch-record($record-id as xs:string) {
fn:doc($record-id)
};
declare
%rest:path("/saveRecord/{$record-id}")
%rest:PUT("{$doc}")
%xdmp:update
function put-record($record-id as xs:string, $doc as document-node(element())) {
xdmp:document-insert($record-id, $doc)
};
Your RESTXQ Modules can sit on their own separate HTTP App Server (on their own port) and live side by side with another HTTP App Server which has the default MarkLogic REST API on it.
XQRS is totally compatible with the rest of MarkLogic's software, including Data Hub Framework, they can party together.
The REST API doesn't support customization or replacement of the default declarative rewriter configured during initialization of a REST API server. In addition, the REST API doesn't provide an XQuery API interface to the functionality of the REST API endpoints.
Instead, the recommended approach is to extend the REST API through one of the following alternatives:
Providing an endpoint module in the modules database and specifying the actual path of the module in the modules database on a request to the REST API server to invoke the endpoint without rewriting as in http://myhost:8010/the/directory/path/to/my/module.xqy
Such endpoints can be Data Service endpoints. See https://docs.marklogic.com/guide/java/DataServices
Using the /v1/invoke endpoint to invoke a main module. See https://docs.marklogic.com/guide/rest-dev/extensions#id_72813
Using a Resource Service Extension. See https://docs.marklogic.com/guide/rest-dev/extensions#id_41710
Hoping that helps,
Thanks for your answers.I'm planning to use two app servers one for rest calls and other for API calls.These two app servers will point to the same DB.Please let me know if this is a right approach.
I have an issue. I built a Spring(+REST, AngularJS, Java and that's about the most important technologies used) application(using JHipster), but I have some difficulties testing it. I try to run requests using Postman(http://localhost:8080/api/users, for example, which is a URI generated by default when you build your JHipster application), but I get the "Full authentication is required to access this resource error". Now I imagine that this could be bypassed by using some sort of token, but I was wondering if there was something I could do to get rid of this. I mean, for example, if I wanted http://localhost:8080/api/users to be accessible without having to log in, you know, display the whole list of users on a website page to everyone, not only to those that have an account, what would I need to do?
Thank you
If you use microservices with JHipster, each microservice has MicroserviceSecurityConfiguration. There you have an overriden configure method which usually has a part like:
.and()
.authorizeRequests()
.antMatchers("/api/profile-info").permitAll()
.antMatchers("/api/**").authenticated()
You can define /api/users similar to api/profile-info. You can also play with permissions in this file and so on.
And something like this surely exists for a monolith app.
I have been viewing several Spring MVC Controller examples, and the ones I've found show one controller handling multiple views. Which this approach seems fine, but which I could see becoming clumsy in a large web-sites.
Given something like:
Accounts
/AcctsRec
/AcctsPay
I can see where one Account controller would work for that setup.
Now Add:
Security
/Login
/Rights
Again I can see one Security Controller.
But now add in something like. If Security/Rights allows access to Accounts/AcctsPay. Would that be a third controller? Or would Security/Rights pass an object to Accounts/AcctsPay? Or Accounts Controller?
How would that work?
A pseudo code example, a pointer to a web-site example, or anything helpful would be appreciated.
Only please don't direct me to the Spring's documentation. I've read that a couple to times and just can't seem to gleam much from it.
But now add in something like. If Security/Rights allows access to Accounts/AcctsPay. Would that be a third controller? Or would Security/Rights pass an object to Accounts/AcctsPay? Or Accounts Controller
I think there is some confusion as to what is going on because the above doesn't make any sense. The paths you have above are URLs. Each one typically maps an HTTP request to a #Controller handler method that produces an HTTP response.
Perhaps /Accounts/AcctsPay is not accessible without authentication and authorization. And maybe /Security/Login authenticates you and /Security/Rights gives you some permissions. In this scenario, you would need to send a request to /Security/Login to get authenticated, then another request to /Security/Rights to get some permissions, and finally a request to /Accounts/AcctsPay to perform some action.
A #Controller method is meant for handling requests. Handling it by responding with a 401 Unauthorized or 403 Forbidden is still a valid response.
I am new to spring integration and am in the process of getting a hold of the components. The requirement is as follows. Get an XML message , validate the data using a web service call and process the valid or invalid data accordingly. We currently use a router to validate the data and route the original payload as per the validation result. I have an alternate approach in mind to segregate this flow. I would like the router to perform only the routing job . For the web service validation , I am thinking of using a service activator . This in turn will pass the routing information to the router - could be by using a header enricher. I have some questions here . Is this the best practice? If so, how best can we pass the validation information received from the webservice to the router?.Also, will the addition of more components not negate the advantages we get by component segregation? Please help.
Regards,
Aravind.
To help with a best practice approach consider a clear separation of responsibilities and what the validation is as a part of the flow. For instance, you may consider the validation to actually be a filter, where only valid messages pass through and invalid are directed to a rejection channel. The filter approach will work if you can distill the validation results toa boolean scenario.
(By the way, try to avoid extending Spring Integration classes/interfaces and instead create POJO services that you can reference. Makes it easier to test and maintain)