I am having multiple WCF service but while consuming the service in Web application each service having its own end point to access the service. I need to have single end point in my web application to access all the services. Is there any other way except partial class.
No this can't be done. You can't merge multiple services into one endpoint.
You mention a partial class definition. That actually means you merge your different services together and expose them as one single service. This can off course be done and would give you one single access point (since it's just one service).
This way you could still logically separate the code in different files and let the them each implement a single interface. The service as a whole would implement a combined interface of all the different elements and that's what you would expose as a service endpoint.
--EDIT--
I personally wouldn't merge the services into one big service because that one big service will have to process all the incoming request. What if you want a certain configuration setting for one service, or you want to do some load balancing and move several services to another server?
If the problem is in maintaning the web.config files, you should have a look at web.config transformations. That way you can automate the process of configuring your application for different deployment scenarios.
Related
In a microservice world, what is the recommended way of configuring the endpoint of a downstream API?
For example, if Service A needs to invoke an endpoint in Service B, we have two options:
a. Make the hostname and port number of Service B's API configurable in Service A (service-b:8080) and append the path URI in your code
or
b. Make the complete endpoint configurable in Service A (http://service-b:8080/somepath)
While I like the idea of making the endpoint configurable, it leaves a lot of room for error because the entire path needs to be specified. It also doesn't fit well when multiple endpoints need to be called from Service A to Service B which may potentially have different paths, requiring us to configure multiple endpoints.
On the other hand, option (a) seems more scalable due to above mentioned reasons.
Most search results online just demonstrated how a service can call another service and uses a hardcoded URL to demo this. It would be good to know how is the community doing this in real world projects.
P.S: We use Spring Webflux and deploy to k8s.
I have seen mostly that teams use option a, where the serviceB "baseUrl" (which is basically https://serviceb-hostname:8080) is injected as environment property (kubernetes configmap) into the application during deployment.
The specific API specific paths are configured in application yaml or in the "proxy config" class itself as constants (eg. ServiceBProxy.java - proxy classes are those which will make rest-calls to the dependent services like service B).
Here is a portion of application yaml from one of the microservices (from one of my projects):
authorizationService:
baseUri: ${authorizationServiceBaseUri}/api
tenantService:
baseUri: ${tenantServiceBaseUri}/api/v1
tenantsUri: ${tenantService.baseUri}/tenants
settingsService:
baseUri: ${settingsServiceBaseUri}
iamService:
fetchBatchSize: 500
baseUri: ${iamServiceBaseUri}
Here the values of iamServiceBaseUri,settingsServiceBaseUri,tenantServiceBaseUri,authorizationServiceBaseUri are all injected during deployment. And each of them contains the clusterIP with port.
I could not find a direct answer to this. Basically I have services MainService and SubService. The idea is that the Client software calls some methods in the MainService, but SubService calls another part of the service in MainService.
I am deploying to Azure and I want to have two separate interfaces in MainService, one for client and one for SubService and I don't want Client service to have any chance of access to the interface the SubService uses.
Given that I am new to WCF services, I am not sure how to approach this. Do I need multiple web roles for different interfaces that access the same database and handle concurrency issues etc. there, or can I somehow include multiple interfaces but restrict the availability by, for example, certificates. I am not exactly sure on Azure firewall rules, but if the interface in MainService that is meant for the SubService could be mapped to a separate port that would be behind a firewall rule, that would also be a viable solution.
tl;dr: Need two separate interfaces in a WCF service, one for client software (open for outer world), one for a sub-system service. Both services are to be run in Azure. What are my options?
You can use standard WCF authorization and authentication. For example: http://msdn.microsoft.com/en-us/library/ff647503.aspx
If you wanted to use Azure Service Bus with relay messaging, you could use some of the authentication and authorization provided by Service Bus. But, I'm not sure if there's any extra value there compared to just hosting your WCF in a web role (you'd have to do that in either case, but the access to the service would be decoupled from the clients via Service Bus).
I have read Why not publish NServiceBus messages from a web application and another similar question about this but I am not clear if this applies to service layer as well. For example, if the service layer is composed of web services or REST services built using WCF or Web API or any other way, should those services publish events or send commands? If those services are hosted in load balanced web servers, the problems outlined in the articles apply to this layer as well. How would the recommendation change or not change?
If I look from the definition of Event vs Command, the messages I am talking about are Events e.g. "a user was created" and so an event should be published. As a matter of fact, the service that created the user doesn't even know what else to do i.e. may be another application is supposed to create a customized portal for it and yet another application is supposed to send a welcome kit to the user. This would be an event and not a command. I guess I am hung up on the definition of a web application and application service when application service itself is composed of one or many web applications.
The definition of Web Application
A web application is an application that is accessed by users over a
network such as the Internet or an intranet.
However, to me, the users can be computers and thus web services are web applications and that is the reason for this question.
EDIT:
Let's consider a concrete example. An ASP.NET website (MVC or Web form - doesn't matter) displays the form to the operator, gets a post with data about user creation (Name, UserName, Password) and invokes a WCF service to create the user. In between website and WCF service we can put ServiceBus and send command to create the user (Request/Response) so that we get all the benefits described in the first article. WCF service is the actual business processing layer i.e. it would create the user. That is where I have the question. After the user is created, it should announce that a user has been created and other systems can react to it and do whatever they are supposed to do. So it fits perfectly the pattern of publish the message. However, the WCF service itself is a web application and thus has most of the traits of the web applications and thus the confusion.
As mentioned in the answer to the SO question you linked to, publishing event has more to do with where the actual processing takes places. Just as a side-note: it is not a matter of Send instead of Publish since that would imply that the two are interchangeable whereas they have rather different intentions. When you want to publish, you want to publish.
The same questions should arise if you find yourself publishing from your web-exposed integration layer: should you be performing the business processing in that code or rather sending it off to another endpoint for processing? Typically you should just send it off to another endpoint. You may even consider how you would perform the relevant action should anyone wish to invoke it. For instance, if you are publishing a UserCreatedEvent message it implies that you created a user. How would a user be created? Would I be forced to use the WCF / Web-Api layer or can I send a CreateUserCommand message on the bus that is processed by some application endpoint? If it is the former then you may need to rethink your design. However, if the latter you should be sending the command from your WCF / Web-Api anyway and the processing endpoint will perform the Publish bit :)
update:
My take on it is that it is more about cohesion / concerns. You would typically interact with your domain, from within your business, via a service bus for commands and events, and a simple query layer for reads. If you need to expose anything to a third-party (or simply via the web) then you use WCF / WS / Web-APi. The point is that you should try to avoid business processing in an integration endpoint (or in a front-end like a website). Business processing is better suited to application servers. There are usually exceptions to the rule but if you are in a position to influence the structure then you are in a better space.
The fact is, whatever code is truly responsible for performing the action should be the same which publishes the event. If you've got a MVC app and in the controller itself you're using Entity Framework to insert the User record, then that is exactly where the Publish should be, right after the SaveChanges call. If however, the controller calls a referenced binary or service which does the actions involved in the "add user" call, then the Publish should be there. My thought is the event should be right alongside the code that does the action whose event you are trying to publish.
I have a WCF service that offers a standard SOAP interface over TCP/IP, HTTP or Named Pipes. This service computes and caches a large, complex, relational data set and offers views on it to clients, via high-level service operations. It's working perfectly.
I also have a separate custom OData service that offers the underlying data in a more "raw" form. This service shares some of the plumbing of the first, with respect to loading and caching the large, complex, relational data set, but is otherwise a standalone service that can be hosted apart from the first.
I'm currently hosting the standard SOAP service in IIS with Windows Process Activation Services, and I'm sure I can do the same thing with the OData service, as a separate endpoint.
If I wanted to host them together in the same IIS host process, what are my options for allowing the two services to share the underlying cached data set, to save on load time and memory consumption?
Assuming you can deal with the limitations of the Reflection Provider or are willing to deal with the complexity of a Custom Provider, you should be able to construct a caching layer that makes the same data available to both your WCF service and your WCF Data Service.
(This would also technically work with the Entity Framework provider, but it sounds like that might not be a good fit for your other needs.)
I can post a sample if you run into trouble getting it up and running.
We currently have a WCF Service which is beginning to reach it's limits performance wise.
We have decided to add another server which will host another instance of the WCF Service.
We have web applications which must communicate with a specific server based on context... e.g. If the web application is dealing with objects from ServiceInstance1 then requests must be directed to ServiceInstance1's EndPoint. If the web application is dealing with objects from ServiceInstance2 then requests must be directed to ServiceInstance2's EndPoint.
I initially thought that a "Intermediate Service" or "Service Manager" could be created, the web application's Service Reference would be updated from the individual Service Instance to the "Intermediate Service" or "Service Manager" and said service would act as a "Broker" to the various Service Instances.
How is this accomplished?
I have currently added a ServiceReference to each service from the Manager however it seems that once a Service is "Referenced" it's types becomes specific to the that of the ServiceReference e.g.
ServiceInstance1's type's are all {ServiceInstance1}.
ServiceInstance2's type's are all {ServiceInstance2}.
I need the types to be the same on the web application end, so this obviously seems like the wrong way to do it.
I would also like that when methods are called on the client generated from referencing the "Intermediate Service" or "Service Manager" that the correct Service Instance is invoked, e.g.
IServiceManager.GetProjectById( {GUID} ) ->
Comes Back to ServiceManager ->
Determines which host has the project and returns the ProjectObject from the correct ServiceInstance.
Where ProjectObject is a Type Defined in ServiceInstance1 and ServiceInstance2.
I think the original service needs to have some of the DLL's pulled out so they can be referenced from the web application side and ServiceManager and a GenericWCF Client can be made.
If I am right hooray for me If someone can point me in the right direction I would appreciate it. If I am wrong can someone please scold me and show me how this is properly done!
The way to solve your problem is to create shared assembly with types used by both services. Reference this assembly on the client consuming your services (manager) and when creating proxies by Add service reference mark Reuse types from referenced assemblies.
What you are building is very simple message router. In WCF 4.0 there is additional support for routing services so you should check those features before developing your own. For WCF 3.5 MSDN magazine contains articles about building message router - part 1, part 2.
Just to Answer this and close it I wound up utilizing the Routing Strategy in .Net 4.0 and custom client class which I modeled after the generated classes from the Proxy.
Before I had the custom client ready I used the auto generated client code and I derived a class from it which allow me to change which service it was connecting to. I determined which service via a property which was made available on all service objects which were serialized.
Long story short this is working 100% as expected including the ServiceManager which can even be bypassed on certain calls which we allow.
We even have the ability to move a project from server to server during run time!
Thanks to everyone who helped! (Especially myself for actually doing the work without being spoon fed)
The easiest way to accomplish what you're trying to do is to stop generating your proxies using the server-hosted URL of the service. Instead, generate your proxies from the *.xsd and *.wsdl locally, and merely change the URL of the endpoint. Alternatively, you can use ChannelFactory<T> to generate proxies on-the-fly, and reference your interface .dll on the client side.
Once you've done that, you can use any common webserver load balancing technique to balance the load between the servers.
Not to put too fine a point on it, but Visual Studio's "Service Reference" is not useful, and should not be used, for services you develop. It's useful only for services developed externally, whose URL and contracts are likely to NEVER change. I personally have never had occasion to use it. For your own services, you should probably be using ChannelFactory<T> or a class based on ClientBase<T> to work out the proxies.