I need to use more commands (cd, mkdir, rmdir) with SFTPOutboundGateway, but according to the official documentation, there is only a handful of commands available, none of the other ones I need being included. Is there a reason behind it ? Is there a(nother) way to use more commands such as cd, mkdir and rmdir ?
cd in a gateway makes no sense since it effectively would do nothing.
For commands not supported by the gateway, use the SftpRemoteFileGateway from your code in a service activator.
For commands not supported by the template, use
/**
* Execute the callback's doInSession method after obtaining a session.
* Reliably closes the session when the method exits.
*
* #param callback the SessionCallback.
* #param <T> The type returned by
* {#link SessionCallback#doInSession(org.springframework.integration.file.remote.session.Session)}.
* #return The result of the callback method.
*/
<T> T execute(SessionCallback<F, T> callback);
and
#FunctionalInterface
public interface SessionCallback {
/**
* Called within the context of a session.
* Perform some operation(s) on the session. The caller will take
* care of closing the session after this method exits.
*
* #param session The session.
* #return The result of type T.
* #throws IOException Any IOException.
*/
T doInSession(Session<F> session) throws IOException;
}
For commands not supported by Session, use
/**
* Get the underlying client library's client instance for this session.
* Returns an {#code Object} to avoid significant changes to -file, -ftp, -sftp
* modules, which would be required
* if we added another generic parameter. Implementations should narrow the
* return type.
* #return The client instance.
* #since 4.1
*/
Object getClientInstance();
#Override
public ChannelSftp getClientInstance() {
return this.channel;
}
and operate on the JSch client directly.
Related
I am writing a node application that uses node-cron to schedule certain function to run at specific times. Currently the code for this is embedded in the main application. I want to move the configuration of scheduled tasks out to a config file, so want need to store the function names in a variable to achieve this, as the schedule tasks call out a number of functions in different modules etc.
For information the syntax to schedule a cron task is this:
cron.schedule('* * * * *', () => {functiontocall()});
The code block below shows how I am currently storing the tasks in an object and trying to schedule them with node-cron.
mycronobj = [
{scheduletime : "* * * * *", schedulefunction : 'testfunction1'},
{scheduletime : "*/5 * * * *", schedulefunction : 'testfunction2'},
{scheduletime : "*/10 * * * *", schedulefunction : 'testfunction3'},
]
for (item in mycronobj) {
cron.schedule(mycronobj[item].scheduletime, () => {mycronobj[item].schedulefunction()});
}
However this doesn't work, the scheduled functions don't run. I have tried storing the functions names as a string (as shown) or direct as
{scheduletime : "* * * * *", schedulefunction : testfunction1()}
When trying to add the scheduled function I have tried this with the following syntaxes:
mycronobj[item].schedulefunction()
mycronobj[item]schedulefunction
mycronobj[item].schedulefunction
None of which have worked for me. I have tried looking for an answer to this and I tried using eval(), but this also didn't work correctly, the outcome was that a task with first schedule ("* * * * *") was scheduled with the last function 'testfunction3' was applied, also I dont really want to use eval as I have read its not great practice and can be avoided if you know what your doing (clearly I don't).
Other options I have come across is to use Window which doesn't exist in Node or This, which I cannot get to work either.
Thanks in advance.
The reason your code isn't working is that mycronobj[item]schedulefunction is a string so is not invokable. You need to turn this string into a reference to the function with the same name.
The simplest solution to this is using eval, e.g:
for (item of mycronobj) {
cron.schedule(item.scheduletime, () =>
eval(`${item.schedulefunction}()`);
}
However this is a really bad idea, and allows for arbitrary code execution which is generally considered a very bad thing (tm).
Node gives you a slightly safer alternative to this using the vm module, which can create a limited sandbox in which your code can execute:
const vm = require("vm");
let context = vm.createContext({ foo });
for (item of mycronobj) {
cron.schedule(item.scheduletime, () =>
vm.runInContext(`${item.schedulefunction}()`, context);
}
This is only marginally better though since it can still allow arbitrary code execution, so by far the safest option is just to explicitly list exactly which functions are allowed to be called:
const commands = {
testfunction1: () => console.log("I am 1"),
testfunction2: () => console.log("I am 2"),
testfunction3 // Reference existing function
}
function testfunction3() { console.log("I am 3"); }
for (item of mycronobj) {
let func = commands[item.schedulefunction];
if (!func) { throw new Error(`Unknown command: "${item.schedulefunction}"`); }
cron.schedule(item.scheduletime, func);
}
This also has the benefit of determining during setup whether functions are valid rather than only when the cron job runs.
I am confused in laravel queued jobs when I run the code below it processes user_id 1,2,3,4,5 but when it's running after the 1 minute mark it will try to run user_id 1,2,3,4,5 again and not continue with 6,7,8,9,10. I want to run this continuously until it finishes through all the users (meaning I don't know the timing when it will finish going through all the users). How do I go about this?
app/console/kernel
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use App\User;
use Illuminate\Support\Facades\File;
use App\Exceptions\Handler;
use App\Jobs\UserJob;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$users = User::where('is_status', 1)->get();
foreach( $users as $user ){
$schedule->job( new UserJob($user) )->everyMinute();
}
}
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
this is my cronjob which runs every minute
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
Have you tried giving it a name and add without lapping, perhaps its starting, before its finished. I was struggling with a similar problem.
->name('Process Whatever')
->withoutOverlapping()
After I update pjsip from v2.6 to v2.7.1,my app will assertion failed with fuction pjsua_set_snd_dev().
According pjsip's ticket #1941:
To make outgoing call:
func provider(_ provider: CXProvider, perform action: CXStartCallAction) {
/* 1. We must not start call audio here, and can only do so
* once the audio session has been activated by the system
* after having its priority elevated. So, make sure that the sound
* device is closed at this point.
*/
/* 2. Provide your own implementation to configure
* the audio session here.
*/
configureAudioSession()
/* 3. Make call with pjsua_call_make_call().
* Then use pjsua's on_call_state() callback to report significant
* events in the call's lifecycle, by calling iOS API
* CXProvider.reportOutgoingCall(with: startedConnectingAt:) and
* CXProvider.reportOutgoingCall(with: ConnectedAt:)
*/
/* 4. If step (3) above returns PJ_SUCCESS, call action.fulfill(),
* otherwise call action.fail().
*/
}
To handle incoming call:
func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
/* 1. We must not start call audio here, and can only do so
* once the audio session has been activated by the system
* after having its priority elevated. So, make sure that the sound
* device is closed at this point.
*/
/* 2. Provide your own implementation to configure
* the audio session here.
*/
configureAudioSession()
/* 3. Answer the call with pjsua_call_answer().
*/
/* 4. If step (3) above returns PJ_SUCCESS, call action.fulfill(),
* otherwise call action.fail().
*/
}
To start sound device:
func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
/* Start call audio media, now that the audio session has been
* activated after having its priority boosted.
*
* Call pjsua API pjsua_set_snd_dev() here.
*/
}
When calling pjsua API pjsua_set_snd_dev(),there show:
Assertion failed: (param && id!=PJMEDIA_AUD_INVALID_DEV), function
pjmedia_aud_dev_default_param, file ../src/pjmedia/audiodev.c, line
487.
I found that v2.7.1, in pjsua_set_no_snd_dev(),there is
pjsua_var.cap_dev = PJSUA_SND_NO_DEV; pjsua_var.play_dev =
PJSUA_SND_NO_DEV;
but in v2.6 ,do not have this.
PJSUA_SND_NO_DEV and PJMEDIA_AUD_INVALID_DEV are same as -3.
Is this a bug,or I confuse anything?
Steve have you added
App provides Voice over IP services required background modes in Capabilities
Or you can add in to directly in Info.plist
i am using
SimpleWebServiceOutboundGateway
simpleGateway.setSendTimeout(1000);
to call a web-service , but some time web-service takes more time to give response , and i want to set timeout so that it should terminate flow if response is delay.even after setSendTimeOut , it keeps on waiting . how can i achieve timeout ?
Quoting JavaDocs:
/**
* Set the timeout for sending reply Messages.
* #param sendTimeout The send timeout.
*/
public void setSendTimeout(long sendTimeout) {
this.messagingTemplate.setSendTimeout(sendTimeout);
}
as a part of the AbstractMessageProducingHandler and it is fully related to already a message to send to the output channel. That isn't a part of the SOAP protocol interaction.
You have to take a look to the options of your particular WebServiceMessageSender. For example HttpComponentsMessageSender has options like:
/**
* Sets the timeout until a connection is established. A value of 0 means <em>never</em> timeout.
*
* #param timeout the timeout value in milliseconds
* #see org.apache.http.params.HttpConnectionParams#setConnectionTimeout(org.apache.http.params.HttpParams, int)
*/
public void setConnectionTimeout(int timeout) {
if (timeout < 0) {
throw new IllegalArgumentException("timeout must be a non-negative value");
}
org.apache.http.params.HttpConnectionParams.setConnectionTimeout(getHttpClient().getParams(), timeout);
}
/**
* Set the socket read timeout for the underlying HttpClient. A value of 0 means <em>never</em> timeout.
*
* #param timeout the timeout value in milliseconds
* #see org.apache.http.params.HttpConnectionParams#setSoTimeout(org.apache.http.params.HttpParams, int)
*/
public void setReadTimeout(int timeout) {
by using configuration file,
<int-http:inbound-gateway request-channel="requestData" **reply-timeout="5000"**
supported-methods="GET" path="/{oft}/users/{userId}"
payload-expression="#pathVariables.userId" reply-channel="responseChannel" >
<int-http:header name="outputfile" expression="#pathVariables.oft"/>
</int-http:inbound-gateway>
I am using kue for my job queue, and I'd like to know without using the GUI how many jobs are still left, how many have failed, etc. How can I retrieve this kind of information?
For example, after a few minutes of starting the processing of the job queue, I'd like to o update the status of all jobs that failed so far to 'inactive', in order to restart them.
The only related question I could find on stackoverflow was this, however, it deals with one job at a time, after it fires a certain event as it is being processed. My concern is different, as I am interested in retrieving all jobs in the database with a certain status.
The answer to this question mentions the function .complete of the kue library, which retrieves all the completed jobs in the database. Are there similar functions for other possible job statuses?
I found a solution by browsing the kue source code. The following code achieves what I need:
var redis = require ('redis'),
kue = require ('kue'),
redisClient = redis.createClient(6379, "127.0.0.1");
kue.redis.createClient = function () {
return redisClient;
};
kue.app.listen(3000);
kue.Job.rangeByType ('job', 'failed', 0, 10, 'asc', function (err, selectedJobs) {
selectedJobs.forEach(function (job) {
job.state('inactive').save();
});
});
For reference, here is the relevant kue source code:
/queue/job.js:123:
/**
* Get jobs of `type` and `state`, with the range `from`..`to`
* and invoke callback `fn(err, ids)`.
*
* #param {String} type
* #param {String} state
* #param {Number} from
* #param {Number} to
* #param {String} order
* #param {Function} fn
* #api public
*/
exports.rangeByType = function(type, state, from, to, order, fn){
redis.client().zrange('q:jobs:' + type + ':' + state, from, to, get(fn, order));
};
Kue source code indicating that:
type is the job type
from, to is the job ranges by index (for example, you can specify load jobs from index 0 to 10, 11 jobs in total.)
order specifies the order of fetched jobs. Default is asc. You can also sort it by desc
The following works, uses the pre-existing queue object and hence, no double Redis connection issue as mentioned by Japrescott in the comments of the accepted answer.
queue.cardByType("notifications", "complete", function( err, count ) {
console.log(count);
});
Feel free to replace with a valid state, the following is a list of valid states.
inactive
complete
active
failed
delayed