How to call a console program from an action - asp.net-mvc

I am building an MVC application that includes an asynchronous image upload so each image, once uploaded, calls the action. Image uploading can be cpu intensive and require time so we are trying to avoid in-action processing.
I have read about using async actions, but we are also processing images at other times, so we have opted to handle image processing through a console application.
What is the proper method for calling a console application from an MVC action asynchronously? Basically we just want to pass the console app some parameters, and tell it start without waiting for any kind of response from the console.
Our program file is an exe.
Speed is our main concern here.
Thanks so much for your help!
EDIT
As per Brian's suggestion here is what we added:
Process pcx = new System.Diagnostics.Process();
ProcessStartInfo pcix = new System.Diagnostics.ProcessStartInfo();
pcix.FileName = "C:\\utils_bin\\fileWebManager\\ppWebFileManager.exe";
pcix.Arguments = WrkGalId.ToString() + " " + websiteId.ToString() + "" + " " + "19" + " \"" + dFileName + "\" ";
pcix.UseShellExecute = false;
pcix.WindowStyle = ProcessWindowStyle.Hidden;
pcx.StartInfo = pcix;
pcx.Start();

You would use Process.Start to execute an external application, e.g.:
Process.Start(#"C:\\path\to\my\application.exe");

Related

Run an automation script via a URL

Maximo 7.6.1.1:
I want to run a Maximo automation script by invoking a URL in a separate system.
Is it possible to do this?
This is a great use-case and something that we've been working through in the last few days.
Create automation script. - mine is called automation_api_test
Manually invoke it through the API using a browser to make sure that you can actually get it to run. (%servername%/maximo/oslc/script/automation_api_test?var1=1212321232&var2=1555&site=OPS&_lid=wilson&_lpwd=wilson)
Script it like you would your regular automation script. Here's one that can read in a few parameters from the URL and use those to perform operations in the core system.
importPackage(Packages.psdi.server);
importPackage(Packages.psdi.util.logging);
var resp = {};
// Get the Site ID from the Query Parameters
//var site = request.getQueryParam("site");
var var1 = request.getQueryParam("var1");
var var2 = request.getQueryParam("var2");
var site = request.getQueryParam("site");
//var zxqponum = request.getQueryParam("ponum");
//logger.debug(zxqprinter);
service.log("TESTING script Params" + request.getQueryParams());
service.log("var1 " + request.getQueryParam("var1"));
service.log("var2 " + request.getQueryParam("var2"));
//count the number of WO's in the site
var woset = MXServer.getMXServer().getMboSet("WORKORDER", request.getUserInfo());
woset.setQbe("SITEID","="+site);
var woCount = woset.count();
resp.wo_count = woCount;
woset.close();
// Get Total Count
resp.total = woCount;
//create the response - still not sure why I had to append the vars to a string.
resp.var1= "" + var1;
resp.var2= "" + var2;
resp.site= "" + site;
var responseBody = JSON.stringify(resp);
Here's an expanded version of Kasey's answer.
Create a sample automation script in Maximo:
Automation Scripts >> More Actions >> Create >> Script
Script [name]: HELLOWORLD
Script Language: js
Paste in this code:
//THIS IS JAVASCRIPT! NOT JYTHON!
//load("nashorn:mozilla_compat.js"); //More info about this here: https://stackoverflow.com/questions/57537142/maximo-js-automation-script-importpackage-is-not-defined
//importPackage(Packages.psdi.server);
//importPackage(Packages.psdi.util.logging);
var resp = {};
var var1 = request.getQueryParam("var1");
resp.var1= " " + var1 + " World!";
var responseBody = JSON.stringify(resp);
Click Create
Try out a URL:
This URL will send the word "Hello" to the automation script. The automation script will append the word " World!" onto "Hello".
The phrase, "Hello World!" is returned.
In a browser, run this URL: http://yourhostname:1234/maximo/oslc/script/helloworld?var1=Hello&_lid=wilson&_lpwd=wilson
Replace yourhostname with your host name
Replace 1234 with your port number
Replace maximo with the appropriate value.
The URL request should return this JSON object to the browser:
{"var1":" Hello World!"}
From there, create a hyperlink in a separate system (using the above URL). And click it to run the automation script.
If the last line in the script were to be deleted, nothing would be returned to the browser.
Note:
The URL only seems to work for me under the WILSON user. It doesn't work with my own user:
{"oslc:Error":{"oslc:statusCode":"401","spi:reasonCode":"BMXAA7901E","oslc:message":
"You cannot log in at this time. Contact the system administrator.","oslc:extendedError"
:{"oslc:moreInfo":{"rdf:resource":"http:\/\/something\/maximo\/oslc\
/error\/messages\/BMXAA7901E"}}}}
Best guess is: my user is not set up correctly.
Here's a really simple JavaScript example:
responseBody = "asdf";
Then just run the URL in a browser (or somewhere else like an automation script in Maximo or a Python script in GIS).
https://<<my host>>/maximo/oslc/script/testscript
It's pretty much the same for Python (no semi-colon):
responseBody = "asdf"

MT4 communication methods

I have tried but couldn't figure it out on my own.
I know MT4 provides Pipe and WebRequest(), as a means of communication, but WebSocket isn't built as part of the Programming. So for now, Pipe is the only thing available. But communication with Pipe breaks at some point. It skips some signals when sent.
How can I get around this please guys?
How can I get around this please guys ?
Free to use either a ZeroMQ or a nanomsg signalling / messaging framework
having been in such a need many years back, started to use ZeroMQ / MQL4-binding, so as to make MetaTrader Terminal work inside a distributed-computing QuantFX-analytics and ML-based augmented trading system.
No O/S localhost-only pipe, no file-based masquerades, but a fair, distributed, low-latency signalling/messaging, with:
remote keyboard / terminal system-console ( yes, added a DSL command language )
remote centralised logs ( avoids MQL4 execution get blocked from resource contentions )
distributed remote AI/ML-predictive engine, with latency under << 80 [ms] RTT
distributed remote automated trade-management processing
ZeroMQ is a way to go, if integration needs are to be kept under your own design controls. A brief sketch was presented here, in [ ZeroMQ hierarchy in less than a five seconds ] Section.
Feel free to read more posts on this and about the differences between WebSockets and ZeroMQ here, in the zeromq and other related posts.
I tried ZeroMQ but couldn't get it working properly.
I'm using WinSockets now and so far have no problems with it.
See: https://www.mql5.com/en/blogs/post/706665
Here you will find a way to use WinSockets in MQL as a server or as a client or both.
I know links can become dead but there is no way to attach files to this answer and the code does not format properly so I cannot include it.
You can then use any programming language that also supports sockets to communicate with your MQL EA. I'm using the build-in node implementation.
See: https://www.digitalocean.com/community/tutorials/how-to-develop-a-node-js-tcp-server-application-using-pm2-and-nginx-on-ubuntu-16-04
const net = require('net');
const port = 7070;
const host = '127.0.0.1';
const server = net.createServer();
server.listen(port, host, () => {
console.log('TCP Server is running on port ' + port + '.');
});
let sockets = [];
server.on('connection', function(sock) {
console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
sockets.push(sock);
sock.on('data', function(data) {
console.log('DATA ' + sock.remoteAddress + ': ' + data);
// Write the data back to all the connected, the client will receive it as data from the server
sockets.forEach(function(sock, index, array) {
sock.write(sock.remoteAddress + ':' + sock.remotePort + " said " + data + '\n');
});
});
// Add a 'close' event handler to this instance of socket
sock.on('close', function(data) {
let index = sockets.findIndex(function(o) {
return o.remoteAddress === sock.remoteAddress && o.remotePort === sock.remotePort;
})
if (index !== -1) sockets.splice(index, 1);
console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
});
});
Pipe in MQL is implemented through files, so you can use files instead of pipes - you will receive same or faster result, and no need to care of the communication

JMeter - fail a test based on the average response time

I am running a JMeter job in Jenkins using performance plugin. I need to fail a job if the average response time < 3 seconds. I see the "duration assertion" in jmeter, but that works on each thread (each http request). Instead is it possible to do the duration assertion on average for each page?
This is the way I tried adding the BeanSehll Listener and Assertion.
Recording Controller
**Home Page**
BeanShell Listener
Debug Sampler
**Page1**
BeanShell Listener
Debug Sampler
Beanshell Assertion
View Results Tree
You can implement this check via some form of Beanshell scripting
Add a Beanshell Listener at the same level as all your requests live
Put the following code into Beanshell Listener's "Script" area
String requests = vars.get("requests");
String times = vars.get("times");
long requestsSum = 0;
long timesSum = 0;
if (requests != null && times != null) {
log.info("requests: " + requests);
requestsSum = Long.parseLong(vars.get("requests"));
timesSum = Long.parseLong(vars.get("times"));
}
long thisRequest = sampleResult.getTime();
timesSum += thisRequest;
requestsSum++;
vars.put("requests", String.valueOf(requestsSum));
vars.put("times", String.valueOf(timesSum));
long average = timesSum / requestsSum;
if (average > 3000){
sampleResult.setSuccessful(false);
sampleResult.setResponseMessage("Average response time is greater than threshold");
}
The code above will record sums of response times for each request and total number of requests into times and requests JMeter Variables
See How to use BeanShell: JMeter's favorite built-in component guide for comprehensive information on Beanshell scripting in Apache JMeter.
Based on the other answer, I managed to create something that works while using multiple threads.
Add the following code as a script to your JSR223 listener, you can also save it to file and load it from file (for easy reuse). I used a parameter in seconds to set the duration threshold.
import org.apache.jmeter.util.JMeterUtils;
int totalRequests = Integer.parseInt(ctx.getThreadGroup().getSamplerController().getProperty("LoopController.loops").getStringValue()) * ctx.getThreadGroup().getNumThreads();
long requestsCount = JMeterUtils.getPropDefault("requestsCount"+sampleResult.toString(),0);
long timesSum = JMeterUtils.getPropDefault("times"+sampleResult.toString(),0);
long thisRequestTime = sampleResult.getTime();
timesSum += thisRequestTime;
requestsCount++;
JMeterUtils.setProperty("requestsCount"+sampleResult.toString(), String.valueOf(requestsCount));
JMeterUtils.setProperty("times"+sampleResult.toString(), String.valueOf(timesSum));
long average = timesSum / requestsCount;
long threshold = Integer.parseInt(args[0])*1000;
if (requestsCount >= totalRequests) {
if(average > threshold){
sampleResult.setSuccessful(false);
sampleResult.setResponseMessage("Average response time is greater than threshold, average: " + String.valueOf(average) + ", threshold: " + threshold);
}
log.info("Average response time (" + sampleResult.toString() + "): " + String.valueOf(average) + ", threshold: " + threshold);
}
This stores it in the global properties, that are saved for the full JVM run. To keep consistency in between runs, I added a setup thread group with a JSR223 sampler, with this code:
import org.apache.jmeter.util.JMeterUtils;
JMeterUtils.getJMeterProperties().clear();
log.info("cleared properties");

Load and reload external SWF in AIR for iOS

I found several info on how to load one or more external SWF files, packaged with my AIR iOS App, the actual working code is:
var myUrlRequest:URLRequest = new URLRequest(mySWF);
var myLoaderContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain, null);
var loader: Loader = new Loader();
loader.load(myUrlRequest, myLoaderContext);
Object(root).MK.addChild(loader)
It works on Android devices and on Windows PC, but on iOS it loads the external SWFs only the first time. In my project I have several buttons that loads an external SWF, but each button works only the first time.
Any idea? It seems very unuseful if I can't reload an SWF.
If you can't load something a second time, perhaps it would be best to simply cache it and make a point of only loading it once?
A good way to handle this would be to load the SWF files into separate movieclips the first time and then when needing to "load" them anytime after that, just show those movieclips that already have the SWF files loaded in them.
You can't load a SWF file that contains any ActionScript ByteCode (ABC) then unload it and reload it on iOS. If you attempt to do this, the runtime throws error 3764.
I had problems loading SWF's even without code a second time. The solution I found depended on whether the code was from the application area (packaged with the app) or loaded externally (either from the web or downloaded into the caches folder).
I wrote an extended post about here, if you're interested: http://www.eqsim.com/blog/?p=400
In a nutshell, here is my code for setting the path:
var moduleDirectoryPath = "/modules/";
if (externalContent == FROM_CACHE) {
moduleDirectoryPath = File.cacheDirectory.url + moduleDirectoryPath;
} else if (externalContent == FROM_WEB) {
moduleDirectoryPath = "http://our-online-content.com" + moduleDirectoryPath;
}
then here is my code for preparing the path, if the SWF is from the app area or otherwise (cache or web):
if (loadFromApp) {
path = moduleDirectoryPath + module_folder + "/" + module + "?nf="+getTimer();
} else {
path = moduleDirectoryPath + module_folder + "/" + module;
}
Finally, my loading statements:
request = new URLRequest(path);
request.cacheResponse = false;
request.useCache = false;
_lc = new LoaderContext(false, ApplicationDomain.currentDomain, null);
moduleLoader.load(request, _lc);
and now I can load SWF's and reload them (more importantly). Of course the SWF's do not have bytecode in them.

context menu demo app not working crossrider

I am generating context menu when user selects some text and right click it. I tried implementing it, problem is even sample application is not working.
http://crossrider.com/apps/10565/ide
appAPI.contextMenu.add("key1", "Display data object", function (data) {
var sAlertText = 'pageUrl: ' + data.pageUrl + '\r\n' +
'linkUrl: ' + data.linkUrl + '\r\n' +
'selectedText:' + data.selectedText + '\r\n' +
'srcUrl:' + data.srcUrl;
alert(sAlertText);
}, ["all"]);
Only data.pageUrl is available rest of all are "undefined". I want selectedText.
Disclaimer: I work at Crossrider.
Indeed there was an issue with the contextMenu due to a change in the Chrome API.
We've fixed this and now the demo app works.
Thank you for reporting this and please feel free to let us know if you encounter any issues!
Amir

Resources