Can i run WCF Workflow Service using WorkflowApplication class? - workflow-foundation-4

im wondering is it possible to load xamlx wcf workflow from file and run it using WorkflowApplication?
Desired result:
using (Stream xaml = File.OpenRead("Service1.xamlx"))
{
activity = ActivityXamlServices.Load(xaml);
}
var workflowApplication = new WorkflowApplication(activity);
workflowApplication.Run();

Extract the WorkflowService Root and run it on wfApp
var svc = (WorkflowService)XamlServices.Load("c:\\path\\Service1.xamlx");
WorkflowApplication wfApp = new WorkflowApplication(svc.Body);
wfApp.Run();
Still not understanding the reason to run a WorkflowService in a WorkflowApplication. Keep in mind that the inverse(run activity workflow with a receive activity as a WorkflowService) is totally valid.

WorkflowApplication was not made to expose endpoints. Use WorkflowServiceHost instead
WorkflowServiceHost host = new WorkflowServiceHost(activityLoadedFromXaml, baseAddress);
host.Description.Behaviors.Add(new System.ServiceModel.Description.ServiceMetadataBehavior() { HttpGetEnabled = true });
host.AddDefaultEndpoints();
host.Open();

Related

Load balance with thrift and nginx

I have the following thrift server (socket), listening for connections on a specific host/port.
final TProtocolFactory factory = new TBinaryProtocol.Factory();
TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(serverPort);
final SignatureService.Processor theProcessor = new SignatureService.Processor(new SignatureServiceFacade());
TServer server = new THsHaServer(new THsHaServer.Args(serverTransport).processor(theProcessor).
protocolFactory(factory).
minWorkerThreads(minThreads).
maxWorkerThreads(maxThreads));
And following client connection:
clientTransport = new TFramedTransport(new TSocket(signatureHost, signaturePort));
final TProtocol theProtocol = new TBinaryProtocol(clientTransport);
client = new SignatureService.Client(theProtocol);
clientTransport.open();
//call the business specific method
client.doStuff(param1, param2, param3);
As we can see in the code above I need to provide the host and port in order to open a connection with the server.
But I want to use a service discovery with load balance support, because I'll have multiple instances of my service running.
Anybody has an example of this using nginx? All the examples is using regular http rest based applications.
Tks in advance.

How do I make a SignalR external reference to hub and not perform circular reference?

So, I'm trying to create a sample where there are the following components/features:
A hangfire server OWIN self-hosted from a Windows Service
SignalR notifications when jobs are completed
Github Project
I can get the tasks queued and performed, but I'm having a hard time sorting out how to then notify the clients (all currently, just until I get it working well) of when the task/job is completed.
My current issue is that I want the SignalR hub to be located in the "core" library SampleCore, but I don't see how to "register it" when starting the webapp SampleWeb. One way I've gotten around that is to create a hub class NotificationHubProxy that inherits the actual hub and that works fine for simple stuff (sending messages from one client to all).
In NotifyTaskComplete, I believe I can get the hub context and then send the message like so:
private void NotifyTaskComplete(int taskId)
{
try
{
var hubContext = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
if (hubContext != null)
{
hubContext.Clients.All.sendMessage(string.Format("Task {0} completed.", taskId));
}
}
catch (Exception ex)
{
}
}
BUT, I can't do that if NotificationHubProxy is the class being used as it's part of the SampleWeb library and referencing it from SampleCore would lead to a circular reference.
I know the major issue is the hub in the external assembly, but I can't for the life of me find a relevant sample that's using SignalR or MVC5 or setup in this particular way.
Any ideas?
So, the solution was to do the following two things:
I had to use the SignalR .NET client from the SampleCore assembly to create a HubConnection, to create a HubProxy to "NotificationHub" and use that to Invoke the "SendMessage" method - like so:
private void NotifyTaskComplete(string hostUrl, int taskId)
{
var hubConnection = new HubConnection(hostUrl);
var hub = hubConnection.CreateHubProxy("NotificationHub");
hubConnection.Start().Wait();
hub.Invoke("SendMessage", taskId.ToString()).Wait();
}
BUT, as part of creating that HubConnection - I needed to know the url to the OWIN instance. I decided to pass that a parameter to the task, retrieving it like:
private string GetHostAddress()
{
var request = this.HttpContext.Request;
return string.Format("{0}://{1}", request.Url.Scheme, request.Url.Authority);
}
The solution to having a Hub located in an external assembly is that the assembly needs to be loaded before the SignalR routing is setup, like so:
AppDomain.CurrentDomain.Load(typeof(SampleCore.NotificationHub).Assembly.FullName);
app.MapSignalR();
This solution for this part came from here.

Publishing with Core Service and Impersonation

I have a Tridion Core Service Web Application to publish pages. When logged into the server and running it from there via a browser client calling a web service with ajax it works fine. However, when I run the application from my desktop it does nothing, and also throws no error messages.
*Edit:
The Web App hosting the web service is running as an 'Application' under the Tridion 2011 CMS website. This is done to avoid cross-domain ajax issues/
Update: The code below is working fine - both with the impersonate and also with Nick's solution. My issue was actually in how I was calling the web service from jQuery and using the appropriate URL. I am leaving the code and question so maybe it will help others.
My code is:
string binding = "wsHttp_2011";
using (var client = new SessionAwareCoreServiceClient(binding))
{
client.Impersonate("company\\cms_svc");
// ** Get Items to Publish
List<string> itemsToPublish = GetItemsToPublish(publishItem.TcmUri, client);
PublishInstructionData instruction = new PublishInstructionData
{
ResolveInstruction = new ResolveInstructionData() { IncludeChildPublications = false },
RenderInstruction = new RenderInstructionData()
};
PublicationTargetData pubtarget = (PublicationTargetData)client.Read(publishItem.PubTargetUri, readoptions);
List<string> target = new List<string>();
target.Add(pubtarget.Id);
client.Publish(itemsToPublish.ToArray(), instruction, target.ToArray(), GetPublishPriority(publishItem.Priority), readoptions);
}
Have at look at this page on SDL Live Content, which explains various types of scenarios for connecting as different users:
http://sdllivecontent.sdl.com/LiveContent/content/en-US/SDL_Tridion_2011_SPONE/task_87284697A4BB423AAD5387BBD6884735
As per the docs, instead of impersonation you may want to establish your Core Service connection as follows using NetworkCredential:
using (ChannelFactory<ISessionAwareCoreService> factory =
new ChannelFactory<ISessionAwareCoreService>("netTcp_2011"))
{
NetworkCredential networkCredential =
new NetworkCredential("username", "password", "domain");
factory.Credentials.Windows.ClientCredential = networkCredential;
ISessionAwareCoreService client = factory.CreateChannel();
Console.WriteLine(client.GetCurrentUser().Title);
}

How to host duplex wcf service on a VPS

i am trying to host a wcf service which has a following attribute;
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
and i am creating host class like this;
var uri = new Uri("net.tcp://localhost:7951");
var binding = new NetTcpBinding();
host = new ServiceHost(typeof(ChatService), uri);
ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb == null) host.Description.Behaviors.Add(new ServiceMetadataBehavior());
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
host.AddServiceEndpoint(typeof(IChat), new NetTcpBinding(), "");
host.Open();
So, on developer computer and dedicated server this is working. However, what i need to do is, host this on a VPS (vitual private server).
I thought making a web project and adding this code block to global.asax application start method. but this failed. I suspect problem that the port is closed from firewall maybe.
What solution should I follow?

asp.net web api: accessing uploaded file stream

I have an asp.net web api application which is acting as a Relay to a wcf web service. In certain scenarios I want to upload large files. The methods in the wcf service accept files as stream.
I do not want to save the files on my intermediate server I want to access the stream of the uploaded file and provide it to the wcf method so that the data is directly streamed to the wcf service.
Here is similar scenario when client is downloading the file
using (IProductsChannel channel = ChannelFactory.CreateChannel())
{
result.Content = new StreamContent(channel.GetFile());
result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
return result;
}
Here is at least one way of doing it. using the HTTPContext the only problem with this one is that it is not good for unit testing so we have to abstract it out in the final solution.
var file = HttpContext.Current.Request.Files[0];
var result = new HttpResponseMessage(HttpStatusCode.OK);
using (IProductsChannel channel = ChannelFactory.CreateChannel())
{
channel.SaveFile(file.InputStream);
}
return new HttpResponseMessage(HttpStatusCode.Created);
}

Resources