/
Adding licensing support to server apps

Adding licensing support to server apps

1. Make your app licensable:

Your app hasn’t conveyed to the product that it should have a license, let alone provided an ability to accept licenses. Here, we’ll add a dependency in your pom.xml file to both the UPM API and the licensing API. Then, you’ll declare your app as licensable in your descriptor file.


Step 1: Add the following dependencies to the dependencies element inside pom.xml.

<dependency>
    <groupId>com.atlassian.upm</groupId>
    <artifactId>licensing-api</artifactId>
    <version>2.21.4</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.atlassian.upm</groupId>
    <artifactId>upm-api</artifactId>
    <version>2.21</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>

Step 2: Add the following parameter to the plugin-info element in /src/main/resources/atlassian-plugin.xml.

   <param name="atlassian-licensing-enabled">true</param>

Step 3: Run atlas-mvn package in the project home directory to repackage the app. QuickReload will then reload the app.

Step 4: Refresh the UPM page. Verify you see two big changes: a License details field, and a License keyinput box.

2. Use PluginLicanseManager to access licensing information:

You can use PluginLicenseManager to access licensing information within your plugin. In the following, we create a servlet that replies with the currently registered license (if there is one).

Step 1: In atlassian-plugin.xml, add the following servlet declaration.

<servlet name="License Servlet" class="com.atlassian.tutorial.LicenseServlet" key="license-servlet">
    <description>Servlet which serves the raw license string</description>
    <url-pattern>/my/license</url-pattern>
</servlet> 

Step 2: Create package com.empyra.projectName.LicenseServlet and put the following code in it.



LicenseServlet.java


package com.empyra.projeactName.LicenseServlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.atlassian.upm.api.license.PluginLicenseManager;

@Scanned
public class LicenseServlet extends HttpServlet {

    @ComponentImport
    private final PluginLicenseManager pluginLicenseManager;

    @Inject
    public LicenseServlet(PluginLicenseManager pluginLicenseManager) {
        this.pluginLicenseManager = pluginLicenseManager;
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter w = resp.getWriter();
        if (pluginLicenseManager.getLicense().isDefined()) {
            w.println(pluginLicenseManager.getLicense().get().getRawLicense());
        } else {
            w.println("License missing!");
        }
        w.close();
    }
}


Step 3: Add template to display license message display.



jira-license.vm

<html>
<head>
<title>License</title>
</head>
<body>

<div class="aui-message aui-message-error">
    <p class="title">
        <strong>License Expired!</strong>
    </p>
    <p>Your license has expired!. Please renew your license.</p>
</div>

</body>
</html>

Step 4: Add condition for every vm pag in your project inside <body> section.

PageName.vm

<html>

<head>

<Title>Page Title</Title>

</head>

<body>
    #if($!bpiLicenseStatus=="UL")
        <div class="aui-message aui-message-warning">
            <p class="title">
                <strong>Please enter a valid license!</strong>
           </p>
           <p>Please get your license.</p>
        </div>
    #end

</body>

</html>


Step 5: Add license condition in every webaction files.

pagenameWebworkAction.java


package com.empyra.bpi.webwork;

public class BulkProfileImporterViewWebworkAction extends JiraWebActionSupport {

    private static final String LICENSE_EXPIRED = "LE";

    private static final String LICENCE_VALID = "LV";
    private static final String UNLICENCED = "UL";
    private String bpiLicenseStatus;

    @ComponentImport

    private final PluginLicenseManager pluginLicenseManager;

    @Inject
    public BulkProfileImporterViewWebworkAction(PluginLicenseManager pluginLicenseManager) {
        this.pluginLicenseManager = pluginLicenseManager;
    }


    @Override
    public String execute() throws Exception {
        // license check
        String licenceStatus = checkLicence();
        this.bpiLicenseStatus = licenceStatus;
        if (licenceStatus.equalsIgnoreCase(LICENSE_EXPIRED)) {
           return "bud-jira-license";
        } else {
            return "bulk-profile-importer-view";
        }

    }

    private String checkLicence() {

        if (pluginLicenseManager.getLicense().isDefined()) {
            PluginLicense license = pluginLicenseManager.getLicense().get();
            if (license.getError().isDefined()) {
                return LICENSE_EXPIRED;
            } else {
                return LICENCE_VALID;
            }
        } else {
            return UNLICENCED;
        }

    }

}

Step 6: Add License attempt count: 

repository.java


String pluginKey = "";try
{
    if (pluginLicenseManager.getLicense().isDefined()) {
        PluginLicense license = pluginLicenseManager.getLicense().get();
        if (license.getError().isDefined()) {
            logger.info("license status: " + pluginLicenseManager.getLicense().toString());
        } else {
            try {
                 logger.info("license status: " + pluginLicenseManager.getLicense().toString());
                 Iterable<PluginLicense> pLicense = pluginLicenseManager.getLicense();
                 for (PluginLicense pluginLicense : pLicense) {
                     LicenseType licenseType = pluginLicense.getLicenseType();
                     String licenseTypeName = licenseType.name();
                     pluginKey = pluginLicense.getPluginKey();
                     validateLicense(pluginLicense, licenseTypeName);
                 }
            } catch (Exception ex) {
                 logger.log(Level.WARNING, "While creating users", ex);
        }
    }
 } else {
    logger.info("UNLICENCED: " + pluginLicenseManager.getLicense().toString());
}

}catch(
Exception e)
{
logger.log(Level.WARNING, "While creating users", e);
}

private void validateLicense(PluginLicense pluginLicense, String licenseTypeName) {
// TODO Auto-generated method stub
logger.info("Plugin licenseTypeName: " + licenseTypeName);

(FYI: Dipesh Chouksey (Unlicensed))

Note: Adding commercial license support in Jira server plugin development
if (COMMERCIAL.equals(licenseTypeName) || DEVELOPER.equals(licenseTypeName)) {
DateTime purchasDate = pluginLicense.getPurchaseDate();
Option<DateTime> maintenanceDates = pluginLicense.getMaintenanceExpiryDate();
long diff = maintenanceDates.get().toDate().getTime() - purchasDate.toDate().getTime();
long date = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
// jiraUser.setCalDate(date);
if (date >= 32) {
isFullVersion = true;
logger.info("Plugin is full vesrion.");
} else {
isFullVersion = false;
isAttempt = true;
logger.info("Plugin is trial vesrion");
}
}

}

private List<JiraUser> validateAttempt(List<JiraUser> jiraUsers, String pluginKey,
List<JiraUser> validatedJiraUsers, UserCreateResult userCreateResult) throws EmpyraWSException {
UserPropertyRepository jiraUserRepository = new UserPropertyRepository(pluginLicenseManager, activeObjects );
List<BpiLicense> bpiLicense = jiraUserRepository.getAttempt(pluginKey);

if (bpiLicense != null && !bpiLicense.isEmpty()) {
if (bpiLicense.get(ZERO_INDEX).getAttempt() < MAX_ATTEMPT) {
if (jiraUsers.size() >= MAX_RECORD || jiraUsers.size() <= MAX_RECORD) {
if (jiraUsers.size() < MAX_RECORD) {
validatedJiraUsers = jiraUsers.subList(ZERO_INDEX, jiraUsers.size());
} else {
validatedJiraUsers = jiraUsers.subList(ZERO_INDEX, MAX_RECORD);
}
} else {
validatedJiraUsers.addAll(jiraUsers);
}
} else {
attemptOver = true;
if (jiraUsers.size() < MAX_RECORD) {
validatedJiraUsers = jiraUsers.subList(ZERO_INDEX, jiraUsers.size());
} else {
validatedJiraUsers = jiraUsers.subList(ZERO_INDEX, MAX_RECORD);
}
logger.info("Your 3 free trials are complete. Please use the licensed version.");
userCreateResult.setErrorMsg("Your 3 free trials are complete. Please use the licensed version.");
}
//update
jiraUserRepository.updateAttempt(bpiLicense.get(ZERO_INDEX).getID());
logger.info("Updated total attemps in db");
} else {
// save
jiraUserRepository.saveAttempt(pluginKey);
if (jiraUsers.size() < MAX_RECORD) {
validatedJiraUsers = jiraUsers.subList(ZERO_INDEX, jiraUsers.size());
} else {
validatedJiraUsers = jiraUsers.subList(ZERO_INDEX, MAX_RECORD);
}
}
return validatedJiraUsers;
}

Step 7: 

Add webaction
in plugin.xml for
every page
in your project.

<action name="com.empyra.bpi.webwork.pagenameWebworkAction"  alias=pagenameWebworkAction" roles-required="admin">  <view name="PageNamer-upload">/templates/PageName.vm</view>
    <view name="bud-jira-license">/templates/bpi-license-module/bpi-jira-license.vm</view>
</action>

AStep 7:
Add Table
in Database:

// Save Attempt
public void saveAttempt(final String strBpiPluginKey) throws EmpyraWSException {
try {
activeObjects.executeInTransaction(new TransactionCallback<BpiLicense>() {
@Override
public BpiLicense doInTransaction() {
final BpiLicense bpiLicense = activeObjects.create(BpiLicense.class);
bpiLicense.setBpiPluginKey(strBpiPluginKey);
bpiLicense.setAttempt(1);
bpiLicense.save();
return null;
}
});
} catch (Exception ex) {
ex.printStackTrace();
logger.log(Level.WARNING, "Exception occurred while saving LicenseActivity from DB.", ex);
throw new EmpyraWSException("E501", "Exception occurred while saving LicenseActivity from DB.", ex);
}
}

// Get Attempt
public List<BpiLicense> getAttempt(final String strBpiPluginKey) throws EmpyraWSException {
try {
return activeObjects.executeInTransaction(new TransactionCallback<List<BpiLicense>>() {

@Override
public List<BpiLicense> doInTransaction() {
return Lists.newArrayList(activeObjects.find(BpiLicense.class,
Query.select().where("BPI_PLUGIN_KEY = ?", strBpiPluginKey)));
}
});
} catch (Exception ex) {
ex.printStackTrace();
logger.log(Level.WARNING, "Exception occurred while saving LicenseActivity entity in DB.", ex);
throw new EmpyraWSException("E501", "Exception occurred while saving LicenseActivity entity in DB.", ex);
}
}

// Update Attempt
public boolean updateAttempt(final int id) throws EmpyraWSException {
try {
activeObjects.executeInTransaction(new TransactionCallback<BpiLicense>() {
@Override
public BpiLicense doInTransaction() {
final BpiLicense budLicense = activeObjects.get(BpiLicense.class, id);
budLicense.setAttempt(budLicense.getAttempt() + 1);
budLicense.save();
return null;
}
});

return true;
} catch (Exception ex) {
logger.log(Level.WARNING, "Exception occurred while saving LicenseActivity from DB.", ex);
throw new EmpyraWSException("E501", "Exception occurred while saving LicenseActivity entity in DB.", ex);
}
}


Output:


While user using 30 days trail it should show "License Expire soon!" message in every page from plugin pages.


while updating trail version it should show this message.




After license expired.



Rreference:

  1. Adding licensing support to server apps.
  2. Server app licensing validation rules.
  3. License type name list for JIRA server plugins