Migration of DPU Configurations

In this tutorial we present a use case of migration configuration in one of the Core DPUs.Let us assume that we have two configurations, old and new.

Our goal is to use the new configuration in our DPU in case the old version is given to the DPU. It should be automatically converted to the new version.

Our old configuration class comes from DPU calledHttpDownload.

Note

To keep things simple we omit setters and getters. Each field in the configuration must be private with appropriate public getter and setter.

package eu.unifiedviews.plugins.extractor.httpdownload;
import java.net.URL;
import eu.unifiedviews.dpu.config.DPUConfigException;
import eu.unifiedviews.helpers.dpu.config.VersionedConfig;
import eu.unifiedviews.plugins.extractor.filesdownload.FilesDownloadConfig_V1;
import eu.unifiedviews.plugins.extractor.filesdownload.VfsFile;
public class HttpDownloadConfig_V1 implements VersionedConfig<FilesDownloadConfig_V1> {
    private URL URL = null;
    private String target = "/file";
    private int retryCount = -1;
    private int retryDelay = 1000;
}

The configuration we want to use:

package eu.unifiedviews.plugins.extractor.filesdownload;
import java.util.LinkedList;
import java.util.List;
public class FilesDownloadConfig_V1 {
    private List<VfsFile> vfsFiles = new LinkedList<>();
    private boolean softFail = false;
}

TheVfsFileclass then:

package eu.unifiedviews.plugins.extractor.filesdownload;
public class VfsFile {
    private String uri = "http://www.zmluvy.gov.sk/data/att/117597_dokument.pdf";
    private String username = "";
    private String password = "";
    private String fileName = "";
    public VfsFile() {
    }
}

As you can see the configuration has changed significantly. The old configurationHttpDownloadConfig_V1 in Code 1 supports only a single file, the new configurationFilesDownloadConfig_V1 in Code 2 supports multiple files.

The old configuration uses an absolute path to the file, the new uses URI (starts with file:// ). Additionally, we changed the package name.

Now we need to do two things:

  1. Create a migration function from old configuration to new one in the old configuration class.

  2. Make the new DPU support the new configuration.

Step 1: Migration function.

This function is defined in theeu.unifiedviews.helpers.dpu.config.VersionedConfiginterface. The interface’s parameter is the configuration we want to update to.

First we update class of the configuration we would like to update so that it looks as follows:

public class HttpDownloadConfig_V1 implements VersionedConfig<FilesDownloadConfig_V1> {

This means, that theHttpDownloadConfig_v1can be converted intoFilesDownladConfig_V1. Now we need to implement the conversion function, which we do by adding the conversion method to HttpDownloadConfig_v1 class as follows:

@Override    public FilesDownloadConfig_V1 toNextVersion() throws DPUConfigException {
        final FilesDownloadConfig_V1 config = new FilesDownloadConfig_V1();
        final VfsFile vfsFile = new VfsFile();
        if (URL != null) {
            vfsFile.setUri(URL.toString());
        } else {
            vfsFile.setUri("");
        }
        vfsFile.setFileName(target);
        config.getVfsFiles().add(vfsFile);
        return config;
    }

This function returns the new configuration that is created from the old version. The code in this function depends on the way how you want to migrate your configuration. But the idea is simple, from current configuration the new one is constructed.

Further, lets update the configuration which is used by the DPU. In order to do this just change the generic parameter of AbstractDialog and AbstractDPU and fix whatever got broken.

So your DPU declaration should now looks like this:

public class FilesDownload extends AbstractDpu<FilesDownloadConfig_V1> {

Step 2: Update the DPU itself.

We need to update the DPU’s constructor - call of super constructor. Before we introduced the new configuration version, the constructor looks as follows, so it tells DPU that there is no history in configuration:

super(MyDpuVaadinDialog.class, ConfigHistory.noHistory(FilesDownloadConfig_V1.class));

Let’s change the above line and use ConfigHistory.history()instead as depicted bellow:

super(MyDpuVaadinDialog.class, 
      ConfigHistory.history(HttpDownloadConfig_V1.class)
                   .addCurrent(FilesDownloadConfig_V1.class));

The ConfigHistory.historyannounces that there is more than one version of configuration. You can chain the calls to list multiple different versions; at the end, you set current configuration by callingaddCurrentmethod.

Now the DPU is using theFilesDownloadConfig_V1. If you import the DPU with the new configuration to tge UnifiedViews instance where older version of configuration (HttpDownloadConfig_V1) is presented in the database, the older version is automatically updated by the helpers before it is given to the DPU.

Additional Considerations

The configuration is updated on the fly as required. If you just upload the DPU with new configuration to UniviedViews instance, no upfront migration happens. If you open a dialog or execute the DPU with new configuration, then the old configuration is loaded from database, transformed to the new one and used. So far there was no update of the configuration in the database. The only way how to update configuration in database is to open the configuration dialog and save changes - only then new version of configuration is written into database.This approach have some advantages and disadvantages.

Disadvantages:

  • You may have a very old configuration in your database.

  • Overhead of converting configuration on the fly until the user opens and saves the configuration of the DPU.

  • Possible multiple versions of configuration of different DPU instances of the same DPU template in the database.

Advantages:

The chosen approach is non-invasive:

  • If something goes wrong, don’t worry just don’t save anything in UnifiedViews and the new configuration is not saved to the database.

  • This made also configuration migration testing easier, as you can keep replacing and updating your DPU till you are satisfied and only then click Save and write the new version of configuration into the database.

  • You do not destroy the old functional configuration once you upload the new DPU.