OpenLiberty / ci.maven

Maven plugins for managing Liberty profile servers #devops
Apache License 2.0
130 stars 91 forks source link

Deploy goal doesn't allow for user-specified <springBootApplication> config in server.xml; will always generate deployment config #1789

Open scottkurz opened 9 months ago

scottkurz commented 9 months ago

For a deployment of a SpringBoot packaged app, with liberty-maven-plugin config:

        <plugin>
           <groupId>io.openliberty.tools</groupId>
       <artifactId>liberty-maven-plugin</artifactId>
       <version>3.10</version>
           <configuration>
              <deployPackages>spring-boot-project</deployPackages>
           </configuration>

I can't specify server.xml config like:

     <springBootApplication location="my-0.0.1-SNAPSHOT.war" autoStart="false">
         <applicationArgument>--my.arg=123</applicationArgument>
    </springBootApplication>

The deploy will, by default, just go into dropins/spring unlike the deployment of regular (non-SB) WAR/EAR packages, in which the default path is calculated based on whether there is any app deployment configuration detected in server.xml config.

If I explicitly configure liberty-maven-plugin to use the 'apps' directory for deploy:

                       <appsDirectory>apps</appsDirectory>

it will always generate a config dropin. It will likewise not look for a springBootApplication at a matching location.

Though we have tests for each type of generated config, I don't think we test with explicitly-provided config in server.xml.

CONSEQUENCE

Depending on the values specified, this could surface with messages like:

[WARNING] CWWKM2179W: ...

OR

[INFO] [ERROR ] CWWKZ0013E: It is not possible to start two applications called ...

More directly, the config the user intends to set from the <springBootApplication> element https://openliberty.io/docs/latest/reference/config/springBootApplication.html won't take effect.

WORKAROUND

  1. Use this LMP config:

                <configuration>
                    <appsDirectory>apps</appsDirectory>
                    <deployPackages>spring-boot-project</deployPackages>
                </configuration>
  2. Do a mvn package liberty:create liberty:deploy just to generate the deployment configDropin.

  3. Take the generated config dropin and look at the contents, e.g. cat configDropins/defaults/install_apps_configuration_1491924271.xml to see something like:

<server>
    <springBootApplication id="spring-web-ee" location="thin-spring-web-ee-0.0.1-SNAPSHOT.war" name="spring-web-ee"/>
</server>
  1. Copy this element into server.xml and expand to add an end tag as well:
    <springBootApplication id="spring-web-ee" location="thin-spring-web-ee-0.0.1-SNAPSHOT.war" name="spring-web-ee">
   <!-- Now you can add the app args here -->
   </springBootApplication>

By matching the generated id, location and name in the explicit config in server.xml, we can cleanly merge over the config dropin-generated app config, and use what's specified in server.xml

PROPOSAL

It seems the most obvious thing is to follow the same pattern used for WAR/EAR deployment, as mentioned previously.

A couple other notes:

  1. we should consider honoring the liberty-maven-plugin <stripVersion>true</stripVersion> config.
  2. Some other context in this area to consider is the disucssion at: https://github.com/OpenLiberty/ci.maven/issues/1780
scottkurz commented 9 months ago

This issue to me suggests an idea I've considered now and again, which is to give 'deploy' its own special skipDeploy parm.

Besides perhaps working around this issue... it might be more generally useful dealing with SpringBoot since we have both the original WAR and SB plugin-repackaged WAR.

In the meantime we can always configure our own skip in the dev/run goals with:

              <execution>
                  <id>deploy-skip</id>
                       <phase>none</phase>
                        <goals>
                            <goal>deploy</goal>
                        </goals>
                        <configuration>
                            <skip>true</skip>
                        </configuration>
                    </execution>
cherylking commented 3 days ago

Summary of discussion at meeting held on 11/07/24 for this issue:

  1. ci.common - We need to parse the config files for springBootApplication elements similar to how we look for application, webApplication and enterpriseApplication today in ServerConfigDocument class in ci.common.
  2. ci.common - If more than one springBootApplication element is found, we should throw an error since the Liberty runtime will fail in this instance.
  3. ci.common - If a springBootApplication element is found, save the location value in a separate field and provide a getter method for it since we will need it in both LMP and LGP to deploy the application properly.
  4. In LMP/LGP, do not generate config in configDropins for the springBootApplication if a springBootApplication element with a location attribute was found in ci.common.
  5. In LMP/LGP, when copying over the thinned application to either the apps or dropins/spring folder, use the value from the location attribute for the file name in the destination.

@scottkurz @tjwatson Please correct me if I got any of that wrong.

tjwatson commented 3 days ago

In LMP/LGP, when copying over the thinned application to either the apps or dropins/spring folder, use the value from the location attribute for the file name in the destination.

When there is a <springBootApplication/> configuration found it would be an error to copy the thinned app to dropins/spring folder. I suspect that should be flagged as an error if the <appsDirectory>apps</appsDirectory> plugin configuration is not being used.

cherylking commented 3 days ago

This is from our documentation:

The server's apps or dropins directory where the application files should be copied. The default value is set to apps if the application is defined in the server configuration, otherwise it is set to dropins.

So we automatically set it to apps when we find the application configured in the server configuration. Need to make sure we do the same for springBootApplication. We don't currently.

scottkurz commented 3 days ago

On a related note we also flag it as an error if you configure LMP to use "dropins" but have app config in server.xml (search for:

       throw new MojoExecutionException(messages.getString("error.install.app.dropins.directory"));

so we should do similar things.