Using Quartz.Net embedded into a Windows Service - windows-services

I Am trying to use Quartz.Net so as to Schedule Jobs Within a Windows Service that I developped.
I included the following code on the Onstart Method, scheduler is a Class attribute
private readonly IScheduler scheduler;
logger = LogManager.GetLogger(typeof (TelegestionService));
scheduler = new StdSchedulerFactory().GetScheduler();
var job = new JobDetail("job1", "group1", typeof (HelloJob));
var trigger = new SimpleTrigger("trigger1", "group1", runTime);
scheduler.ScheduleJob(job, trigger);
This works fine for me. I got the Job running.
Now I'am trying to make the scheduler embedded remotely accessible, based en Example12 in the Quartz source Examples (the Console Server/Client works fine).
var properties = new NameValueCollection();
properties["quartz.scheduler.instanceName"] = "RemoteServer";
properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
properties["quartz.threadPool.threadCount"] = "5";
properties["quartz.threadPool.threadPriority"] = "Normal";
properties["quartz.scheduler.exporter.type"] = "Quartz.Simpl.RemotingSchedulerExporter, Quartz";
properties["quartz.scheduler.exporter.port"] = "555";
properties["quartz.scheduler.exporter.bindName"] = "QuartzScheduler";
properties["quartz.scheduler.exporter.channelType"] = "tcp";
scheduler = new StdSchedulerFactory(properties).GetScheduler();
The service starts correctly and so does the scheduler but i cannot remotely schedule the Job using a Console/Winform Client (Connection refused).
I checked the LISTENING ports on my server using SysInternals TcpView and I cannot find the 555 port specified above.
Am suspecting an issue related to .Net Remoting but cannot figure out how to resolve this.
Any ideas ?
Thanks in advance.

could use http://topshelf-project.com/ to host Scheduler which will provide hostFactory and using that could shelf host via HttpSelfHostServer, http is better as you could invoke job via controller. sample code as below
hope this helps.
using System;
using System.Configuration;
using System.Web.Http;
using System.Web.Http.SelfHost;
using Topshelf;
class Program
{
static void Main(string[] args)
{
HostFactory.Run(hostConfigurator =>
{
if (!Uri.TryCreate("http://localhost:8080", UriKind.RelativeOrAbsolute, out var hostname))
{
throw new ConfigurationErrorsException($"Could not uri");
}
var serviceName = "my service";
var hostConfiguration = new HttpSelfHostConfiguration(hostname);
hostConfiguration.Routes.MapHttpRoute("API", "{controller}/{action}/{id}", (object)new
{
id = RouteParameter.Optional
});
var httpSelfHostServer = new HttpSelfHostServer(hostConfiguration);
// Impl.Scheduler would be your implementation of scheduler
hostConfigurator.Service<Impl.Scheduler>(s =>
{
s.ConstructUsing(name => new Impl.Scheduler());
s.WhenStarted(tc =>
{
tc.Start();
httpSelfHostServer.OpenAsync().Wait();
});
s.WhenStopped(tc =>
{
tc.Stop();
//dispose scheduler implementation if using IOC container
httpSelfHostServer.CloseAsync().Wait();
});
});
hostConfigurator.RunAsLocalSystem();
hostConfigurator.SetDescription(serviceName);
hostConfigurator.SetDisplayName(serviceName);
hostConfigurator.SetServiceName(serviceName);
});
}
}

Related

Azure notification hub installation c#

Can anyone help me with Azure notification hub, how to set up device installation form c# code. I have problem with the Installation object. How to set it to pass it as parameter to CreateOrUpdateInstallation method of hub client instance. It's not clear to me.
I have a hub on azure that works with device registration like charm in local, but uploaded on azure are not working. Now I wanna try with istalation.
thnx
update: after 4 days, I figured out, that you can't send notification to yourself. Azure somehow knows that you are sending notification to yours phone, and that's why my welcome message never delivered to my phone.
update: this is how now I install the device i my backend code:
[HttpGet]
[Route("api/push/test-installation")]
public async Task<IActionResult> NotificationInstalationTest()
{
string connectionString = "{{my connection string}}";
string hubName = "{{my hub name}}";
string token = "{{tokne}}";
NotificationHubClient hubClient = NotificationHubClient.CreateClientFromConnectionString(connectionString, hubName);
string notificationText = $"Test message for Azure delivery for Atila at: {DateTime.Now.ToShortTimeString()}";
var alert = new JObject
(
new JProperty("aps", new JObject(new JProperty("alert", notificationText))),
new JProperty("inAppMessage", notificationText)
).ToString(Newtonsoft.Json.Formatting.None);
IList<string> tags = new List<string>();
tags.Add("email");
IDictionary<string, string> pushVariables = new Dictionary<string, string>();
pushVariables.Add( "email", "atila#panonicit.com" );
Installation installation = new Installation();
installation.InstallationId = Guid.NewGuid().ToString();
installation.Platform = NotificationPlatform.Apns;
installation.PushChannel = token;
installation.Tags = tags;
installation.PushVariables = pushVariables;
await hubClient.CreateOrUpdateInstallationAsync(installation);
NotificationOutcome result = await hubClient.SendAppleNativeNotificationAsync(alert);
return Ok("Success");
}
Now when I hit this endpoint with Postman it works, if the same endpoint call comes from iOS it not works!
thnx
How to set it to pass it as parameter to CreateOrUpdateInstallation method of hub client instance. It's not clear to me.
Based on my understanding, you are registering the notification hub from your backend using the installation model. For your WebAPI project, assuming your method for create/update an installation as follows:
InstallationController.cs
//PUT api/installation
public async Task<HttpResponseMessage> Put(DeviceInstallation deviceUpdate)
{
Installation installation = new Installation();
installation.InstallationId = deviceUpdate.InstallationId;
//TODO:
await hub.CreateOrUpdateInstallationAsync(installation);
return Request.CreateResponse(HttpStatusCode.OK);
}
For your mobile client, you could refer to the following method:
private async Task<HttpStatusCode> CreateOrUpdateInstallationAsync(DeviceInstallation deviceInstallation)
{
using (var httpClient = new HttpClient())
{
//TODO: set your authorization header
//httpClient.DefaultRequestHeaders.Authorization
var putUri =$"{your-backend-endpoint}/api/installation";
string json = JsonConvert.SerializeObject(deviceInstallation);
var response = await httpClient.PutAsync(putUri, new StringContent(json, Encoding.UTF8, "application/json"));
return response.StatusCode;
}
}
Moreover, for more details you could refer to Registration management and here for building backend with the registration model to build your backend using the installation model.

Missing Configuration File For Tests - Aqueduct

When implementing OAuth with aqueduct I mistakenly didn't follow the test driven development ideology, and I am paying for it now...
When I run my tests, I get the error:
"No configuration file found. See README.md."
Which is thrown from the initializeApplication method in my AppSink class.
As I understand it, tests make use of the config.src.yaml file so I have configured my test harness accordingly:
application = new Application<OdexSink>();
application.configuration.port = 0;
application.configuration.configurationFilePath = "config.src.yaml";
Since I was able to run the tests before I implemented the AuthServer etc, I suspect it happened along the way.
My test setUp is as follows:
var app = new Application<OdexSink>();
TestClient client;
setUp(() async {
await app.start(runOnMainIsolate: true);
client = new TestClient(app);
var ctx = ManagedContext.defaultContext;
var builder = new SchemaBuilder.toSchema(ctx.persistentStore, new Schema.fromDataModel(ctx.dataModel), isTemporary: true);
for (var cmd in builder.commands) {
await ctx.persistentStore.execute(cmd);
}
});
And my Test harness start() method is:
Future start() async {
RequestController.letUncaughtExceptionsEscape = true;
application = new Application<OdexSink>();
application.configuration.port = 0;
application.configuration.configurationFilePath = "config.src.yaml";
await application.start(runOnMainIsolate: true);
await createDatabaseSchema(ManagedContext.defaultContext, sink.logger);
await addClientRecord();
await addClientRecord(clientID: DefaultClientID, clientSecret: DefaultClientSecret);
client = new TestClient(application)
..clientID = DefaultClientID
..clientSecret = DefaultClientSecret;
}
My config.src.yaml file exits, and contains DB information.
Ah, just one small thing - in your setUp method, you are creating and starting an Application instead of that TestApplication harness. It should look like this
var app = new TestApplication();
setUp(() async {
await app.start();
});
All of the other stuff in setUp is already done in your test harness and you can use the TestClient as app.client:
expect(await app.client.request("/endpoint"), hasStatus(200));

running ECSTask in IOS

I am new to IOS platform. I have a code snippet written using JAVA API.
AmazonECS amazonECS = new AmazonECSClient(credentials).withRegion(usWest1);
String command="bash /opt/run-task.sh "+"/mnt/s3/inputFile1::/mnt/s3/inputFile2"+" "+ "outputFile";
ContainerOverride containerOverrides = new ContainerOverride().withCommand(command).withName("<<container name>>");
TaskOverride overrides = new TaskOverride().withContainerOverrides(containerOverrides);
RunTaskRequest runTaskRequest = new RunTaskRequest().withCluster("<<cluster name>>").withTaskDefinition("<<task definition arn>>")
.withOverrides(overrides).withGeneralProgressListener(new ProgressListener() {
#Override
public void progressChanged(ProgressEvent progressEvent) {
System.out.println(progressEvent.getBytesTransferred());
System.out.println(progressEvent.getEventType());
}
});
Task task = new Task().withTaskDefinitionArn("<<task definition arn>>")
.withOverrides(overrides);
RunTaskResult runTaskResult = amazonECS.runTask(runTaskRequest).withTasks(task);
List<Failure> failures = runTaskResult.withTasks(task).getFailures();
I am using ffmpeg to merge few video files as single file. I need to know if there is equivalent functionality available in IOS.

can't run the automated project in testcomplete when it calls from jenkins

can't run the automated project in testcomplete when calls from jenkins.
In our continuous integration part ,the project is automated using testcomplete and it is calling through jenkins with the help of bat file.The scripts inside the bat file is
"C:\Program Files\Automated QA\TestComplete 7\Bin\TestComplete.exe " "D:\Test Complete7 Projects\ProjectInput_AllSamples\ProjecInputs.pjs" /r /p:Samples /rt:Main "iexplore" /e
It will open testcomplete and iexplorer ,but it is not filling the data(automation).
It is working perfectly when we directly call the bat file with out jenkins.Is there any solution
From your description it sounds like something in Windows stopping you from allowing your test application to work normally. It might be the fact that the second user could be a problem but I can't confirm that as I was not able find any definite explanations of how it works in Windows XP. I am pretty sure that this won't work on a Windows Vista, 7, 8 or server machine though because of the changes in architecture.
It sounds like the best solution is to make sure that your automated UI tests are started by an interactive user. When I was trying to add automated testing to our builds we used TestComplete 7 on a Windows XP SP2 virtual machine. In order to start our tests as an interactive user we:
Made an user log on when windows started, this way there was always an interactive user which means there was an actual desktop session which has access to the keyboard / mouse. I seem to remember (but can't find any links at the moment) that without an interactive user there is no active desktop that can access the keyboard / mouse.
We wrote a little app that would start when the interactive user logged on. This app would look at a specific file and when that file changed / was created it would read the file and start the application. The code for this app looked somewhat like this:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ApplicationStarter
{
class Program
{
// The string used to indicate that the application should quit.
private const string ExitString = "exit";
// The path which is being watched for changes.
private static string s_LoadFilePath;
static void Main(string[] args)
{
try
{
{
Debug.Assert(
args != null,
"The arguments array should not be null.");
Debug.Assert(
args.Length == 1,
"There should only be one argument.");
}
s_LoadFilePath = args[0];
{
Console.WriteLine(
string.Format(
CultureInfo.InvariantCulture,
"Watching: {0}",
s_LoadFilePath));
}
if (File.Exists(s_LoadFilePath))
{
RunApplication(s_LoadFilePath);
}
using (var watcher = new FileSystemWatcher())
{
watcher.IncludeSubdirectories = false;
watcher.NotifyFilter =
NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.FileName
| NotifyFilters.DirectoryName;
watcher.Path = Path.GetDirectoryName(s_LoadFilePath);
watcher.Filter = Path.GetFileName(s_LoadFilePath);
try
{
watcher.Created += OnConfigFileCreate;
watcher.EnableRaisingEvents = true;
// Now just sit here and wait until hell freezes over
// or until the user tells us that it has
string line = string.Empty;
while (!string.Equals(line, ExitString, StringComparison.OrdinalIgnoreCase))
{
line = Console.ReadLine();
}
}
finally
{
watcher.Created -= OnConfigFileCreate;
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private static void RunApplication(string configFilePath)
{
var appPath = string.Empty;
var arguments = string.Empty;
using (var reader = new StreamReader(configFilePath, Encoding.UTF8))
{
appPath = reader.ReadLine();
arguments = reader.ReadLine();
}
// Run the application
StartProcess(appPath, arguments);
}
private static void StartProcess(string path, string arguments)
{
var startInfo = new ProcessStartInfo();
{
startInfo.FileName = path;
startInfo.Arguments = arguments;
startInfo.ErrorDialog = false;
startInfo.UseShellExecute = true;
startInfo.RedirectStandardOutput = false;
startInfo.RedirectStandardError = false;
}
Console.WriteLine(
string.Format(
CultureInfo.InvariantCulture,
"{0} Starting process {1}",
DateTime.Now,
path));
using (var exec = new Process())
{
exec.StartInfo = startInfo;
exec.Start();
}
}
private static void OnConfigFileCreate(
object sender,
FileSystemEventArgs e)
{
Console.WriteLine(
string.Format(
CultureInfo.InvariantCulture,
"{0} File change event ({1}) for: {2}",
DateTime.Now,
e.ChangeType,
e.FullPath));
// See that the file is there. If so then start the app
if (File.Exists(e.FullPath) &&
string.Equals(s_LoadFilePath, e.FullPath, StringComparison.OrdinalIgnoreCase))
{
// Wait for a bit so that the file is no
// longer locked by other processes
Thread.Sleep(500);
// Now run the application
RunApplication(e.FullPath);
}
}
}
}
This app expects the file to have 2 lines, the first with the app you want to start and the second with the arguments, so in your case something like this:
C:\Program Files\Automated QA\TestComplete 7\Bin\TestComplete.exe
"D:\Test Complete7 Projects\ProjectInput_AllSamples\ProjecInputs.pjs" /r /p:Samples /rt:Main "iexplore" /e
You should be able to generate this file from Jenkins in a build step.
Finally you may need to watch the TestComplete process for exit so that you can grab the results at the end but I'll leave that as an exercise to reader.
If you are running Jenkins (either master or slave) as a windows service, ensure it is running as a user and not as Local System.
We also do the same as Gentlesea's recommends, we run TestExecute on our Jenkins Slaves and keepo the TestComplete licenses for the people designing the TestComplete scripts.

Windows service always writes to custom log and application log

I am using a custom EventLog for my Windows service. The service creates the event source after installtion. I don't have any problems.
However, I have setup my service so that I can run it from the IDE using the following mechanism:
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledException);
string firstArgument = string.Empty;
if (args.Length > 0)
firstArgument = args[0].ToUpperInvariant();
if (string.Compare(firstArgument, "-CONSOLE", true) == 0)
{
new SchedulerService().RunConsole(args);
}
else
{
ServiceBase[] services = new ServiceBase[] { new SchedulerService() };
ServiceBase.Run(services);
}
}
When writing to the event log, it seems to write my custom event log AND the application log. How can I prevent this from occurring?
Below is the code I am using to write to the event log: (The EventLog app setting is the same for the source and name)
using (System.Diagnostics.EventLog eventLog =
new EventLog(
System.Configuration.ConfigurationManager.AppSettings["EventLog"], ".",
System.Configuration.ConfigurationManager.AppSettings["EventLog"]))
{
eventLog.WriteEntry(msg, entryType);
}
It seems that a reboot of my machine has fixed this problem. I am not sure why yet, but I am going to assume the Event Viewer mechanism got in to some kind of weird state.

Resources