New MVC 4 Beta Web API is not serving requests when ran as a Windows Service - asp.net-mvc-4

I'm trying to run a self hosted executable as a Windows service. I'm using the MVC 4 beta Web API. First I used Derik Whittaker's blog for setting up the basic console application and tested it with positive results.
I then used Einar Egilsson's blog to make it work as both a console application and a windows service. The application installed as a service just fine. I set the service logon to use my own for this basic testing; it failed to bind to the socket without this. When the service starts up I see all my trace logs as expected there are no fatal errors. The application appears to be running normally. When I test using fiddler using the same request for the console application I get a "HTTP/1.1 500 Internal Server Error".
Using this same code when I turn off the service then launch using F5 in VS the application starts up just fine and serves the same request!? The log entries are identical within the same execution paths.
public partial class TestService : ServiceBase {
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private HttpSelfHostServer _server;
static void Main(string[] args) {
Logger.Debug("Main Called");
var service = new TestService();
if (Environment.UserInteractive) {
Logger.Debug("Environment.UserInteractive == true");
Console.WriteLine("Press any key to stop program");
service.OnStart(args);
service.OnStop();
} else {
Logger.Debug("Environment.UserInteractive == false");
try {
Run(service);
} catch(Exception exception) {
Logger.Fatal(exception.Message, exception);
}
}
}
protected override void OnStart(string[] args) {
Logger.Debug("OnStart called");
var hostUri = string.Format("http://{0}:{1}", Environment.MachineName, ConfigurationManager.AppSettings["Service.Port"]);
Logger.Debug("URL:" + hostUri);
var selfHostConfiguration = new HttpSelfHostConfiguration(hostUri);
selfHostConfiguration.Routes.MapHttpRoute(
name: "DefaultApiRoute",
routeTemplate: "endpoints/{controller}",
defaults: null
);
Logger.Debug("Routes registered");
try {
using (_server = new HttpSelfHostServer(selfHostConfiguration)) {
Logger.Debug("Hosting at " + hostUri + "/endpoints/{controller}");
_server.OpenAsync().Wait();
if (Environment.UserInteractive) { // *** I've tried this commented out as well
Console.ReadLine();
}
Logger.Debug("End of using");
}
} catch(Exception exception) {
Logger.Fatal(exception.Message, exception);
if(exception.InnerException != null) {
Logger.Fatal(exception.InnerException.Message, exception.InnerException);
}
}
}
protected override void OnStop() {
_server.Dispose();
}
}

It has been some time since you posted this but I wanted to input.
I don't know why this is, but the internal error comes from initializing the self host inside the onStart method. You must initialize it in the constructor of the service and then only call the _server.OpenAsync() in the onStart method.
Or at least that is what worked for me.

Use TopShelf. I just blogged about how to do that.

as i can see, you use _server.OpenAsync().Wait(); in OnStart method. This just makes your initialization code to freeze, all code after that line will not execute. To avoid this try to remove .Wait() from the OpenAsync().

Related

AvaloniaUI: Setup was already called on one of AppBuilder instances

Whenever I try to restart Avalonia application form base application, I get an exception: "Setup was already called on one of AppBuilder instances." on SetupWithLifetime() call.
Application Startup code is:
public static void Start()
{
lifeTime = new ClassicDesktopStyleApplicationLifetime()
{
ShutdownMode = ShutdownMode.OnLastWindowClose
};
BuildAvaloniaApp().SetupWithLifetime(lifeTime);
lifeTime.Start(new[] { "" });
}
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace()
.UseReactiveUI();
Application shutdown code is:
lifeTime.Shutdown();
lifeTime.Dispose();
Here's a link to functional example code, which produces this error: https://pastebin.com/J1jqppPv
Has anyone encountered such problem? Thank you
SetupWithLifetime calls Setup which can only be called once. A possible solution is to call SetupWithoutStarting on BuildAvaloniaApp, which can only be called once as well, for example:
private static AppBuilder s_builder;
static void Main(string[] args)
{
s_builder = BuildAvaloniaApp();
}
public static void Start()
{
lifeTime = new ClassicDesktopStyleApplicationLifetime()
{
ShutdownMode = ShutdownMode.OnLastWindowClose
};
s_builder.Instance.Lifetime = lifeTime;
s_builder.Instance.OnFrameworkInitializationCompleted();
lifeTime.Start(new[] { "" });
}
private static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace()
.UseReactiveUI();
Additional note: Restarting the app probably won't work on macOS.

How to implement a Restlet JAX-RS handler which is a thin proxy to a RESTful API, possibly implemented in the same java process?

We have two RESTful APIs - one is internal and another one is public, the two being implemented by different jars. The public API sort of wraps the internal one, performing the following steps:
Do some work
Call internal API
Do some work
Return the response to the user
It may happen (though not necessarily) that the two jars run in the same Java process.
We are using Restlet with the JAX-RS extension.
Here is an example of a simple public API implementation, which just forwards to the internal API:
#PUT
#Path("abc")
public MyResult method1(#Context UriInfo uriInfo, InputStream body) throws Exception {
String url = uriInfo.getAbsolutePath().toString().replace("/api/", "/internalapi/");
RestletClientResponse<MyResult> reply = WebClient.put(url, body, MyResult.class);
RestletUtils.addResponseHeaders(reply.responseHeaders);
return reply.returnObject;
}
Where WebClient.put is:
public class WebClient {
public static <T> RestletClientResponse<T> put(String url, Object body, Class<T> returnType) throws Exception {
Response restletResponse = Response.getCurrent();
ClientResource resource = new ClientResource(url);
Representation reply = null;
try {
Client timeoutClient = new Client(Protocol.HTTP);
timeoutClient.setConnectTimeout(30000);
resource.setNext(timeoutClient);
reply = resource.put(body, MediaType.APPLICATION_JSON);
T result = new JacksonConverter().toObject(new JacksonRepresentation<T>(reply, returnType), returnType, resource);
Status status = resource.getStatus();
return new RestletClientResponse<T>(result, (Form)resource.getResponseAttributes().get(HeaderConstants.ATTRIBUTE_HEADERS), status);
} finally {
if (reply != null) {
reply.release();
}
resource.release();
Response.setCurrent(restletResponse);
}
}
}
and RestletClientResponse<T> is:
public class RestletClientResponse<T> {
public T returnObject = null;
public Form responseHeaders = null;
public Status status = null;
public RestletClientResponse(T returnObject, Form responseHeaders, Status status) {
this.returnObject = returnObject;
this.responseHeaders = responseHeaders;
this.status = status;
}
}
and RestletUtils.addResponseHeaders is:
public class RestletUtils {
public static void addResponseHeader(String key, Object value) {
Form responseHeaders = (Form)org.restlet.Response.getCurrent().getAttributes().get(HeaderConstants.ATTRIBUTE_HEADERS);
if (responseHeaders == null) {
responseHeaders = new Form();
org.restlet.Response.getCurrent().getAttributes().put(HeaderConstants.ATTRIBUTE_HEADERS, responseHeaders);
}
responseHeaders.add(key, value.toString());
}
public static void addResponseHeaders(Form responseHeaders) {
for (String headerKey : responseHeaders.getNames()) {
RestletUtils.addResponseHeader(headerKey, responseHeaders.getValues(headerKey));
}
}
}
The problem is that if the two jars run in the same Java process, then an exception thrown from the internal API is not routed to the JAX-RS exception mapper of the internal API - the exception propagates up to the public API and is translated to the Internal Server Error (500).
Which means I am doing it wrong. So, my question is how do I invoke the internal RESTful API from within the public API implementation given the constraint that both the client and the server may run in the same Java process.
Surely, there are other problems, but I have a feeling that fixing the one I have just described is going to fix others as well.
The problem has nothing to do with the fact that both internal and public JARs are in the same JVM. They are perfectly separated by WebResource.put() method, which creates a new HTTP session. So, an exception in the internal API doesn't propagate to the public API.
The internal server error in the public API is caused by the post-processing mechanism, which interprets the output of the internal API and crashes for some reason. Don't blame the internal API, it is perfectly isolated and can't cause any troubles (even though it's in the same JVM).

Silverlight Dispose pattern with WCF (Async)

I'm a little new to Silverlight, and I want to know how to deal with the Faulted/Disposing of a WCF service.
I'm used to something like this (wcf abort/close pattern) where you call the service in a try/catch (making sure you close or abort). (which works well in a stateless application)
looking into Silverlight, where do we apply the abort/close pattern? as the service call is async and the application is state full.
At the moment the only thing I can think of is some sort of dynamic proxy (using something like Castle DP) accompanied with the ChannelFactoryManager from the n-tier app, about 1/2 way down the page example. where the proxy will ensure there is always an open channel and the ChannelFactoryManager will handle the faults
Because of the asynchronous nature of the Silverlight networking environment I recommend you to build more testable ServiceAgents - long-living singleton wrappers around silverlight's client proxies with callbacks for service methods. You can check real-proxy state (& recreate if needed) before calling service methods or use channel Faulted event. For ex:
public void GetOptionsAsync(Action<GetOptionsCompletedEventArgs> callback)
{
try
{
CheckProxy();
EventHandler<GetOptionsCompletedEventArgs> handler = null;
handler = (sender, args) =>
{
Proxy.GetOptionsCompleted -= handler;
if (args.Error != null)
{
//...
}
if (callback != null)
{
callback(args);
}
};
Proxy.GetOptionsCompleted += handler;
Proxy.GetOptionsAsync();
}
catch (Exception unknownException)
{
//...
throw;
}
}
public override void ResetProxy() //AbortProxy/CloseProxy
{
if (Proxy != null)
{
try
{
Proxy.CloseProxy(); //extension method to handle exception while closing
}
catch (Exception unknownException) //CommunicationObjectFaultedException
{
//...
Proxy.Abort();
}
}
CreateProxy();
}
public override void CheckProxy()
{
if (Proxy == null || (Proxy.State != CommunicationState.Opened && Proxy.State != CommunicationState.Created))
{
ResetProxy();
}
}
public override void CreateProxy() //RecreateProxy
{
Proxy = new WcfClient();
Proxy.InnerChannel.Faulted += OnChannelFaulted;
}
Solution using Castle DP with the ChannelFactoryManager implemented and detailed here:
http://www.codeproject.com/Articles/502121/WCF-in-a-stateful-application-WPF-Silverlight

WCF closing best practice

I read that the best practice for using WCF proxy would be:
YourClientProxy clientProxy = new YourClientProxy();
try
{
.. use your service
clientProxy.Close();
}
catch(FaultException)
{
clientProxy.Abort();
}
catch(CommunicationException)
{
clientProxy.Abort();
}
catch (TimeoutException)
{
clientProxy.Abort();
}
My problem is, after I allocate my proxy, I assign event handlers to it and also initialize other method using the proxy:
public void InitProxy()
{
sdksvc = new SdkServiceClient();
sdksvc.InitClusteringObjectCompleted += new EventHandler<InitClusteringObjectCompletedEventArgs>(sdksvc_InitClusteringObjectCompleted);
sdksvc.InitClusteringObjectAsync(Utils.DSN, Utils.USER,Utils.PASSWORD);
sdksvc.DoClusteringCompleted += new EventHandler<DoClusteringCompletedEventArgs>(sdksvc_DoClusteringCompleted);
sdksvc.CreateTablesCompleted += new EventHandler<CreateTablesCompletedEventArgs>(sdksvc_CreateTablesCompleted);
}
I now need to call the InitProxy() method each Time I use the proxy if I want to use it as best practice suggests.
Any ideas on how to avoid this?
There are several options. One option is to write a helper class as follows:
public class SvcClient : IDisposable {
public SvcClient(ICommunicationObject service) {
if( service == null ) {
throw ArgumentNullException("service");
}
_service = service;
// Add your event handlers here, e.g. using your example:
sdksvc = new SdkServiceClient();
sdksvc.InitClusteringObjectCompleted += new EventHandler<InitClusteringObjectCompletedEventArgs>(sdksvc_InitClusteringObjectCompleted);
sdksvc.InitClusteringObjectAsync(Utils.DSN, Utils.USER,Utils.PASSWORD);
sdksvc.DoClusteringCompleted += new EventHandler<DoClusteringCompletedEventArgs>(sdksvc_DoClusteringCompleted);
sdksvc.CreateTablesCompleted += new EventHandler<CreateTablesCompletedEventArgs>(sdksvc_CreateTablesCompleted);
}
public void Dispose() {
try {
if( _service.State == CommunicationState.Faulted ) {
_service.Abort();
}
}
finally {
_service.Close();
}
}
private readonly ICommunicationObject _service;
}
To use this class write the following:
var clientProxy = new YourClientProxy();
using(new SvcClient(clientProxy)) {
// use clientProxy as usual. No need to call Abort() and/or Close() here.
}
When the constructor for SvcClient is called it then sets up the SdkServiceClient instance as desired. Furthermore the SvcClient class cleans up the service client proxy as well aborting and/or closing the connection as needed regardless of how the control flow leaves the using-block.
I don't see how the ClientProxy and the InitProxy() are linked but if they are linked this strong I'd move the initialization of the ClientProxy to the InitProxy (or make a method that initializes both) so you can control both their lifespans from there.

Using NUnit-2.5 RequiresSTAAttribute with TeamCity 4

Using TeamCity, I'm trying to get a (TestAutomationFX) test that requires an STA thread to run .
It works via a custom app.config that configures NUnit 2.4.x (8) (as referred to by Gishu, thanks, described at http://madcoderspeak.blogspot.com/2008/12/getting-nunit-to-go-all-sta.html)
It works via:
/// <summary>
/// Via Peter Provost / http://www.hedgate.net/articles/2007/01/08/instantiating-a-wpf-control-from-an-nunit-test/
/// </summary>
public static class CrossThreadTestRunner // To be replaced with (RequiresSTA) from NUnit 2.5
{
public static void RunInSTA(Action userDelegate)
{
Exception lastException = null;
Thread thread = new Thread(delegate()
{
try
{
userDelegate();
}
catch (Exception e)
{
lastException = e;
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
if (lastException != null)
ThrowExceptionPreservingStack(lastException);
}
[ReflectionPermission(SecurityAction.Demand)]
static void ThrowExceptionPreservingStack(Exception exception)
{
FieldInfo remoteStackTraceString = typeof(Exception).GetField(
"_remoteStackTraceString",
BindingFlags.Instance | BindingFlags.NonPublic);
remoteStackTraceString.SetValue(exception, exception.StackTrace + Environment.NewLine);
throw exception;
}
}
I'm hoping to use something built in. So NUnit 2.5.0.8322 (Beta 1)'s RequiresSTAAttribute seems ideal. It works standalone, but not via TeamCity, even when I attempt to force the issue via:
<NUnit Assemblies="Test\bin\$(Configuration)\Test.exe" NUnitVersion="NUnit-2.5.0" />
The docs say the runner supports 2.5.0 alpha 4? (http://www.jetbrains.net/confluence/display/TCD4/NUnit+for+MSBuild)
Probably answering my own question, 2.5.0 Aplha 4 doesnt have RequiresSTAAttribute, hence the runner is not honouring my Attribute...
TeamCity 4.0.1 contains NUnit 2.5.0 beta 2. I believe that should work for that case.
Can you see if this helps? Setting STA via the .config file approach... as in pre NUnit 2.5
http://madcoderspeak.blogspot.com/2008/12/getting-nunit-to-go-all-sta.html
For now, I'm using:
private void ForceSTAIfNecessary(ThreadStart threadStart)
{
if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
threadStart();
else
CrossThreadTestRunner.RunInSTA(threadStart);
}
[Test]
public void TestRunApp()
{
ForceSTAIfNecessary(TestRunAppSTA);
}
public void TestRunAppSTA()
{
Assert.That(Thread.CurrentThread.GetApartmentState(), Is.EqualTo(ApartmentState.STA));
...
}
instead of:
[RequiresSTA]
public void TestRunAppSTA()
{
Assert.That(Thread.CurrentThread.GetApartmentState(), Is.EqualTo(ApartmentState.STA));
...
}