Skip to content

Commit

Permalink
Documentation: add Custom Group Provider Guide
Browse files Browse the repository at this point in the history
  • Loading branch information
guusdk committed Jul 14, 2023
1 parent d45abdf commit d47c5bd
Showing 1 changed file with 192 additions and 0 deletions.
192 changes: 192 additions & 0 deletions documentation/implementing-groupprovider-guide.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Openfire: Custom Group Provider Guide</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>

<article>

<header>
<img src="images/header_logo.gif" alt="Openfire Logo" />
<h1>Custom Group Provider Guide</h1>
</header>

<nav>
<a href="index.html">&laquo; Back to documentation index</a>
</nav>

<section id="intro">

<h2>Introduction</h2>

<p>
This is a guide for developers that wish to integrate Openfire with their own group system.
</p>

<aside>
<p>
An Openfire 'group' is a logical definition of entities, that is typically used to organize users in
collections. It explicitly does not cover 'group chat', which in Openfire (and XMPP), is refered to as
"multi-user chat" (MUC).
</p>
</aside>

<p>
This integration requires some Java knowledge in order to implement a custom group provider
for Openfire. The skill needed will vary depending on what you are trying to achieve.
</p>

<p>Topics that are covered in this document:</p>

<nav>
<ul>
<li><a href="#background">Background</a>
<li><a href="#groupprovider">The GroupProvider extension point</a>
<li><a href="#faq">Frequently Asked Questions</a>
</ul>
</nav>

</section>

<section id="background">

<h2>Background</h2>

<p>
Under standard configuration, Openfire maintains group data in its own database tables. Various
alternatives to this are offered that allow you to <a href="ldap-guide.html">use groups defined in Active Directory or LDAP</a>
or <a href="db-integration-guide.html#group-integration">obtaining groups from custom database tables</a>.
</p>
<p>
If you're interested in integrating with a system that is not compatible with the standard integration
options that are provided by Openfire, then you can implement a custom integration. This guide will help you
get started!
</p>

</section>

<section id="groupprovider">

<h2>The GroupProvider extension point</h2>

<p>
Openfire's API defines the <a href="javadoc/org/jivesoftware/openfire/group/GroupProvider.html">GroupProvider</a>
interface, which is the extension point to use when implementing custom group functionality. It is noteworthy
that many implementations choose to inherit from
<a href="javadoc/org/jivesoftware/openfire/group/AbstractGroupProvider.html">AbstractGroupProvider</a>. This
abstract class provides common functionality typically used by implementations. You are, of course, free to
write your own implementation that does not extend on <code>AbstractGroupProvider</code>!
</p>
<p>
The default implementation of this provider is the <code>DefaultGroupProvider</code>, which as the name
suggests is the version of this provider Openfire will use if not overridden. It uses the
<code>ofGroup</code>, <code>ofGroupUser</code> and <code>ofGroupProp</code> database tables.
</p>
<p>
The steps to get Openfire using a custom <code>GroupProvider</code> are described below.
</p>
<ol>
<li>
Write a class that implements <code>GroupProvider</code>, providing your own business logic.
</li>
<li>
Make the class available in a jar and make this available to Openfire by placing it in the lib directory.
There are numerous ways to package a jar with this class inside it, popular build systems such as Gradle and Maven
can make your life easier.
</li>
<li>
Set the property <code>provider.group.className</code> to be the full name of your class, e.g.
<code>org.example.CustomGroupProvider</code>. You can easily do this by defining such a property in the
<code>conf/openfire.xml</code> configuration file, as shown below.
<fieldset>
<legend>Example openfire.xml configuration snippet</legend>
<pre><code>&lt;provider&gt;
&lt;group&gt;
&lt;className&gt;org.example.CustomGroupProvider&lt;/className&gt;
&lt;/group&gt;
&lt;/provider&gt;</code></pre>
</fieldset>
</li>
<li>
Restart Openfire. Your custom class should now be providing user groups to Openfire.
</li>
</ol>
<p>
It is worth noting that the <code>GroupProvider</code> interface defines an interface that can be used to
both read data from, but also write data back to the system that is being integrated with. If the system
that you're integrating with can not or must not have its user definitions changed, you can implement your
provider as being 'read-only'.
</p>
<p>
To mark your provider as being read-only, implement the <code>isReadOnly()</code> method to return the value
<code>true</code>. All methods that would cause a change of data won't be invoked by Openfire if you do so.
These methods should receive an implementation that throws <code>java.lang.UnsupportedOperationException</code>.
</p>
<p>
A similar approach (throwing <code>java.lang.UnsupportedOperationException</code>) can be used to prevent
implementing optional functionality, such as the support group properties.
</p>


</section>

<section id="faq">

<h2>Frequently Asked Questions</h2>

<h4>Do I have to compile my custom class into the Openfire jar?</h4>
<p>
No, the class only needs to be visible on the Openfire classpath.
</p>

<h4>How do I ensure my custom class is visible on the Openfire classpath?</h4>
<p>
Just place your new custom library in the Openfire lib directory, this will ensure it is automatically
available at startup.
</p>

<h4>Can I see some examples?</h4>
<p>
Openfire's own group functionality makes use of the <code>GroupProvider</code> API! If you want to get
some inspiration, you can have a look at the implementations of this interface that are part of Openfire,
such as the ones below.
</p>
<ul>
<li><code>org.jivesoftware.openfire.group.DefaultGroupProvider</code> - used as the default provider.</li>
<li><code>org.jivesoftware.openfire.group.JDBCGroupProvider</code> - integrates with a custom database.</li>
<li><code>org.jivesoftware.openfire.ldap.LdapGroupProvider</code> - used when Openfire is configured to integrate with Active Directory or LDAP.</li>
</ul>
<p>
Note that these providers are but a sample of the available providers. Discover more providers by using your
IDE to find implementations of the interface!
</p>

<h4>Will I have a degradation in performance using a custom GroupProvider?</h4>
<p>
It completely depends on your implementation. As with any Openfire customisation or plugin, badly written
code has the potential to cause Openfire to perform slower. Use performance testing tools such as Tsung to
ensure issues haven't been introduced.
</p>

<h4>How can I have my custom class connect to another DB/Web service/NoSQL store etc?</h4>
<p>
This is out of the scope of this documentation and is your choice as a developer. If you are looking to
externalize properties like connection details, the Openfire properties mechanism and the JiveGlobals class
are good places to start investigating.
</p>

</section>

<footer>
<p>
An active support community for Openfire is available at
<a href="https://discourse.igniterealtime.org">https://discourse.igniterealtime.org</a>.
</p>
</footer>

</article>

</body>
</html>

0 comments on commit d47c5bd

Please sign in to comment.