Spring webflux - Validate Query param & Path param - spring-webflux

Is there any better way to do query param validation in Spring webflux handler?
final Optional<String> productIdParam = request.queryParam("product_id");
int productId = 0;
if(!productIdParam.isEmpty()) {
productId = Integer.parseInt(productIdParam.get());
}

No, not with the 'functional' definition.
You could switch to definition with controllers and annotations which gives you validation of PathVariable's, RequestParam's and the RequestBody out of the box.
Take a look at the Spring Webflux docs

Related

does gin(go api framework) have IDL method like proto3 or thrift to define a api service?

does gin have an IDL method like proto3 or thrift to define a api service?
for example , i have an echo api
i want to define it like before
does gin has an IDL tool to generate basic code including field verify input, model generate?
message EchoRequest{
string content = 1;
}
message EchoData{
string content = 1;
}
message EchoResponse{
int status = 1;
string message = 2;
EchoData data = 3;
}
service{
api EchoResponse Echo(EchoRequest )(api.get='/echo')
}

Adding custom Response header to Spring WebFlux contoller endpoint

Is there a way to add a response header to spring webflux controller endpoint? for example to the following method I have to add a custom header say 'x-my-header'
#GetMapping(value = "/search/{text}")
#ResponseStatus(value = HttpStatus.OK)
public Flux<SearchResult> search(#PathVariable(
value = "text") String text){
return searchService().find(text);
}
In the functional API, this is really easy; the ServerResponse builder has builders for almost everything you need.
With the annotated controllers; you can return an ResponseEntity<Flux<T>> and set the headers:
#GetMapping(value = "/search/{text}")
public ResponseEntity<Flux<SearchResult>> search(#PathVariable(
value = "text") String text) {
Flux<SearchResult> results = searchService().find(text);
return ResponseEntity.ok()
.header("headername", "headervalue")
.body(results);
}
Note that the updated code doesn't need the #ResponseStatus annotation now.
UPDATE:
Apparently the solution above works; unless you have spring-cloud-starter-netflix-hystrix-dashboard dependency. In that case you can use the following code:
#GetMapping(value = "/search/{text}")
public Mono<ResponseEntity<List<SearchResult>>> search(#PathVariable(
value = "text") String text) {
return searchService().find(text)
.collectList()
.map(list -> ResponseEntity.ok()
.header("Header-Name", "headervalue")
.body(list));
}
A couple of things to note:
Outer type should be Mono<ResponseEntity<T>>: There is one response for request. If you declare it to be a Flux, Spring will try to deserialize the ResponseEntity as if it was a POJO.
You need to use an operator to transform the Flux into a Mono: collectList() or single() will do the job for you.
Checked with Spring Boot 2.0.3.RELEASE

How to implement an integration test to check if my circuit breaker fallback is called?

In my application, I need to call an external endpoint and if it is too slow a fallback is activated.
The following code is an example of how my app looks like:
#FeignClient(name = "${config.name}", url = "${config.url:}", fallback = ExampleFallback.class)
public interface Example {
#RequestMapping(method = RequestMethod.GET, value = "/endpoint", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
MyReturnObject find(#RequestParam("myParam") String myParam);
}
And its fallback implementation:
#Component
public Class ExampleFallback implements Example {
private final FallbackService fallback;
#Autowired
public ExampleFallback(final FallbackService fallback) {
this.fallback = fallback;
}
#Override
public MyReturnObject find(final String myParam) {
return fallback.find(myParam);
}
Also, a configured timeout for circuit breaker:
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
How can I implement an integration test to check if my circuit break is working, i.e, if my endpoint (mocked in that case) is slow or if it returns an error like 4xx or 5xx?
I'm using Spring Boot 1.5.3 with Spring Cloud (Feign + Hystrix)
Note i donot know Feign or Hystrix.
In my opinion it is problematic to implement an automated integrationtest that simulates different implementatondetails of Feign+Hystrix - this implementation detail can change at any time. There are many different types of failure: primary-Endpoint not reachable, illegal data (i.e. receiving a html-errormessage, when exprecting xml data in a special format), disk-full, .....
if you mock an endpoint you make an assumption of implementationdetail of Feign+Hystrix how the endpoint behaves in a errorsituation (i.e. return null, return some specific errorcode, throw an exception of type Xyz....)
i would create only one automated integration test with a real primary-enpoint that has a never reachable url and a mocked-fallback-endpoint where you verify that the processed data comes from the mock.
This automated test assumes that handling of "networkconnection too slow" is the same as "url-notfound" from your app-s point of view.
For all other tests i would create a thin wrapper interface around Feign+Hystrix where you mock Feign+Hystrix. This way you can automatically test for example what happens if you receive 200bytes from primary interface and then get an expetion.
For details about hiding external dependencies see onion-architecture

WCF Data Service Method for Aggregation with filter

I need to aggreate some data of my wcf data service in order do something like a "monthly report". Afaik aggregation is not possible via the odata protocol. I guess I have to implement my own WebGet method for this (or is there an other possibility?). My first shot would be:
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any, UseSynchronizationContext = false)]
class MyDataService : DataService<MyContext>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.UseVerboseErrors = true;
}
[WebGet]
public int SumColumnOfMyTable()
{
// return here the aggregated data with the usage of the odata $filter param
}
}
I want to use the $filter param of the odata protocol to filter the aggreagtion. Is this possible? Is this the right way to do aggregation with WCF Data Services? I'm quite clueless and can't find any useful information about that. Thanks in Advance...
After rethinking this I came to the conclusion that the best and easiest way would probably be a database view. This means I could create an extra Entity that maps to the view and that then can be accessed via the data service. However this gives me an issue, because the view has no primary key...
Any other ideas?
UPDATE: I resolved the primary key issue by genarating an ID for each row in the view (Firebird):
coalesce(cast(rdb$get_context('USER_TRANSACTION', 'row#') as integer), 0) + 1 as ID
However it seems there is no "clean" solution for this problem with wcf data services?

Returning wcf/json result from the wcf service

I Need by service contract to return the xml/json result depending on the request type.I also need a kind of helper function which will convert my result set (i am using linq to sql) so that i do not need to create the xml format for the result set by iterating through the table row many times.What is the suitable way to do that.
I need a kind of short cut method which will convert the table data to xml result.Had i been using asp.net mvc i would have been able to generate the xml data by overriding the the ExecuteResult method in the ActionResult and giving Conetnt-Type = "text/xml" as OP.But since i am using
Wcf i don't have the controller context(as controller context is the parameter that needs to be passed to Execute Result).
My present code for converting the table data to the xml format is below.
public XDocument UsersLists(string authToken)
{
bool IsAuthenticated = Authenticate(authToken);
XDocument xDoc = new XDocument();
XElement root = new XElement("Users");
if (IsAuthenticated)
{
List<User> lstUsers = _lService.UserRepository.GetUserCompanyFromAccountID(GetAccountId(authToken)).ToList();
if (lstUsers != null)
{
root.Add(new XElement("Message", "Success"));
foreach (var u in lstUsers)
{
XElement chid = new XElement("User");
root.Add(new XElement("UserId", u.UserId));
root.Add(new XElement("FirstName", u.FirstName));
root.Add(new XElement("LastName", u.LastName));
root.Add(new XElement("Email", u.Email));
root.Add(new XElement("CompanyName", u.Company.CompanyName));
root.Add(chid);
}
xDoc.Add(root);
return xDoc;
}
else
{
return ReturnFailure(xDoc, root);
}
}
else
{
return ReturnFailure(xDoc, root);
}
}
I need to eliminate this way of generating xml for each table records.
An early response is priceless.
Thanks
Technology : Windows Communication Foundation.
Implementation of single operation returning both XML or JSON differs between WCF 3.5 or WCF 4.0. For implementing this feature in WCF 3.5 check this thread. Generally you will have to create custom behavior and set the content type based on Accept header from the request. WCF 4.0 has native support for this feature. WebHttpBehavior has property AutomaticFormatSelectionEnabled. If you set this property to true it should just work out of the box.
To your second question. You don't need any custom formatting like in ASP.NET MVC. Formatting in WCF is handled by serialization. Just return collection from your operation and you will see what happens. Linq-To-Sql generated entities should be serializable by default. Just don't forget to execute query before returning from method. If you need special format of date which is not the same as Linq-To-Sql entities create custom data type which have public parameterless constructor and all required properties with getter and setter. If you want to make it clear makr that class with DataContract attribute and all properties with DataMember attribute. Return collection of that custom class instances from your operation.