How can I setup cron dynamically in config.xml (custom module) in Magento 2?
Magento2 has a different scheme to merge layout config so you have to create a new file that called crontab.xml under your_custom_module/etc folder. And then you can add your cron config like this one:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
<group id="default">
<job name="custom_cronjob" instance="YourVenDoerName\CustomModule\Cron\Test" method="execute">
<schedule>* * * * *</schedule>
</job>
</group>
</config>
I will try to make a proposition, not sure if it completely answers your question tho.
So config.xml is setting a default value for your configuration field set in system.xml
So you can have another cron job that runs every minute (* * * * *) and dynamically change this value set in system.xml. Something like this:
public function __construct(
\Magento\Framework\App\Config\ConfigResource\ConfigInterface $resourceConfig)
{
$this->resourceConfig = $resourceConfig;
}
public function execute()
{
$newvalue = $dynamicvalue;
$this->resourceConfig->saveConfig(
'section/group/field',
$newvalue,
\Magento\Framework\App\Config\ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
\Magento\Store\Model\Store::DEFAULT_STORE_ID
);
}
So basically two cron jobs.
One that actually does the job you want and one that tweaks it schedule.
Also you can tweak the schedule of it dynamically in an observer, plugin or some other class depending on your needs using the code above.
Related
Basically the title itself kinda explains what i'm trying to achieve but in greater detail:
Let's say the one has similar to the following XML setup for the layout:
layout="<log level='${level:lowerCase=True}' time='${longdate:universalTime=true}' myCustomProperty1='${event-properties:item=myCustomProperty1}' myCustomProperty2='${event-properties:item=myCustomProperty2}'>${newline}
...."
Now when myCustomProperty1 is set to let's say 'blah1' but myCustomProperty2 is not added to eventInfo.Properties collection the resulting entry looks like following:
<log level='blah' time='blah' myCustomProperty1='blah1' myCustomProperty2=''>
...
The question is - what can be done (preferably in the config file) to exclude the myCustomProperty2 attribute from finally rendered result so the output looks as following:
<log level='blah' time='blah' myCustomProperty1='blah1'>
...
Here is the gotcha - the same logger is used by multiple threads so i can't simply alter target's layout configuration at the runtime since it may negatively affect the rest of the threads
Thank you in advance for your suggestions.
-K
You could try using When :
<variables>
<variable name="var_myCustomProperty1" value="${when:when=length('${event-properties:item=myCustomProperty1}')>0:Inner= myCustomProperty1="${event-properties:item=myCustomProperty1}"}"/>
<variable name="var_myCustomProperty2" value="${when:when=length('${event-properties:item=myCustomProperty2}')>0:Inner= myCustomProperty2="${event-properties:item=myCustomProperty2}"}"/>
</variables>
<targets>
<target name="test" type="Console" layout="<log level='${level:lowerCase=True}' time='${longdate:universalTime=true}'${var_myCustomProperty1}${var_myCustomProperty2} />" />
</targets>
NLog 4.6 will include the XmlLayout, that might make things easier:
https://github.com/NLog/NLog/pull/2670
Alternative you can use the JsonLayout, if xml-output is not a requirement (renderEmptyObject="false")
I would like to enhance my current file inbound channel adapter that will scan the directory to refresh the file listing in the queue for each poll.
Below are the XML config for my current file inbound channel adapter :
<int-file:inbound-channel-adapter id="hostFilesOut" channel="hostFileOutChannel"
directory="${hostfile.dir.out}" prevent-duplicates="false"
filename-regex="${hostfile.out.filename-regex}" >
<int:poller id="poller" cron="${poller.cron:0,4,8,12,16,20,24,28,32,36,40,44,48,52,56 * * * * * }"
max-messages-per-poll="1" />
</int-file:inbound-channel-adapter>
I have try to create a custom scanner to read file. However, using the scanner to a file inbound channel adapter will cause the cron configuration not working.
Can someone give an advice on this or is there any other way can also achieve the same goal.
Thank you.
The FileReadingMessageSource has already such an option:
/**
* Optional. Set this flag if you want to make sure the internal queue is
* refreshed with the latest content of the input directory on each poll.
* <p>
* By default this implementation will empty its queue before looking at the
* directory again. In cases where order is relevant it is important to
* consider the effects of setting this flag. The internal
* {#link java.util.concurrent.BlockingQueue} that this class is keeping
* will more likely be out of sync with the file system if this flag is set
* to <code>false</code>, but it will change more often (causing expensive
* reordering) if it is set to <code>true</code>.
*
* #param scanEachPoll
* whether or not the component should re-scan (as opposed to not
* rescanning until the entire backlog has been delivered)
*/
public void setScanEachPoll(boolean scanEachPoll) {
However I'm surprised that we don't have that option exposed for the XML configuration although that option is there since day first https://jira.spring.io/browse/INT-583.
Here is a Doc on the matter.
As a workaround you can create FileReadingMessageSource bean and use it as a ref in the <int:inbound-channel-adapter>. Another way to proceed is Annotations or Java DSL configuration. You can find some sample in the Doc mentioned above.
For the XML support, please, raise a JIRA and we will add such a XSD definition. Also don't hesitate providing contribution on the matter!
I have a beanshell script and I would like it to automate.
I need to create cronjob and add my beanshell code to it.
Maybe someone do that think?
Is anyone know how to do this?
or how to match my script with cronjob?
The answer is actually given in Cronjob scripting documentation.
In a nutshell, you will use dynamic scripting to create the cronjob instead of using the slow old-fashioned way.
Concept
There are three new objects used (quoted from doc):
Script - the item type where the script content is stored (a separate deployment table)
ScriptingJob - a new ServicelayerJob item, which contains additionally the scriptURI (consequently, the stored script can be
found at runtime from different locations (classpath, db, etc..)
ScriptingJobPerformable - the spring bean assigned to every ScriptingJob instance; it implements the usual perform() method (like
for any other cronjob). This is where the "scripted" cronjob logic is
executed
How to use Cronjob scripting
First step - save your Script instance in the database. For this example I've used a code from http://www.beanshell.org/manual/quickstart.html
Note: you can create script with Groovy, BeanShell ad JavaScript
INSERT_UPDATE Script; code[unique=true];content;scriptType(code)
;myBshScript;"foo = ""Foo"";
four = (2 + 2)*2/2;
print( foo + "" = "" + four ); // print() is a BeanShell command
// Do a loop
for (i=0; i<5; i++)
print(i);
// Pop up a frame with a button in it
button = new JButton( ""My Button"" );
frame = new JFrame( ""My Frame"" );
frame.getContentPane().add( button, ""Center"" );
frame.pack();
frame.setVisible(true);";BEANSHELL
Don't forget to escape " in the script with an other " (Impex restriction).
Second step - create a ScriptingJob that use the previously created Script
INSERT_UPDATE ScriptingJob; code[unique=true];scriptURI
;myBshDynamicJob;model://myBshScript
model://myBshScript is used to retrieve a Script stored in the DB
Third step - create the CronJob
INSERT_UPDATE CronJob; code[unique=true];job(code);singleExecutable;sessionLanguage(isocode)
;myBshDynamicCronJob;myBshDynamicJob;true;en
Optional step - create a trigger for the CronJob
INSERT_UPDATE Trigger;cronjob(code)[unique=true];cronExpression
;myBshDynamicCronJob;0 0 0/1 1/1 * ? *
This executes the cronjob every hour.
Execute the CronJob by script
In the hac scripting tab, choose Groovy and run this in commit mode.
def dynamicCJ = cronJobService.getCronJob("myBshDynamicCronJob")
cronJobService.performCronJob(dynamicCJ,true)
After running the Script you should have this displayed
And in the console
INFO [hybrisHTTP27] (myBshDynamicCronJob) [ScriptingJobPerformable] Foo = 4
0
1
2
3
4
In Hybris, go to HMC> System> CronJobs> Search your created cronjob or create a new cronjob> Time Schedule tab> Trigger> Create Trigger.
From this Trigger tab window, you can schedule the interval eg. daily, weekly, etc. Also you can set the start time and frequency.
You can also do this trigger setting via impex as below:
INSERT_UPDATE Trigger;cronJob(code)[unique=true];second;minute;hour;day;month;year;relative;active;maxAcceptableDelay
;CartRemovalJob;0;5;4;-1;-1;-1;false;true;-1
For more detailed information, have a look at this, in case you have access to Hybris Wiki.
If you have access to hybris wiki, here you can find how to create and execute a cronjob.
In order to execute bean shell, in the cronjob "perform" method you should do this:
SimpleScriptContent content = new SimpleScriptContent("beanshell", "here your beanshell script code as string");
ScriptExecutable script = scriptingLanguagesService.getExecutableByContent(content);
ScriptExecutionResult result = script.execute();
...
Here the import section:
import de.hybris.platform.scripting.engine.content.impl.SimpleScriptContent;
import de.hybris.platform.scripting.engine.ScriptExecutionResult;
import de.hybris.platform.scripting.engine.ScriptExecutable;
You should access to scriptingLanguagesService with annotation:
#Autowired
ScriptingLanguagesService scriptingLanguagesService;
I have tried below steps for the groovy script. You can try the same for the beanshell.
You have to create an instance of
Script - the item type where the script content is going to store.
ScriptingJob - a new ServicelayerJob item, which contains additionally the scriptURI
CronJob - This is where the "scripted" cronjob logic is executed
1. Create a Script
Script code: HelloScript
Script engine type: beanshell
Content: log.info("Hello");
2. Create the Scripting Job
Again from HMC/Backoffice, find ScriptinJobs and create the new instance of it. Here you have to define Code and ScriptURI like
Code: HelloScriptJob
ScriptURI: model://HelloScript
You can access this job in the next step to create the CronJob
3. Create a CronJob
From HMC/BackOffice, create an instance of cronJob. Select above-created job(HelloScriptJob) in
Job definition drops down and save the changes. Now you good to schedule/run this cronJob.
Refer detailed post cronjob-using-groovy-script-hybris
Would like to add files to a Drupal6 user's account based upon certain conditions (basically just upon new account creation). I want to use the Rules module to accomplish this but the conditional items don't seem to cover this action. Probably if you select the "Execute Custom PHP code" it is possible, but this out of my programming league. Any ideas welcome.
mmmm ok maybe u will find creating a new module is something difficult but its very easy..lets do it
1- go to /sites/all/modules
2- create new folder called when_user_login (lets called our new module when_user_login)
3- create inside this folder when_user_login.info include the following code
name = when user login
description = this module do something when user login
core = 6.x
4- now lets create a new file in the same directory called when_user_login.module include the following code
/**
* Implementation of hook_user().
* #see http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hook_user/6
* for more details
*/
function when_user_login_user($op, &$edit, &$account, $category = NULL) {
switch($op){
case 'insert' :
// now any code we will write here will be implemented when new user register
// you can access the new user information by {$account} variable
// E.g $account->uid include the id of the new account that register
break ;
}
}
good luck...hop that will help you (don't forget to enable the module)
I have a custom content (using cck) namely thewittyshit and it has a field namely field_thewittyshit . I want to theme field_thewittyshit field for all the views. I wrote the following code and saved it in a new file namely views-view-field--default--field-thewittyshit-value.tpl.php . But still no change is reflected in any of my views or node display.
<?php
// $Id: views-view-field.tpl.php,v 1.1 2008/05/16 22:22:32 merlinofchaos Exp $
/**
* This template is used to print a single field in a view. It is not
* actually used in default Views, as this is registered as a theme
* function which has better performance. For single overrides, the
* template is perfectly okay.
*
* Variables available:
* - $view: The view object
* - $field: The field handler object that can process the input
* - $row: The raw SQL result that can be used
* - $output: The processed output that will normally be used.
*
* When fetching output from the $row, this construct should be used:
* $data = $row->{$field->field_alias}
*
* The above will guarantee that you'll always get the correct data,
* regardless of any changes in the aliasing that might happen if
* the view is modified.
*/
?>
<em>
<?php print $output; ?>
<em/>
I want to format the text. In this code i am just making it appear in italics.
The template you are overriding must reside in your theme directory. Find the views-view-field.tpl.php file in the views module folder and copy and paste it into your theme directory where your views-view-field--default--field-thewittyshit-value.tpl.php resides. This should let you then use this file. Also make sure to clear the cache after you do this.
For debugging purposes, if you are still having troubles, make sure views is using views-view-field--default--field-thewittyshit-value.tpl.php. Click on "information" next to the theme option in the views UI under the "Basic settings" section. The theme that you are using will be in bold.