Design pattern to distinguish call as Web Service vs. Local - web-services

I have to come up with a design for service lookup i.e. decide on whether the service request can be handled locally or should be sent to a remote server (using SOAP Web Service calls). The first thing that comes to my mind is Service Locator.
Are there any other design patterns that fit the requirement? Any pointers or sample code would be helpful?

Service locator + Factory is exactly what you need.
The code , in my humble opinion, should look like this:
public enum ServiceOrigin {
REMOTE,LOCAL;
}
public class ServiceLocatorFactory {
MyService getService(ServiceOrigin origin) {
///Return a proper service instance
}
}
public interface MyService {
void doSomething();
}
ServiceLocatorFactory factory = //Get the factory somehow
MyService service = factory.getService(ServiceOrigin.REMOTE);
service.doSomething();

You can use Dependency Injection. If clients are unaware of where service are located (whether locally or remote), they should depends on abstractions:
public interface MyService {
void doSomething();
}
public class MyClientThatUsesMyService {
private MyService _service;
public MyClientThatUsesMyService(MyService service) {
_service = service;
}
public void Go() { _service.doSomething(); }
}
Then you can use a Dependency Injection container or (Poor Man's DI) to configure your composition root and set lifetime of the objects.

Related

Micronaut application AWS Lambda - Http Requests and Responses filter

I am running a Micronaut app in an AWS Lambda as explained here : https://guides.micronaut.io/latest/mn-application-aws-lambda-java11.html
How am I supposed to implement a Request/Response filter ? I want a functionality like a good old Servlet filter. I read this documentation : https://docs.micronaut.io/latest/guide/#filters. Unfortunately it only consider the case where Micronaut is running in a Netty Http server context where we need to implement reactive way of doing to "not block the underlying Netty event loop". But here, I am running in a Lambda. Each of the incoming HTTP request will be handled by one Lambda instance and its Thread. I don't care about this reactive way of doing here. The need of a thread pool is replaced by Lambda.
I don't know what to do with this Publisher<MutableHttpResponse<?>>. I want the HTTP response directly.
#Filter("/**")
public class SecurityFilter implements HttpServerFilter {
Logger logger = LoggerFactory.getLogger(SecurityFilter.class);
#Override
public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
logger.debug("request = " + request);
// Do something with HTTP request
// Would like to call chain to go to the next Filter or to the Controller if no other filter
// and have access to the HTTP Response like in a good old Servlet filter
// What am I supposed to do with this response publisher. This app is running in AWS Lambda.
// I don't have a netty http server. I don't need to protect "the underlying Netty event loop"
// just want to have access to my Http Response here and be able to modify it (add headers for example)
// in a synchronous manner without all this reactive stuff that I don't care about in this Lambda context
Publisher<MutableHttpResponse<?>> responsePublisher = chain.proceed(request);
responsePublisher.subscribe(new Subscriber<MutableHttpResponse<?>>() {
#Override
public void onSubscribe(Subscription s) {
logger.debug("A");
}
#Override
public void onNext(MutableHttpResponse<?> mutableHttpResponse) {
logger.debug("response");
logger.debug(mutableHttpResponse + "");
}
#Override
public void onError(Throwable t) {
logger.debug("B");
}
#Override
public void onComplete() {
logger.debug("C");
}
});
return responsePublisher;
}
}

How to dynamically call the webservices from .NET Core

Currently I am consuming some webservices with multiple endpoints in .NET with the help of WCF Webservices reference provider tool. If there are any changes in webservices then I have to update or delete and reattach, then again will have to build to get the DLL and put in to deployment server.
This is very time consuming. Are there any alternate options?
At first, the WCF created by some complex bindings, authentication security may not work well with NetCore,such as Wshttpbinding. Generally, basichttpbinding is supported by the Core-based client.
With the interface, address and other service information unchanged, we can call the service dynamically through the channel factory, No matter how the server changes the implementation of the service. It does not affect the client’s invocation.
Here is an example.
class Program
{
static void Main(string[] args)
{
Uri uri = new Uri("http://10.157.13.69:1500");
BasicHttpBinding binding = new BasicHttpBinding();
ChannelFactory<ICalculator> factory = new ChannelFactory<ICalculator>(binding,new EndpointAddress(uri));
ICalculator service = factory.CreateChannel();
try
{
var result = service.Add(34.32, 2.34);
Console.WriteLine(result);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
throw;
}
}
}
[ServiceContract]
public interface ICalculator
{
[OperationContract]
double Add(double a, double b);
}
Here is a related document.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-the-channelfactory
Feel free to let me know if there is anything I can help with.

Force create a local actor in Akka on the local JVM

How to force create an actor on the local JVM (not remote) in Akka? Is this some parameter you can pass to the create function or a configuration that you need to set?
Your worry will not happen by AKKA design.
actorOf by default will just setup actor on local node's actorsystem, it will not try to setup actor on remote node even you are in cluster or remote mode.
If you want to setup actor on remote system, you will have to explicitly do follows:
application.conf
akka {
actor {
deployment {
/sampleActor {
remote = "akka.tcp://sampleActorSystem#10.192.225.100:2553"
}
}
}
}
test.scala
val actor = system.actorOf(Props[SampleActor], "sampleActor")
Only with above configuration, the actorsystem will setup the new actor on remote system.
Anyway, your worry not exist if you not do special configuration in application.conf, detail you can refer to akka guide
Create an Actor with props method like below
public class MyActor extends AbstractActor {
#Override
public Receive createReceive() {
return ReceiveBuilder.create()
.match(Order.class, this::handleMessage)
.build();
}
static Props props() {
return Props.create(MyActor.class);
}
private void handleMessage(String e)
{
//do something with the string
}
}
Then you can create the child ActorRef using.
ActorRef childRef = actorSystem.actorOf(MyActor.props(), "myActor");
And send messages to it like below.
childRef.tell(myMessage,self());

Can't start a WCF Service installed as a Windows Service

I created a service that basically exposes some methods to update a sql server database.
I tested the service as a normal WCF Service (not a Windows Service) and it worked fine (which tells me that the ServiceModel definition in App.config is ok)
Then I turned it into a Windows Service, I installed it using InstallUtil, and it installed fine. But when trying to start it in the Services console, I get this message "The service WCFProductsWindowsService service on Local Computer started and then stopped. Some services stop automatically if they are not in use by other services or programs"
The solution that exposes the service is composed of two projects,
a class library that defines the service, the contract, and an ADO
NET Entity Data Model to the database,
and a console application that exposes the service
The class that exposes the serice is:
public class ProductsWindowsService : ServiceBase {
public ServiceHost serviceHost = null;
public ProductsWindowsService() {
ServiceName = "WCFProductsWindowsService";
}
public static void Main() {
ServiceBase.Run(new ProductsWindowsService());
}
protected override void OnStart(string[] args) {
if (serviceHost != null) {
serviceHost.Close();
}
serviceHost = new ServiceHost(typeof(ProductsServiceImpl));
serviceHost.Open();
}
protected override void OnStop() {
if (serviceHost != null) {
serviceHost.Close();
serviceHost = null;
}
}
}
I uploaded the simple project in SkyDrive
What could I be doing wrong?
Does not allow me to add a comment.
This error "The service WCFProductsWindowsService service on Local Computer started and then stopped. Some services stop automatically if they are not in use by other services or programs" indicates an exception is thrown.
I would check the event viewer to see the exception logged.
Does ProductsServiceImpl exists? I can't find it in your image or in your solution.

Persistence of service for multiple requests

I had originally thought that a particular "service interface" and in my example one that inherits from ServiceStack.ServiceInterface.Service is recreated with every request. I recently found out that perhaps it's not the case, as dependencies( and members in general) are retaining internal state. I was just hoping if someone could point me in the right direction as to expected behavior and why it behaves this way. I'm primarily interested in two scenarios, one for IIS hosting, and one for VS hosting / debugging.
A Service in ServiceStack is registered and autowired like any other IOC dependency. Every request a new instance of the Service is created and autowired with its dependencies.
Whether the service is autowired with existing instances or not depends on how the dependency is registered, e.g if you use the built-in Funq IOC:
By default dependencies are registered with Singleton scope, i.e. it will inject the same instance everytime:
container.Register<IFoo>(c => new Foo());
container.Register<IFoo>(c => new Foo()).ReusedWithin(ReuseScope.Container);
You can also specify RequestScope so a new instance is created and injected per request:
container.Register<IFoo>(c => new Foo()).ReusedWithin(ReuseScope.Request);
Finally there's transient scope where a new instance is created and injected each time:
container.Register<IFoo>(c => new Foo()).ReusedWithin(ReuseScope.None);
To re-cap a new instance of your service is indeed created per request, but whether you get a new instance or not depends on the Registration scope of your dependencies:
public class MyService : Service {
public IFoo Foo { get; set; } // auto-wired using above registration rules
}