Difference in ServiceManifest for owin hosted API controller vs regular stateless service - service

When you create owin hosted API controller in service fabric with vs 2015, the following line appears in the ServiceManifest.xml file (under Resources/Endpoints):
<Endpoint Protocol="http" Name="ServiceEndpoint" Type="Input" Port="8726" />
But in case of regular stateless service, the following line appears in the related ServiceManifest.xml file:
<Endpoint Name="ServiceEndpoint" />
Since both are stateless services under the hood, why the difference in Endpoint definition? What does this signify? Also how would I call the 2nd service (from 1st service) over http transport?
Thanks.

A web API is normally used as a gateway to the application, so it requires a fixed port, to be mapped by the load balancer to an external port (in contrast to the default, a random port assigned by the Fabric).
In addition, this ensures a correct HTTP endpoint registration in Windows, as described in the documentation:
This step is important because the service host process runs under
restricted credentials (Network Service on Windows). This means that
your service won't have access to set up an HTTP endpoint on its own.
By using the endpoint configuration, Service Fabric knows to set up
the proper access control list (ACL) for the URL that the service will
listen on. Service Fabric also provides a standard place to configure
endpoints.

Related

Connecting services without Dapr

New to Container Apps.
I'm trying to understand basic connectivity between services in Container Apps.
Lets say I have a web front in .Net Core and an Web API backend (.Net Core).
Without containerization, I could put the base address of my web api in my app settings of the front end to connect to the api, lets say localhost:5000 etc. Using an httpClient to do the call.
If I containerize the front end and api and deploy it to ACA, what would that look like? I think its would be like:
Ingress external for front end
Ingress internal for api
Port 80 for both front end and web api????
Or do I need to setup a base address of some sort to call the web api? Or an environment variable?
I put both ports to 80 but they cannot seem to connect.
Thanks!
In your "Without containerization" example, if your web ui is running on localhost:8080 for example, and your API is running on localhost:5000 then you'll need to enable CORS on the api. In That example, both your web ui and your api are "external". Anything you need to call from a browser is 'external'.
Internal only are for server to server communication, or microservices communicating with each other.
In your example, you'd deploy both as external apps, this will give you 2 domains https://webui.env.region.azurecontainerapps.io and https://api.env.region.azurecontainerapps.io then you will configure a CORS policy on the api app.
see this for more details

How to share a port in Azure Service Fabric using Kestrel

I have multiple Service Fabric APIs. Both services are hosted in the same cluster using Kestrel. Currently each service is assigned to a specific port so they show up as
http://service1:123 and
http://service2:456
I would like to access the services using default port 80 for both. Is there a way to do this without having to use Azure API Management?
Sure, Kestrel doesn't support port sharing, but you can:
run on IIS, inside containers.
use the built in reverse proxy
use a (containerized) reverse proxy like Traefik

Azure Service Fabric: Make endpoint Input and Internal for identity server 4

I want to run an application on Azure service fabric. One service should serve as identity provider. So I installed identity server 4 package on that 'usermanager'. I have also two other services which should use this usermanager for authentication and authorization.
That works on localhost. But on Azure I have the problem that an endpoint must be 'Input' or 'Internal' in my service manifest. But for my usermanager I need both input and internal.
<Endpoint Protocol="http" Name="IdentityServerEndpoint" Type="Input" Port="5000" />
/.well-known/openid-configuration needs 'Internal' and
/connect/authorize?xxxxxx needs 'Input'
I found that for Input endpoints azure service fabric uses the full qualified domain name and for internal endpoints it uses the ip address of the lokal network like 10.0.0.4.
Is there a solution to make an endpoint both input and internal?
Or is there a solution to make identity server 4 to handle two endpoints?
Any ideas to solve this problem?
Believe it or not, the "Type" field in the Endpoint config doesn't actually do anything on any hosting platform. It's just metadata that you can configure and use in your code (basically a way for you to set your own policies). It doesn't matter what you put there otherwise.
Ultimately, you're opening an endpoint on a process on a VM. That endpoint will be open on the VM's IP and the port you choose, e.g., 10.0.0.1:5000.
If you want that endpoint to also be available on your cluster's VIP and FQDN, that configuration is external to Service Fabric. In Azure you just need to configure the Azure Load Balancer to forward external traffic on the port your service is listening on. See here for more info on that: https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-connect-and-communicate-with-services#connections-from-external-clients

How to call an app with no-route from another app in Bluemix?

Here is usecase:
I have two apps in Bluemix: app1 and app2
app1 is accessible through the internet using its route (e.g. app1.mybluemix.net)
app2 doesn't have any route to prevent from being accessible through the internet.
app2 may expose a REST API.
How do I call app2 from app1 inside Bluemix?
An example of communicating to an application without a route is implemented in this Microservice Shipping sample.
This is an EJB Liberty application that runs on Bluemix without a route and subscribes to the Bluemix MQ Light service. The sender of the messages is the Microservice Orders sample application, which binds to the same MQ Light service.
Going the REST API route will mean you must have an externally accessible route. However, you could secure it using keys and tokens.
It would be easier to use one of the services in Bluemix as an "RPC" layer between the two applications. You could use one of the queue services (MQLight, RabbitMQ) or Redis to pass messages between the applications to execute commands.
These service bindings are internal and won't be exposed externally unlike the REST API.
Alternatively, you could expose the REST API from App2 and use authentication to control access.
There are two ways you can prevent access.
Put your microservice inside a Bluemix Container and utilize private IPs https://new-console.ng.bluemix.net/docs/containers/container_security_network.html#container_cli_ips_byoip
Use API Connect as a API Gateway/proxy to the private IP being in your container microservice.
Use Bluemix Dedicated to deploy app2. Bluemix dedicated provides firewall capabilities and you could set it up so that it only accepts requests from app1's IP address.
Use Bluemix Local when it becomes available with the same approach where you use your corporate firewall to only accept requests that come from your App1 IP Address. This is an expensive alternative compared to a public PAAS.
Use the API Connect Service which replaced the API Management Service to:
Specify what users can access your apis
Specify the number of requests per day or other unit of time
Provides a API Gateway to securely call the other service App2.
I expect at some point a software network defined solution will be considered as part of the offering.

API gateway/proxy pattern for microservices deployed using Azure Service Fabric

After watching the BUILD conference videos for Azure Service Fabric, I'm left imagining how this might be a good fit for our current microservice-based architecture. There is one thing I'm not entirely sure how I would go about solving, however - the API gateway/proxy.
Consider a less-than-trivial microservice architecture where you have N number of services running within the Azure Service Fabric exposing REST endpoints. In many situations, you want to package these fragmented API endpoints up into a single-entry API for consumers to use, to avoid having them connecting to the service fabric-instances directly. The Azure Service Fabric solution seems so complete in every way that I'm sort of wondering if I missed something obvious when I don't see a way to trivially solve this within the capabilities mentioned during the BUILD talks.
Services like Vulcan aim to solve this problem by having the services register the paths they want routed to them in etcd. I'm guessing one way of solving this may be to create a separate stateful web service that other services can register themselves with, providing service name and the paths they need routed to them. The stateful web service can then route traffic to the correct instance based on its state. This doesn't seem entirely ideal, though, with stuff like removing routes when applications are removed and generally keeping the state in sync with the services deployed within the cluster. Has anybody given this any thought, or have any ideas how one might go about solving this within Azure Service Fabric?
The service registration/discoverability you need to do this is actually already there. There's a stateful system service called the Naming Service, which is basically a registrar of service instances and the endpoints they're listening on. So when you start up a service - either stateless or stateful - and open some listener on it, the address gets registered with the Naming Service.
Now the part you'd need to fill in is the "gateway" that users interact with. This doesn't have to be stateful because the Naming Service manages the stateful part. But you'd have to come up with an addressing scheme that works for you, and then it would just forward requests along to the right place. Basically something like this:
Receive request.
Use NS to find the service that can take the request.
Forward the request to it and the response back to the user.
If the service doesn't exist anymore, 404.
In general we don't like to dictate anything about how your services talk to each other, but we are thinking of ways to solve this problem for HTTP as a complete built-in solution.
We implemented a HTTP gateway service for this purpose as well. To make sure we can have one HTTP gateway for any internal protocol, we implemented the gateway for HTTP based internal services (like ASP.NET WebAPIs) using an ASP.NET 5 middleware. It routes requests from e.g /service to an internal Service Fabric address like fabric:/myapp/myservice by using the ServicePartitionClient and some retry logic from CommunicationClientFactoryBase.
We open-sourced this middleware and you can find it here:
https://github.com/c3-ls/ServiceFabric-HttpServiceGateway
There's also some more documentation in the wiki of the project.
This feature is build in for http endpoints, starting with release 5.0 of service fabric. The documentation is available at https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reverseproxy/
We have used an open source project called Traefik with amazing success. There is an Azure Service Fabric wrapper around it - it's essentially a GoLang exe that is deployed onto the cluster as Managed Executable.
It supports circuit breakers, weighted round robin LB, path & header version routing (this is awesome for hosting multiple API versions), the list goes on. And its got a handy portal to view the config and health stats.
The real power in it lies in how you configure it. It's done via the service itself in the ServiceManifest.xml. This allows you to deploy new services and have them immediately able to be routed to - no need to update a routing table etc.
Example
<StatelessServiceType ServiceTypeName="WebServiceType">
<Extensions>
<Extension Name="Traefik">
<Labels xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
<Label Key="traefik.frontend.rule.example">PathPrefixStrip: /a/path/to/service</Label>
<Label Key="traefik.enable">true</Label>
<Label Key="traefik.frontend.passHostHeader">true</Label>
</Labels>
</Extension>
</Extensions>
</StatelessServiceType>
Highly recommended!
Azure Service Fabric makes it easy to implement the standard architecture for this scenario: a gateway service as a frontend for the clients to connect to and all the N backend services communicating with the front end gateway. There are a few communication API stacks available as part of Service Fabric that make it easy to communicate from clients to services and within services themselves. The communication API stacks provided by Service Fabric hide the details of discovering, connecting and retrying connections so that you can focus on the actual exchange of information. When using the Service Fabric communication APIs the services do not have to implement the mechanism of registering their names and endpoints to a specific routing service except what are the usual steps as part of creating the service itself. The communication APIs take in the service URI and partition key and automatically resolve and connect to the right service instance. This article provides a good starting point to help make a decision with regards to which communication APIs will be best suited for your particular case depending on whether you are using Reliable Actors or Reliable Services, or protocols such as HTTP or WCF, or the choice of programming language that the services are written in. At the end of the article you will find links to more detailed articles and tutorials for different communication APIs. For a tutorial on communication in Web API services see this.
We are using SF with a gateway pattern and about 13 services behind the gateway. We use the built in DNS service that SF provides, see: https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-dnsservice, this allows the internal service to service calls with known (internal to SF) DNS names, including gateway service to internal services. There are some well known asp.net core gateways (Ocelot, ProxyKit) to use, but we rolled our own. We have an external load balancer to route to multiple gateway instances in SF.
When a service is started, it registers it's endpoint with the fabric naming service. Using the Fabric client APIs you can then ask fabric for the registered endpoints, associated with the registered service name.
So yes, just as you described your case, you would have a gateway that would accept an incoming URI for connection, and then use that path information as the service name lookup, to then create a proxy connection between the incoming request and the actual internal endpoint location.
Looks like the team as posted one the samples that shows how to do this: https://github.com/Azure/servicefabric-samples/tree/master/samples/Services/VS2015/WordCount