How do I implement functions in a Bond services definition? - web-services

Looking at the Bond Comm documentation, it wasn't clear to me how the functions I define for services are connected to specific functions in my code.
Does it look for a function with the same signature in the project and assign it to the endpoint? Is there some underlying settings file I am missing?

NB: Bond Comm is deprecated. It isn't supported any more, and will be removed from Bond in an upcoming release. Bond-over-gRPC is its replacement.
When using either Bond-over-gRPC or Bond Comm, the generated server-side code is an abstract class with an abstract method for each method in the service definition. To provide your logic for these methods, you inherit from the generated base and provide implementations for all the service methods. Then, typically in your main function, you create a Server (for Bond-over-gRPC) or a Listener (for Bond Comm) and register an instance of the implementation class. This sets up the routing for IDL service method to your implementation code.
From the Bond-over-gRPC C# documentation:
Given a service definition like the following:
service Example
{
ExampleResponse ExampleMethod(ExampleRequest);
}
gbc will generate C# classes for gRPC with the --grpc flag:
gbc c# --grpc example.bond
...
To build the service functionality, simply write a concrete service
implementation by subclassing the server base and supplying the
business logic:
public class ExampleServiceImpl : Example.ExampleBase {
public override async Task<IMessage<ExampleResponse>>
ExampleMethod(
IMessage<ExampleRequest> param,
ServerCallContext context)
{
ExampleRequest request = param.Payload.Deserialize();
var response = new ExampleResponse();
// Service business logic goes here
return Message.From(response);
}
}
This service implementation is hooked up to a gRPC server as follows:
var server = new Grpc.Core.Server {
Services = { Example.BindService(new ExampleServiceImpl()) },
Ports = { new Grpc.Core.ServerPort(ExampleHost, ExamplePort, Grpc.Core.ServerCredentials.Insecure) } };
server.Start();
At this point the server is ready to receive requests and route them to the
service implementation.
There are more examples as well:
a standalone C# project
a C# ping/pong example
a C++ "Hello World" example
a C++ ping/pong example
It's worth pointing out that (Bond-over-) gRPC and Bond Comm are neither SOAP nor REST. The question was tagged with web-service, and sometimes people mean SOAP/REST when they talk about web services. I think of both gRPC and Bond Comm as custom binary protocols over TCP, although gRPC is run atop HTTP/2.

Related

Mock an Eureka Feign Client for Unittesting

i am using spring cloud's eureka and feign to communicate between some services (lets say A and B). Now id like to unittest my service layer of a single service (A). The problem is, that this service (A) is using a feign client to request some information of the other service (B).
Running the unittests without any special configuration throws the following exception: java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: service-b => but i do not want any server to run.
My question is: Is there a way to mock the feign client, so i can unittest my service (A) without running an eureka instance and service (B)?
Edit:
I ended up creating a stub for the feign client. The stub is marked as a primary component to force spring instantiating the stub within my tests.
This is the solution i came up with.
//the feign client
#FeignClient("user")
public interface UserClient {
UserEntity getUser();
}
//the implementation i use for the tests
#Component
#Primary //mark as primary implementation
public class UserClientTestImpl implements UserClient {
#Override public UserEntity getUser() {
return someKindOfUser;
}
}
The question is ... do you even need to mock? I often see that people mention "mock" as the first solution to anything that "should not be part of the unit test". Mocking is a technique, not the solution to everything. (see here).
If you are still at the early stages of your code, just refactor and use something else instead of depending on the concrete instance of the Feign Client. You might use an interface, an abstract class, a trait or whatever you want. Don't depend on the object itself, otherwise you have to "mock it".
public interface IWebClient {
public String get(...);
public String post(...);
}
To the question: but I will have other code that will do exactly the same (except that it will be on the concrete instance of Feign), what do I do then?
Well, you can write a functional test and call an instance of a web server that you can setup locally - or use Wiremock, as mentioned by Marcin Grzejszczak in one of the answers.
public class FeignClientWrapper implements IWebClient {
private feign = something
public String get() {
feign.get( ... )
}
public String post() {
feign.post( ... )
}
}
Unit tests are used to test algorithms, if/else, loops: how units work. Don't write code to make mocks fit - it must be the other way around: your code should have less dependencies, and you should mock only when you need to verify the behavior (otherwise you can use a stub or a fake object): do you need to verify the behavior? Do you need to test that a particular method gets called in your code? Or that a particular method gets called with X, Y, and Z for 3 times in a row? Well, then yes, mocking is ok.
Otherwise, use a fake object: what you want is to test just the call/response and maybe the status code. All you probably want is to test how your code reacts to different outputs (e.g., the field "error" is present or not in a JSON response), different status codes (assuming that the Client documentation is right: 200 OK when GET, 201 when POST, etc).
Mocking a feign client is really useful in microservice component tests. You want to test one microservice without having to start all the other microservices.
If you're using Spring (and it looks like you are), the #MockBean annotation together with a bit of Mockito code will do the job.
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment =
SpringBootTest.WebEnvironment.DEFINED_PORT)
public class TestYourComponent {
#Configuration
#Import({YourConfiguration.class})
public static class TestConfiguration {
}
#MockBean
private UserClient userClient;
#Test
public void someTest()
{
//...
mockSomeBehavior();
//...
}
private void mockSomeBehavior() {
Mockito.doReturn(someKindOfUser).when(userClient).getUser();
}
}
If you need to use a mock you can use Wiremock to stub the response for a given request - http://wiremock.org/stubbing.html. That way you will do integration tests with real HTTP requests sent. For unit testing the answer from #Markon is very good.

Creating webservice and client with JBossWS using Complex objects as arguments and return types

I am developing a WebService and Client for it using JBoss 5.1.0GA. The JBossWs stack was already preinstalled with the binary that I downloaded and as I understand it is JBossWs 3.1.2GA
I have developed a web service using this setup and have also created a client successfully. This is what I have.
A pojo web service deployed as a war file.
#WebService
public class Service{
#WebMethod
public CompleObj getConfiguration() {
CompleObj oConf = new CompleObj ();
for (int i = 0; i < 10; i++) {
NestObj oInst = new BOpRepoInstance("Val1", "Val2", "Val3", "Val4");
oConf.addRepoInstance(oInst);
}
return oConf;
}
}
Here,
CompleObj => is a Complex Object that has a list of type NestObj. Its
getter/setters, toString and some other methods.
NextObj => has 4 variables of Type String. Its getter/setters,
toString, hashCode, equals and some other methods.
Got this web service deployed successfully.
Later created a client using the eclipse wizard for generating Web Service Client using WSDL document. It also created a sample client file which would call the webservice and fetch the return value. This also worked like a charm.
Now my problem is, when eclipse generated stubs for clients it created classes for CompleObj and NestObj. These classes only has the variables and its getters/setters (this make sense as these are being generated from WSDL doc). Thus i loose a lot of other methods that includes toString, hasCode, equals etc, which I want to use at the Client side as well.
Now how can I make use of the actual class files defined in the WebService project directly and avoid the client to use the generated ones. I can provide the class files as .jar binary for the Client project, I cant really get how to achieve this.
Another question is, the web service location is embedded in the stubs directly, what can i do to have the webservice location passed as part of the argument to the invocation code?
The classes which are generated in the client side are just place
holders it is not deserilized version of your own classes,When you
invoke the service it is used to carry your object to server then
the JBOOSWS will do the JAXB mapping to the actual classes. So you
can not make the your own classes to be used in the client side
though they are look same.
URL will be fixed in the stub code, since in eclipse while generating WS client the first
thing you must provide is, the WSDL URL,then eclipse will generate the
client code accordingly,so generated code is specific to the WSDL
you provided. If you want to pass the WSDL dynamically,then you
need to have your own code to generate the client stubs by passed
WSDL URL using any WSDLtoJAVA or any other utility.

Flex Webservice

I'm using Flash Builder 4.5 and flex 4.5 language.
I'm using a webservice to retrieve data in json calling a .php.
<webservice:Webservice id="webservice" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>
<s:CallResponder id="testResult" result="onTestResult(event)"/>
...
private function onTestResult(e:ResultEvent):void{
Alert.show(ObjectUtil.toString(testResult.lastResult));
}
In the "Test Operation" window of Flash Builder I made my call and the return is a json Object made by arrays.
If I call the same webservice from the code instead, it returns a (object)#0 so an empty Object. No errors thown, just an empty Object.
Anyone has some tips?
The ns prefix of your Webservice class susggests you're using a custom implementation, rather than the framework WebService class. However, you don't provide any specifics, so I'm gonna take a swing in the dark:
If your custom service is based off the HTTPService class, make sure you're setting the resultFormat='text'. The default is XML, which will be causing you problems.
If you're using the Framework WebService class, well - you can't, as it's designed for SOAP webservices, not JSON. (From the Docs for mx.rpc.soap.WebService:)
The WebService class provides access to SOAP-based web services on
remote servers.
If it's some other implementation, please provide more details.

Mocking Web Services for client layer unit testing

I have a business rule visual studio class library (.NET 2.0) project that takes a dependency on Dynamics Crm Web Services - a classic SOAP web reference as opposed to a WCF endpoint. I want to unit test those business rules without having a real crm instance behind it. Adding a web reference doesn't produce an interface that I can fake. It does generate c# in my project that I think I can fake if I can create the interface. I don't think I need to actually navigate HTTP and get into all of the protocol stuff.
I saw Joh Skeet's blog post. Alas I didn't want to write any code and I'm hoping a tool has been written since then that might help. I tried some of his steps but concluded that he is smarter than me and I couldn't make that work.
I am aware of SoapUI, however, I was hoping for pure unit tests that would work in a CI build environment.
Is there a way to do this.
The standard way to mock something which doesn't come with an interface, is to build your own wrapper around it.
the code you want to mock, say the webservice stuff:
class AutoGeneratedStuff
{
public string GeneratedMethodYouUse()
{...}
public string GeneratedMethodYouDontNeed()
{...}
}
you then make an interface which covers only the bits of the code you need:
public interface IWebServiceClient
{
string MethodYouUse();
}
and a concrete wrapper class which implements it, which has a dependency to the generated stuff
class WebServiceClient : IWebServiceClient
{
private AutoGeneratedStuff _stuff;
public WebService(AutogeneratedStuff stuff)
{
_stuff = stuff;
}
public string MethodYouUse()
{
return _stuff.MethodYouUse();
}
}
then, in your code when you would have called the generated class, call your interface instead. In your unit tests, you can mock the interface, either using a mocking framework, or by implementing the interface with another concrete class that has no dependencies to the generated stuff

Factory pattern for test and live web services

Can web services be used in a factory pattern given that the code is auto-generated and I do not want to alter it (to add a base class for example)?
A reason to do this would be if you had 2 web services that were identical but one was for test data and one was for live data and you wanted to switch between the services based on the environment the code was runnig in.
[Edit]
I am using C# 3.
If you're using C# and SOAP, you can change the destination at runtime:
var webSvc = new WebServerObjectName();
webSvc.Url = "http://examples/com/foo.asmx";
//or pull from .config, etc.
webSvc.Url = ConfigurationManager.AppSettings["WebServiceUri"].ToString();
//make the call to the web method
var custs = webSvc.GetCustomerList();
The flow would be:
at design-time, make the web reference. Establish the contract, and code for it (input & output params). You'll only need to make it once, as long as the contract stays the same.
at run-time, change the URL/URI/target of the web service. Obviously it would have to have the same contract/params/method signature, otherwise the call would fail at runtime.
make the call