Message Boards

Can't trigger some methods on Hot Deploy

Olga S, modified 6 Years ago.

Can't trigger some methods on Hot Deploy

Junior Member Posts: 26 Join Date: 4/17/17 Recent Posts
Hello!
I am writing module which supposed to run on hot deploy and create custom workflow from xml file. My component looks like this now:



@Component(
		immediate = true,
		property = {},
		service = BaseHotDeployListener.class
	)
public class MyClass extends BaseHotDeployListener {
	private final static Log LOGGER  = LogFactoryUtil.getLog(MyClass .class);
	private static final String JOURNAL_ARTICLE = "com.liferay.portlet.journal.model.JournalArticle";


	@Override
	public void invokeDeploy(HotDeployEvent event) throws HotDeployException {
		String servletContextName = event.getServletContextName();
		if (servletContextName.startsWith("workflow-definition-uploader")) {
			try {
				//******** DO SOMETHING
			} catch (Exception e) {
				LOGGER.error(e.getMessage(), e);
			}
		}

	}


However, when I deploy the module it is not triggered on deploy. Could anyone point what am I doing wrong?
Maybe I miss some properties? There is very scarce documentation on deploy, especially hot deploy, in Liferay 7.

Thanks!
thumbnail
David H Nebinger, modified 6 Years ago.

RE: Can't trigger some methods on Hot Deploy

Liferay Legend Posts: 14914 Join Date: 9/2/06 Recent Posts
I wouldn't necessarily want to bind to deploy.

Instead I would just bind as a portal lifecycle listener. When triggered, I would see if my workflow was loaded and, if not, load it.

A good example would be https://github.com/liferay/liferay-portal/blob/master/modules/apps/foundation/portal-scheduler/portal-scheduler-quartz/src/main/java/com/liferay/portal/scheduler/quartz/internal/SchedulerLifecycleInitializer.java. It handles the registration of the lifecycle listener.

Then the https://github.com/liferay/liferay-portal/blob/master/portal-kernel/src/com/liferay/portal/kernel/scheduler/SchedulerLifecycle.java does it's work in the doPortalInit() method.

Think of this as a new form of the global startup action handler.

Another easier solution would be to just use @Activate and build your logic in there if you use the "immediate=true" property. When OSGi loads your component, it will be started and the activate method would get invoked. There you can query to see if your workflow was already loaded and then take care of it.

In either case, your code gets executed at every start, every deploy, so you need to have the check in place if it is loaded or not.

Another option is to incorporate the Liferay upgrade facilities. This is based upon your module deployment. By providing upgrade steps, whenever your module is loaded the version in the Release table is compared with the bundle version - if it is the same, no action. If it is different, the registered upgrade steps are invoked to upgrade to the bundle version.

This last option is probably your best bet as it removes the need to check for the initial deployment, plus it also helps you incorporate auto-processing of upgrades to the workflow by bumping your upgrade version and providing the necessary upgrade steps.

But don't bind to the hot deploy process, that is so old school...







Come meet me at the 2017 LSNA!
Olga S, modified 6 Years ago.

RE: Can't trigger some methods on Hot Deploy

Junior Member Posts: 26 Join Date: 4/17/17 Recent Posts
Regarding the second option (which is based upon module deployment)
Is there any example of using Liferay upgrade facilities?
Do I need to implement UpgradeStepRegistrator and override register() method?

Thanks,
Olga
thumbnail
David H Nebinger, modified 6 Years ago.

RE: Can't trigger some methods on Hot Deploy

Liferay Legend Posts: 14914 Join Date: 9/2/06 Recent Posts
You'll find all kinds of doco on implementing upgrades here: https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/creating-an-upgrade-process-for-your-app

I also have a blog post about the upgrade implementations: https://web.liferay.com/web/user.26526/blog/-/blogs/building-in-upgrade-support, also https://web.liferay.com/web/user.26526/blog/-/blogs/servicebuilder-and-upgrade-processes which specifically covers what happens during the first time SB module deployment.








Come meet me at the 2017 LSNA!
Olga S, modified 6 Years ago.

RE: Can't trigger some methods on Hot Deploy

Junior Member Posts: 26 Join Date: 4/17/17 Recent Posts
Thanks! It is working fine now with this code:
@Component( immediate = true, 
			service = UpgradeStepRegistrator.class)

public class WorkflowDefinitionUploader implements UpgradeStepRegistrator {
  
	private final static Log LOGGER  = LogFactoryUtil.getLog(WorkflowDefinitionUploader.class);

	@Activate
	protected void activate(final BundleContext bundleContext) {
	   // I am loading my custom workflow here
	}
	  
	@Override
	public void register(UpgradeStepRegistrator.Registry registry) {
		  registry.register(_bundleName, "0.0.0", "1.0.0", new DummyUpgradeStep());
	}
	  
	private String _bundleName;

I have just a couple of clarifying questions:
- Why do I need register() method since I don't have bnd.bnd file and don't update version.
- Why it loads a new workflow only if I update workflow version:
<workflow-definition xmlns="urn:liferay.com:liferay-workflow_7.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="urn:liferay.com:liferay-workflow_7.0.0 http://www.liferay.com/dtd/liferay-workflow-definition_7_0_0.xsd">
	<name>my  workflow</name>
	<description>A single approver can approve a workflow content.</description>
	<version>1</version>
	<state>
		<name>created</name></state></workflow-definition>

Sorry, if those questions are too specific, but I curious how Liferay 7 keeps track of workflow definition version.

Thanks!
thumbnail
David H Nebinger, modified 6 Years ago.

RE: Can't trigger some methods on Hot Deploy (Answer)

Liferay Legend Posts: 14914 Join Date: 9/2/06 Recent Posts
Olga S:
I have just a couple of clarifying questions:
- Why do I need register() method since I don't have bnd.bnd file and don't update version.


You must have a bnd.bnd file, it is part of building an OSGi module. Well, I guess maven can build a bundle by putting the content of the bnd into the pom, but there is still effectively the bnd.bnd content.

Why it loads a new workflow only if I update workflow version:


You want to manage your loading. Workflows are versioned - if you auto-import the workflow every day, you're going to have tens or hundreds of versions before you know it. And your assets using the workflow are bound to a specific version - you don't want to have to pick from a huge list of versions that don't have any real changes.

So you manage it carefully. Define the version in your bnd.bnd file to indicate what the current version is. You register upgrade steps to support single-step upgrades (from 1.2.0 to 1.3.0 for example) as well as the initial deployment step (0.0.0 to 1.3.0) since effectively the upgrade just involves loading the workflow xml.

This way the portal will only have different versions that reflect workflow changes, plus you are managing and supporting the upgrade in an environment that either has or did not have the workflow deployed before.








Come meet me at the 2017 LSNA!
Thomas Potter, modified 4 Years ago.

RE: Can't trigger some methods on Hot Deploy

New Member Post: 1 Join Date: 7/2/19 Recent Posts
Hi David. 

I am fairly new to Liferay. I have been looking into the upgrade process to upgrade data in the production database. Note that our team currently uses manual sql scripts to update the data. I thought I could use the upgrade process to upgrade data (not just the schema) but was concerned that since we hot deploy there would be issues with the upgrade process (possibly the cache not being updated when we use the upgrade process) and instead that I should use the MVC portlet init method.  So I have 2 questions:
1. Is it bad practice to use the upgrade facilities to add data (records) to the database?
2. Is it bad practice to use the upgrade facilities to update data in the database?
3. Does hotdeploy not mix well with using the upgrade facilities for updating/adding data to the database?

Thank you for your time. I didn't mean to hijack this convo but it seems related to my question and I couldn't figure out how to start my own thread.
thumbnail
David H Nebinger, modified 4 Years ago.

RE: Can't trigger some methods on Hot Deploy

Liferay Legend Posts: 14914 Join Date: 9/2/06 Recent Posts
1. No, feel free to add data in upgrade processes. I use upgrade processes to add new roles, categories, etc. so I can "automate" environment preparation. As long as you use the relevant service builder APIs, you don't have to worry about caches as that is a normal service builder function.

2.No, you can update data also. Using the service builder APIs will also ensure the right things happen.

3. Hot deploy is just a live version of a standard deployment. There's nothing special with it outside of the fact it occurs while the Liferay environment is still running. So I would recommend not thinking about hot deploy as some sort of option to do something. The upgrade process was designed to apply a change when processing a module upgrade. It is well tested and will do the right thing whether it is running in an environment that needs an upgrade applied or whether the environment has already been updated.

I'd really recommend doing the upgrade process for all of the environment setup and data adds/updates. It won't let you down...