Building Extensions

Tools

  • Language: Java 11 
  • Packaging: Java Jar
  • Build: maven. This guide assumes the usage of maven. You can use Gradle or others

Step 1 - Get Started

To get started:

  • Get the Control Center extension API, published as a standalone Jar
  • Get the source for one of the published extensions. Use this as a starting point
  • Import the existing source into the IDE of your choice
  • Build the project by
    • Switching to the
    • Run mvn clean package

Step 2 - Logic

Customize the Extension code to add your custom logic.

An extension is an implementation of the Control Center plugin API. You need to extend the HyprExtension class. Below is the outline of a typical extension:

public class MyExtension extends HyprExtension {

    public MyPlugin(PluginWrapper wrapper) {
        super(wrapper);
        }

    @Extension(ordinal = 1)
    public static class MyRegExtPoint extends AbstractRegistrationExtensionPoint {
        // Implement custom lifecycyle logic here
        }

    @Extension(ordinal = 2)
    public static class MyAuthExtPoint extends AbstractAuthenticationExtensionPoint {
        // Implement custom lifecycyle logic here
        }
}

Replace the existing Extension Point code with your custom logic

Step 3 - Dependencies

Customizing lib dependencies

Dependency management is done via the standard maven/gradle approach.

In general it's recommended to minimize the use of external libs to keep the plugin package small and reduce the likelihood of dependency conflicts.

If you do use external libs, they must be packaged with the Plugin jar file - commonly referred to as the fat jar.

The following dependencies are provided by the Control Center, so you do not need to package them.  

LibraryDescriptionVersion
pf4jCC plugins are based on this library. https://pf4j.org/2.6.0
HYPR cc-extension-apiArtifact containing CC ext. API3.6.0
Apache httpclienthttps://hc.apache.org/httpcomponents-client-4.5.x/
Useful for making external REST calls over Http
4.5.8

Step 4 - Manifest

Customize the manifest

Manifest.mf
Control Center extensions use the Java jar manifest.mf file to provide metadata to the Control Center.

When the Extension jar is uploaded, the Control Center will inspect the Manifest and extract the relevant information.

The manifest is automatically created by the maven build file, using the maven-compiler-plugin.

Similar results can be achieved with Gradle. 

The following is a sample:

10281028

Modify the following attributes in the pom.xml to match your needs. These will feed into the generated manifest file.

<properties>
        ...

        <!-- Plugin metadata, used to uniquely identify the extension -->
        <!-- The assembly plugin (below) is going to put this in the Jar Manifest.mf -->
        <extension.id>${project.artifactId}</extension.id>
        <extension.class>com.hypr.server.rp.extensions.okta.OktaExtension</extension.class>
        <extension.version>${project.version}</extension.version>
        <extension.provider>HYPR Corp</extension.provider>
        <extension.dependencies/>
    </properties>

Step 5 - Testing

It is recommended to unit/component test your plugin code. There are no complicated dependencies so it is easy to add tests.

You can simulate the plugin configuration by manually as shown below:

public class MyExtensionTest {
  
  private MyPlugin.MyRegistrationExtension setupTestExtension() {
  
    MyPlugin.MyRegistrationExtension ext = new MyPlugin.MyRegistrationExtension();

    // Setup test configuration 
    PluginConfigAttribute config = new PluginConfigAttribute();
    config.setName("Attribute A");
    config.setValue("Value");

    List<PluginConfigAttribute> config = new ArrayList<>();
    config.add(config);

    // Invoke the callback to set configuration on the ext 
    // Once ext is deployed, the server does this step
    ext.setConfigAttributes(config);
    return ext;
  }
  
  @Test
  public void testReg() {
    MyPlugin.MyRegistrationExtension ext = setupTestExtension();
    // Invoke the callbacks on the ext and assert outcome
  }
}

Now that we have a plugin instance (above), you can invoke the callbacks to test relevant code.