0
votes

I am working on a Service Fabric project with Owin, and I'm having troubles getting it deployed into the cloud. I have searched for others with the same problem, but I only found an answer telling that the error in the cluster tells where in the code it goes wrong. I have followed Microsofts Owin tutorial on how to write the method that fails, but with no luck. I can run the project on Localhost direcly from Visual Studio, but the problem starts when I deploy it to a Service Fabric cluster in Azure. I have a 5 node cluster running, and when I deploy to it, it starts giving warnings after 2 minutes, and errors after 5 minutes. the status of the application is "inbuild". Image of warning and Image of error.

I have two services, and the error from my cluster gives the error in these two methods(the same method in each service(OpenAsync)):

        public Task<string> OpenAsync(CancellationToken cancellationToken)
    {
        var serviceEndpoint =
            _parameters
            .CodePackageActivationContext
            .GetEndpoint("ServiceEndpoint");

        var port = serviceEndpoint.Port;
        var root =
            String.IsNullOrWhiteSpace(_appRoot)
            ? String.Empty
            : _appRoot.TrimEnd('/') + '/';


        _listeningAddress = String.Format(
            CultureInfo.InvariantCulture,
            "http://+:{0}/{1}",
            port,
            root
        );
        _serverHandle = WebApp.Start(
            _listeningAddress,
            appBuilder => _startup.Configuration(appBuilder)
        );

        var publishAddress = _listeningAddress.Replace(
            "+",
            FabricRuntime.GetNodeContext().IPAddressOrFQDN
        );

        ServiceEventSource.Current.Message("Listening on {0}", publishAddress);
        return Task.FromResult(publishAddress);
    }

the error from the cluster tells the error is in this section:

          _serverHandle = WebApp.Start(
            _listeningAddress,
            appBuilder => _startup.Configuration(appBuilder)
        );

the other method(from the other service):

        public Task<string> OpenAsync(CancellationToken cancellationToken)
    {
        var serviceEndpoint =
            _parameters
            .CodePackageActivationContext
            .GetEndpoint("ServiceEndpoint");

        var port = serviceEndpoint.Port;
        var root =
            String.IsNullOrWhiteSpace(_appRoot)
            ? String.Empty
            : _appRoot.TrimEnd('/') + '/';

        _listeningAddress = String.Format(
            CultureInfo.InvariantCulture,
            "http://+:{0}/{1}",
            port,
            root
        );

        try
        {
            _serverHandle = WebApp.Start(
                _listeningAddress,
                appBuilder => _startup.Configuration(appBuilder)
            );
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw e;
        }


        var publishAddress = _listeningAddress.Replace(
            "+",
            FabricRuntime.GetNodeContext().IPAddressOrFQDN
        );

        ServiceEventSource.Current.Message("Listening on {0}", publishAddress);
        return Task.FromResult(publishAddress);
    }

the error from the cluster tells the error is in this section:

            try
        {
            _serverHandle = WebApp.Start(
                _listeningAddress,
                appBuilder => _startup.Configuration(appBuilder)
            );
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw e;
        }

My StartUp Classes:

        public void Configuration(IAppBuilder appBuilder)
    {
        var corsAttr = new EnableCorsAttribute(origins: "*", headers: "*", methods: "*");

        var config = new HttpConfiguration();
        config.WithWindsorSetup();
        config.WithJsonSetup();
        config.MapHttpAttributeRoutes(); //Enable Attribute-routing
        config.WithSwaggerSetup();
        config.EnsureInitialized();
        config.EnableCors(corsAttr);
        appBuilder.UseWebApi(config);


    }

and where I create a new OwenCommunicationListener:

        protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return new[] {
            new ServiceInstanceListener(initParams => new OwinCommunicationListener("", new Startup.Startup(), initParams))
        };
    }

I would very much like to be able to deploy it to Azure Service Fabric Cluster without any errors. Have a nice day, and thanks for helping.

2

2 Answers

0
votes

you need to write your own custom class that configure the routing and http configuration for Owin listener. Here is the class which I am using to configure the routing, try with it:

    /// <summary>
    /// This is the startup class that configure the routing and http configuration for Owin listener.
    /// </summary>
    public static class Startup
        {
        // This code configures Web API. The Startup class is specified as a type
        // parameter in the WebApp.Start method.
        public static void ConfigureApp (IAppBuilder appBuilder)
            {

            appBuilder.UseCors(CorsOptions.AllowAll);
            // Configure Web API for self-host. 
            HttpConfiguration config = new HttpConfiguration();
            config.MapHttpAttributeRoutes();

            var json = config.Formatters.JsonFormatter;
            json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
            config.Formatters.Remove(config.Formatters.XmlFormatter);

            appBuilder.UseWebApi(config);
            }
        }

pass this class as an action to instance where you are creating instance of OwinCommunication Listener. Here is my code

endpoints.Select(endpoint => new ServiceInstanceListener(
                serviceContext => new OwinCommunicationListener(Startup.ConfigureApp, serviceContext,
                    null, endpoint), endpoint));

This approach is working for me. Try with it hopefully it will work for you too

0
votes

problem is solved. I edited this code:

        protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return Context.CodePackageActivationContext.GetEndpoints()
            .Where(endpoint => endpoint.Protocol.Equals(EndpointProtocol.Http) || endpoint.Protocol.Equals(EndpointProtocol.Https))
            .Select(endpoint => new ServiceInstanceListener(serviceContext => new OwinCommunicationListener("", new Startup.Startup(), serviceContext)));

        //return new[] {
        //    new ServiceInstanceListener(initParams => new OwinCommunicationListener("", new Startup.Startup(), initParams))
        //};
    }