From b89ca3aa5a7437b5cc6009dc508136d997c17872 Mon Sep 17 00:00:00 2001 From: Jonathan Jenne Date: Wed, 9 Dec 2020 16:35:54 +0100 Subject: [PATCH] EDMIService: Move service configuration to code --- Modules.EDMIAPI/Client/Channel.vb | 5 +- Service.EDMIService/App.config | 17 +++++-- Service.EDMIService/EDMIService.vb | 16 ++++++- Service.EDMIService/EDMIService.vbproj | 1 + Service.EDMIService/ServiceHost.vb | 65 ++++++++++++++++++++++++++ Service.EDMIService/WindowsService.vb | 24 ++++++++-- 6 files changed, 116 insertions(+), 12 deletions(-) create mode 100644 Service.EDMIService/ServiceHost.vb diff --git a/Modules.EDMIAPI/Client/Channel.vb b/Modules.EDMIAPI/Client/Channel.vb index 041ae8d0..962fd57e 100644 --- a/Modules.EDMIAPI/Client/Channel.vb +++ b/Modules.EDMIAPI/Client/Channel.vb @@ -7,8 +7,8 @@ Public Class Channel ' https://social.msdn.microsoft.com/Forums/vstudio/en-US/d6e234d3-942f-4e9d-8470-32618d3f3212/maxbufferpoolsize-vs-maxbuffersize?forum=wcf Public Const MAX_RECEIVED_MESSAGE_SIZE = 2147483647 ' 1GB - Public Const MAX_BUFFER_SIZE = 2147483647 ' 10MB - Public Const MAX_BUFFER_POOL_SIZE = 2147483647 ' 40MB + Public Const MAX_BUFFER_SIZE = 104857600 ' 100MB + Public Const MAX_BUFFER_POOL_SIZE = 1048576 ' 1MB Public Const MAX_CONNECTIONS = 500 Public Const MAX_ARRAY_LENGTH = 2147483647 @@ -19,7 +19,6 @@ Public Class Channel .MaxReceivedMessageSize = MAX_RECEIVED_MESSAGE_SIZE, .MaxBufferSize = MAX_BUFFER_SIZE, .MaxBufferPoolSize = MAX_BUFFER_POOL_SIZE, - .MaxConnections = MAX_CONNECTIONS, .TransferMode = TransferMode.Streamed, .Security = New NetTcpSecurity() With { .Mode = SecurityMode.Transport, diff --git a/Service.EDMIService/App.config b/Service.EDMIService/App.config index 03cb00ce..add3025c 100644 --- a/Service.EDMIService/App.config +++ b/Service.EDMIService/App.config @@ -25,11 +25,22 @@ - - + + - + diff --git a/Service.EDMIService/EDMIService.vb b/Service.EDMIService/EDMIService.vb index 7a80145b..a29fb9ee 100644 --- a/Service.EDMIService/EDMIService.vb +++ b/Service.EDMIService/EDMIService.vb @@ -1,12 +1,14 @@ Imports DigitalData.Modules.Database Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Filesystem -Imports DigitalData.Modules.language +Imports DigitalData.Modules.Language Imports DigitalData.Modules Imports System.IO Imports System.ServiceModel Imports System.Data.SqlClient Imports DigitalData.Services.EDMIService.Results +Imports System.ServiceModel.Description +Imports System.ServiceModel.Channels Public Class EDMIService @@ -27,6 +29,18 @@ Public Class EDMIService Private ReadOnly _debug As Boolean = False Private ReadOnly _username As String + Public Shared Sub Configure(Config As ServiceConfiguration) + Dim oBaseAddress = Config.BaseAddresses.Item(0) + Dim oBinding = EDMI.API.Channel.GetBinding() + Dim oAddress = New EndpointAddress(oBaseAddress) + ' See: https://stackoverflow.com/questions/42327988/addserviceendpoint-throws-key-is-null + Dim oDescription = ContractDescription.GetContract(GetType(IEDMIService), GetType(EDMIService)) + Dim oEndpoint As New ServiceEndpoint(oDescription, oBinding, oAddress) + + Config.AddServiceEndpoint(oEndpoint) + Config.Description.Behaviors.Add(New ServiceDebugBehavior With {.IncludeExceptionDetailInFaults = True}) + End Sub + Public Sub New() Dim oOperationContext As OperationContext = OperationContext.Current Dim oInstanceContext As InstanceContext = oOperationContext.InstanceContext diff --git a/Service.EDMIService/EDMIService.vbproj b/Service.EDMIService/EDMIService.vbproj index 6e0de2e7..cf51d68f 100644 --- a/Service.EDMIService/EDMIService.vbproj +++ b/Service.EDMIService/EDMIService.vbproj @@ -134,6 +134,7 @@ + Component diff --git a/Service.EDMIService/ServiceHost.vb b/Service.EDMIService/ServiceHost.vb new file mode 100644 index 00000000..9680df2e --- /dev/null +++ b/Service.EDMIService/ServiceHost.vb @@ -0,0 +1,65 @@ +Imports System.ServiceModel +Imports System.ServiceModel.Channels +Imports System.ServiceModel.Description + +Public Class ServiceHost(Of T) + Inherits ServiceHost + + Public Sub New(baseAddresses As Uri()) + MyBase.New(GetType(T), baseAddresses) + End Sub + + Public Sub EnableMetadataExchange(ByVal Optional EnableHttpGet As Boolean = True) + If State = CommunicationState.Opened Then + Throw New InvalidOperationException("Host is already opened") + End If + + Dim oMetadataBehavior As ServiceMetadataBehavior = Description.Behaviors.Find(Of ServiceMetadataBehavior)() + + If oMetadataBehavior Is Nothing Then + oMetadataBehavior = New ServiceMetadataBehavior() + Description.Behaviors.Add(oMetadataBehavior) + + If BaseAddresses.Any(Function(uri) uri.Scheme = "http") Then + oMetadataBehavior.HttpGetEnabled = EnableHttpGet + Else + oMetadataBehavior.HttpGetEnabled = False + End If + End If + + AddAllMexEndPoints() + End Sub + + Public ReadOnly Property HasMexEndpoint As Boolean + Get + Return Description.Endpoints.Any(Function(endpoint) endpoint.Contract.ContractType = GetType(IMetadataExchange)) + End Get + End Property + + Public Sub AddAllMexEndPoints() + Debug.Assert(HasMexEndpoint = False) + + For Each baseAddress As Uri In BaseAddresses + Dim oBinding As Binding = Nothing + + Select Case baseAddress.Scheme + Case "net.tcp" + oBinding = MetadataExchangeBindings.CreateMexTcpBinding() + Exit Select + Case "net.pipe" + oBinding = MetadataExchangeBindings.CreateMexNamedPipeBinding() + Exit Select + Case "http" + oBinding = MetadataExchangeBindings.CreateMexHttpBinding() + Exit Select + Case "https" + oBinding = MetadataExchangeBindings.CreateMexHttpsBinding() + Exit Select + End Select + + If oBinding IsNot Nothing Then + AddServiceEndpoint(GetType(IMetadataExchange), oBinding, "mex") + End If + Next + End Sub +End Class diff --git a/Service.EDMIService/WindowsService.vb b/Service.EDMIService/WindowsService.vb index 20deb2a8..6aa602d4 100644 --- a/Service.EDMIService/WindowsService.vb +++ b/Service.EDMIService/WindowsService.vb @@ -5,11 +5,12 @@ Imports DigitalData.Modules.Database Imports DigitalData.Modules Imports System.ServiceModel.Description Imports DigitalData.Modules.Config +Imports System.ServiceModel.Channels Public Class WindowsService Inherits ServiceBase - Private _ServiceHost As ServiceHost + Private _ServiceHost As ServiceHost(Of EDMIService) Private _LogConfig As LogConfig Private _Logger As Logger @@ -37,7 +38,7 @@ Public Class WindowsService Try Dim oServicePath As String = AppDomain.CurrentDomain.BaseDirectory - _LogConfig = New LogConfig(LogConfig.PathType.CustomPath, oServicePath) + _LogConfig = New LogConfig(LogConfig.PathType.CustomPath, IO.Path.Combine(oServicePath, "Log")) _LogConfig.Debug = True _Logger = _LogConfig.GetLogger() _Logger.Info("Service {0} is starting...", SERVICE_DISPLAY_NAME) @@ -79,14 +80,27 @@ Public Class WindowsService EDMIService.Scheduler = _Scheduler _Logger.Debug("Starting WCF ServiceHost") - _ServiceHost = New ServiceHost(GetType(EDMIService)) + + Dim oBaseAddresses() As Uri = {New Uri("net.tcp://localhost:9000/DigitalData/Services/Main")} + _ServiceHost = New ServiceHost(Of EDMIService)(oBaseAddresses) + _ServiceHost.EnableMetadataExchange(False) + + _Logger.Debug("Listing Endpoints:") + For Each oEndpoint In _ServiceHost.Description.Endpoints + _Logger.Debug("Name: {0}", oEndpoint.Name) + _Logger.Debug("Address: {0}", oEndpoint.Address.ToString) + _Logger.Debug("Listen Uri: {0}", oEndpoint.ListenUri.AbsoluteUri) + _Logger.Debug("Binding: {0}", oEndpoint.Binding.Name) + _Logger.Debug("Contract: {0}", oEndpoint.Contract.Name) + Next + _ServiceHost.Open() _Logger.Info("WCF ServiceHost started") - _Logger.Info("Service {0} successfully started", SERVICE_DISPLAY_NAME) Catch ex As Exception - _Logger.Error(ex, "Failed to start the service host!") + _Logger.Warn("Unexpected Error while starting the service: {0}", ex.Message) + _Logger.Error(ex) GracefullyStop() End Try End Sub