directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From build...@apache.org
Subject svn commit: r1024235 - in /websites/staging/directory/trunk/content: ./ api/internal-design-guide/ api/internal-design-guide/images/
Date Wed, 24 Jan 2018 07:45:53 GMT
Author: buildbot
Date: Wed Jan 24 07:45:53 2018
New Revision: 1024235

Log:
Staging update by buildbot for directory

Modified:
    websites/staging/directory/trunk/content/   (props changed)
    websites/staging/directory/trunk/content/api/internal-design-guide/14-extended-operations.html
    websites/staging/directory/trunk/content/api/internal-design-guide/images/extended-request-decorator.graphml
    websites/staging/directory/trunk/content/api/internal-design-guide/images/extended-request-decorator.png

Propchange: websites/staging/directory/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Wed Jan 24 07:45:53 2018
@@ -1 +1 @@
-1821950
+1822082

Modified: websites/staging/directory/trunk/content/api/internal-design-guide/14-extended-operations.html
==============================================================================
--- websites/staging/directory/trunk/content/api/internal-design-guide/14-extended-operations.html (original)
+++ websites/staging/directory/trunk/content/api/internal-design-guide/14-extended-operations.html Wed Jan 24 07:45:53 2018
@@ -214,8 +214,8 @@ ExtendedResponse ::= [APPLICATION 24] SE
 </ul>
 <h2 id="encoding-and-decoding">Encoding and decoding<a class="headerlink" href="#encoding-and-decoding" title="Permanent link">&para;</a></h2>
 <p>When the <em>requestValue</em> part is present, it has to be encoded (when the client sends the request to the srrver) or decoded ( when the client receives the response from the server).</p>
-<h3 id="decoding-a-request">Decoding a request<a class="headerlink" href="#decoding-a-request" title="Permanent link">&para;</a></h3>
-<p>The payload is decoded on the fly when the request is processed during the <em>extendedRequest</em> is being decoded. The <em>StoreExtendedRequestValue</em> will store the <em>byte[]</em> - if any - and depending on the operation, the specific request will decode the value. Here is the <em>action</em> method for the <em>StoreExtendedRequestValue</em> class :</p>
+<h3 id="decoding-a-requestresponse">Decoding a request/response<a class="headerlink" href="#decoding-a-requestresponse" title="Permanent link">&para;</a></h3>
+<p>The payload is decoded on the fly when the request/response is processed during the <em>extendedRequest</em>/<em>extendedResponse</em> is being decoded. The <em>StoreExtendedRequestValue</em>/<em>StoreExtendedResponseValue</em> will store the <em>byte[]</em> - if any - and depending on the operation, the specific request/response will decode the value. Here is the <em>action</em> method for the <em>StoreExtendedRequestValue</em> class :</p>
 <div class="codehilite"><pre><span class="kd">public</span> <span class="kt">void</span> <span class="nf">action</span><span class="o">(</span> <span class="n">LdapMessageContainer</span><span class="o">&lt;</span><span class="n">ExtendedRequestDecorator</span><span class="o">&lt;?&gt;&gt;</span> <span class="n">container</span> <span class="o">)</span> <span class="kd">throws</span> <span class="n">DecoderException</span>
 <span class="o">{</span>
     <span class="c1">// We can allocate the ExtendedRequest Object</span>
@@ -237,7 +237,7 @@ ExtendedResponse ::= [APPLICATION 24] SE
 </pre></div>
 
 
-<p>Each implementaion may have a <em>setRequestValue</em> methd, overloading the parentclass. In this case, the value is decoded by the method.</p>
+<p>Each implementaion may have a <em>setRequestValue</em>/<em>setResponseValue</em> methd, overloading the parentclass. In this case, the value is decoded by the method.</p>
 <p>Here is an example of <em>setRequestValue</em> implementation (for the <em>PasswordModifyRequest</em> class) :</p>
 <div class="codehilite"><pre><span class="kd">public</span> <span class="kt">void</span> <span class="nf">setRequestValue</span><span class="o">(</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">requestValue</span> <span class="o">)</span>
 <span class="o">{</span>
@@ -266,10 +266,762 @@ ExtendedResponse ::= [APPLICATION 24] SE
 </pre></div>
 
 
-<p>As we can see, the decoder is invoked if the <em>requestValye</em> bytes is not null. It instanciate a <em>PasswordModifyRequest</em>.</p>
+<p>As we can see, the decoder is invoked if the <em>requestValue</em> bytes is not null. It instanciate a <em>PasswordModifyRequest</em>.</p>
 <p>If there is no payload, the parent's method is invoked (which basically does nothing).</p>
-<p>Here is a schema showing which operation as a payload that needs to be decoded :</p>
+<p>Here is a schema showing which request/response operations as a payload that needs to be decoded :</p>
 <p><img alt="Extended Operations Payload" src="images/extended-request-decorator.png" /></p>
+<h3 id="encoding-a-requestresponse">Encoding a request/response<a class="headerlink" href="#encoding-a-requestresponse" title="Permanent link">&para;</a></h3>
+<p>Encoding is done through a <em>Decorator</em>. Each extended operation has a dedicated <em>Decorator</em>, which may have a specific encoding function. Again, as we only encode the payload, if this payload is absent, there is nothing to encode. Not all the extended operations have a payload.</p>
+<p>If there is a payload to encode, this is done by calling the <em>getRequestValue()</em>/<em>getResponseValue()</em> method in the decorator. Here is an example :</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kt">byte</span><span class="o">[]</span> <span class="nf">getRequestValue</span><span class="o">()</span>
+<span class="o">{</span>
+    <span class="k">if</span> <span class="o">(</span> <span class="n">requestValue</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">try</span>
+        <span class="o">{</span>
+            <span class="n">requestValue</span> <span class="o">=</span> <span class="n">encodeInternal</span><span class="o">().</span><span class="na">array</span><span class="o">();</span>
+        <span class="o">}</span>
+        <span class="k">catch</span> <span class="o">(</span> <span class="n">EncoderException</span> <span class="n">e</span> <span class="o">)</span>
+        <span class="o">{</span>
+            <span class="n">LOG</span><span class="o">.</span><span class="na">error</span><span class="o">(</span> <span class="n">I18n</span><span class="o">.</span><span class="na">err</span><span class="o">(</span> <span class="n">I18n</span><span class="o">.</span><span class="na">ERR_04167</span> <span class="o">),</span> <span class="n">e</span> <span class="o">);</span>
+            <span class="k">throw</span> <span class="k">new</span> <span class="nf">RuntimeException</span><span class="o">(</span> <span class="n">e</span> <span class="o">);</span>
+        <span class="o">}</span>
+    <span class="o">}</span>
+
+    <span class="k">return</span> <span class="n">requestValue</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The <em>encodeInternal</em> method is in charge of encoding teh paylod.</p>
+<p>If the <em>getRequestValue</em>/getResponseValue_ method is absent, that leans there is nothing to encode. The inherited method will be executed, which returns null.</p>
+<p>Internally, we compute the length of the needed <strong>PDU</strong> accordingly to the data we have to encode, allocate a <em>ByteBuffer</em> to hold the encoded data, and store teh encoded data into it :</p>
+<div class="codehilite"><pre><span class="cm">/**</span>
+<span class="cm"> * Encodes the PasswordModifyRequest extended operation.</span>
+<span class="cm"> * </span>
+<span class="cm"> * @return A ByteBuffer that contains the encoded PDU</span>
+<span class="cm"> * @throws org.apache.directory.api.asn1.EncoderException If anything goes wrong.</span>
+<span class="cm"> */</span>
+<span class="cm">/* No qualifier */</span><span class="n">ByteBuffer</span> <span class="n">encodeInternal</span><span class="o">()</span> <span class="kd">throws</span> <span class="n">EncoderException</span>
+<span class="o">{</span>
+    <span class="n">ByteBuffer</span> <span class="n">bb</span> <span class="o">=</span> <span class="n">ByteBuffer</span><span class="o">.</span><span class="na">allocate</span><span class="o">(</span> <span class="n">computeLengthInternal</span><span class="o">()</span> <span class="o">);</span>
+
+    <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">UniversalTag</span><span class="o">.</span><span class="na">SEQUENCE</span><span class="o">.</span><span class="na">getValue</span><span class="o">()</span> <span class="o">);</span>
+    <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getBytes</span><span class="o">(</span> <span class="n">requestLength</span> <span class="o">)</span> <span class="o">);</span>
+
+    <span class="k">if</span> <span class="o">(</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getUserIdentity</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="kt">byte</span><span class="o">[]</span> <span class="n">userIdentity</span> <span class="o">=</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getUserIdentity</span><span class="o">();</span>
+        <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="o">(</span> <span class="kt">byte</span> <span class="o">)</span> <span class="n">PasswordModifyRequestConstants</span><span class="o">.</span><span class="na">USER_IDENTITY_TAG</span> <span class="o">);</span>
+        <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getBytes</span><span class="o">(</span> <span class="n">userIdentity</span><span class="o">.</span><span class="na">length</span> <span class="o">)</span> <span class="o">);</span>
+        <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">userIdentity</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+    <span class="k">if</span> <span class="o">(</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getOldPassword</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="kt">byte</span><span class="o">[]</span> <span class="n">oldPassword</span> <span class="o">=</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getOldPassword</span><span class="o">();</span>
+        <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="o">(</span> <span class="kt">byte</span> <span class="o">)</span> <span class="n">PasswordModifyRequestConstants</span><span class="o">.</span><span class="na">OLD_PASSWORD_TAG</span> <span class="o">);</span>
+        <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getBytes</span><span class="o">(</span> <span class="n">oldPassword</span><span class="o">.</span><span class="na">length</span> <span class="o">)</span> <span class="o">);</span>
+        <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">oldPassword</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+    <span class="k">if</span> <span class="o">(</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getNewPassword</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="kt">byte</span><span class="o">[]</span> <span class="n">newPassword</span> <span class="o">=</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getNewPassword</span><span class="o">();</span>
+        <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="o">(</span> <span class="kt">byte</span> <span class="o">)</span> <span class="n">PasswordModifyRequestConstants</span><span class="o">.</span><span class="na">NEW_PASSWORD_TAG</span> <span class="o">);</span>
+        <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getBytes</span><span class="o">(</span> <span class="n">newPassword</span><span class="o">.</span><span class="na">length</span> <span class="o">)</span> <span class="o">);</span>
+        <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">newPassword</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+    <span class="k">return</span> <span class="n">bb</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>and the <em>computeLength</em> method is :</p>
+<div class="codehilite"><pre><span class="cm">/**</span>
+<span class="cm"> * Compute the PasswordModifyRequest extended operation length</span>
+<span class="cm"> * &lt;pre&gt;</span>
+<span class="cm"> * 0x30 L1 </span>
+<span class="cm"> *   | </span>
+<span class="cm"> *  [+-- 0x80 L2 userIdentity] </span>
+<span class="cm"> *  [+-- 0x81 L3 oldPassword] </span>
+<span class="cm"> *  [+-- 0x82 L4 newPassword] </span>
+<span class="cm"> * &lt;/pre&gt;</span>
+<span class="cm"> */</span>
+<span class="cm">/* No qualifier */</span><span class="kt">int</span> <span class="n">computeLengthInternal</span><span class="o">()</span>
+<span class="o">{</span>
+    <span class="n">requestLength</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
+
+    <span class="k">if</span> <span class="o">(</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getUserIdentity</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="kt">int</span> <span class="n">len</span> <span class="o">=</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getUserIdentity</span><span class="o">().</span><span class="na">length</span><span class="o">;</span>
+        <span class="n">requestLength</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getNbBytes</span><span class="o">(</span> <span class="n">len</span> <span class="o">)</span> <span class="o">+</span> <span class="n">len</span><span class="o">;</span>
+    <span class="o">}</span>
+
+    <span class="k">if</span> <span class="o">(</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getOldPassword</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="kt">int</span> <span class="n">len</span> <span class="o">=</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getOldPassword</span><span class="o">().</span><span class="na">length</span><span class="o">;</span>
+        <span class="n">requestLength</span> <span class="o">+=</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getNbBytes</span><span class="o">(</span> <span class="n">len</span> <span class="o">)</span> <span class="o">+</span> <span class="n">len</span><span class="o">;</span>
+    <span class="o">}</span>
+
+    <span class="k">if</span> <span class="o">(</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getNewPassword</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="kt">int</span> <span class="n">len</span> <span class="o">=</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getNewPassword</span><span class="o">().</span><span class="na">length</span><span class="o">;</span>
+        <span class="n">requestLength</span> <span class="o">+=</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getNbBytes</span><span class="o">(</span> <span class="n">len</span> <span class="o">)</span> <span class="o">+</span> <span class="n">len</span><span class="o">;</span>
+    <span class="o">}</span>
+
+    <span class="k">return</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getNbBytes</span><span class="o">(</span> <span class="n">requestLength</span> <span class="o">)</span> <span class="o">+</span> <span class="n">requestLength</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<h2 id="adding-a-new-extended-operation">Adding a new Extended operation<a class="headerlink" href="#adding-a-new-extended-operation" title="Permanent link">&para;</a></h2>
+<p>We will show how to add a new extended operation in the <strong>LDAP API</strong>. The added operation is the <em>startTransaction</em> operation, described in <a href="https://tools.ietf.org/html/rfc5805">RFC 5805</a>. </p>
+<p>The <em>startTransactionRequest</em> has a <em>requestName</em> containing <strong>1.3.6.1.1.21.1</strong>, and no <em>requestValue</em>.
+The <em>startTransactionResponse</em> has no <em>responseName</em> and a <em>responseValue</em> containing an opaque transaction identifier (ie, it does not need to be decoced).</p>
+<p>We first need to declare an interface and implementation for each of those two operations. Those four elements are declared in the <em><coec-api></em> module (in <em>/ldap/extras/codec-api</em>), and in the <em>org.apache.directory.api.ldap.extras.extended.startTransaction</em> package, beside the other extended operations :</p>
+<div class="codehilite"><pre><span class="kn">package</span> <span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">directory</span><span class="o">.</span><span class="na">api</span><span class="o">.</span><span class="na">ldap</span><span class="o">.</span><span class="na">extras</span><span class="o">.</span><span class="na">extended</span><span class="o">.</span><span class="na">startTransaction</span><span class="o">;</span>
+
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.ExtendedRequest</span><span class="o">;</span>
+
+
+<span class="cm">/**</span>
+<span class="cm"> * The TransactionRequest interface. This is for the RFC 5805 Start Transaction Request,</span>
+<span class="cm"> * which grammar is :</span>
+<span class="cm"> * &lt;pre&gt;</span>
+<span class="cm"> * ExtendedRequest ::= [APPLICATION 23] SEQUENCE {</span>
+<span class="cm"> *              requestName      [0] LDAPOID,</span>
+<span class="cm"> *              requestValue     [1] OCTET STRING OPTIONAL }</span>
+<span class="cm"> * &lt;/pre&gt;</span>
+<span class="cm"> * </span>
+<span class="cm"> * where &#39;requestName&#39; is 1.3.6.1.1.21.1 and requestValue is absent.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @author &lt;a href=&quot;mailto:dev@directory.apache.org&quot;&gt;Apache Directory Project&lt;/a&gt;</span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">StartTransactionRequest</span> <span class="kd">extends</span> <span class="n">ExtendedRequest</span>
+<span class="o">{</span>
+    <span class="cm">/** The OID for the Transaction extended operation request. */</span>
+    <span class="n">String</span> <span class="n">EXTENSION_OID</span> <span class="o">=</span> <span class="s">&quot;1.3.6.1.1.21.1&quot;</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The request interface defines noting but the <em>OID</em>, as we don't have any payload.</p>
+<p>Here is the implementation :</p>
+<div class="codehilite"><pre><span class="kn">package</span> <span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">directory</span><span class="o">.</span><span class="na">api</span><span class="o">.</span><span class="na">ldap</span><span class="o">.</span><span class="na">extras</span><span class="o">.</span><span class="na">extended</span><span class="o">.</span><span class="na">startTransaction</span><span class="o">;</span>
+
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.AbstractExtendedRequest</span><span class="o">;</span>
+
+
+<span class="cm">/**</span>
+<span class="cm"> * Implement the extended Start Transaction Request as described in RFC 5805.</span>
+<span class="cm"> * </span>
+<span class="cm"> * It&#39;s grammar is :</span>
+<span class="cm"> * </span>
+<span class="cm"> * &lt;pre&gt;</span>
+<span class="cm"> * ExtendedRequest ::= [APPLICATION 23] SEQUENCE {</span>
+<span class="cm"> *              requestName      [0] LDAPOID,</span>
+<span class="cm"> *              requestValue     [1] OCTET STRING OPTIONAL }</span>
+<span class="cm"> * &lt;/pre&gt;</span>
+<span class="cm"> * </span>
+<span class="cm"> * where &#39;requestName&#39; is 1.3.6.1.1.21.1 and requestValue is absent.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @author &lt;a href=&quot;mailto:dev@directory.apache.org&quot;&gt;Apache Directory Project&lt;/a&gt;</span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">StartTransactionRequestImpl</span> <span class="kd">extends</span> <span class="n">AbstractExtendedRequest</span> <span class="kd">implements</span> <span class="n">StartTransactionRequest</span>
+<span class="o">{</span>
+    <span class="cm">/**</span>
+<span class="cm">     * Creates a new instance of StartTransactionRequestImpl.</span>
+<span class="cm">     *</span>
+<span class="cm">     * @param messageId the message id</span>
+<span class="cm">     */</span>
+    <span class="kd">public</span> <span class="nf">StartTransactionRequestImpl</span><span class="o">(</span> <span class="kt">int</span> <span class="n">messageId</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="kd">super</span><span class="o">(</span> <span class="n">messageId</span> <span class="o">);</span>
+        <span class="n">setRequestName</span><span class="o">(</span> <span class="n">EXTENSION_OID</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * Creates a new instance of StartTransactionRequestImpl.</span>
+<span class="cm">     */</span>
+    <span class="kd">public</span> <span class="nf">StartTransactionRequestImpl</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="n">setRequestName</span><span class="o">(</span> <span class="n">EXTENSION_OID</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">StartTransactionResponse</span> <span class="nf">getResultResponse</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">if</span> <span class="o">(</span> <span class="n">getResponse</span><span class="o">()</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">)</span>
+        <span class="o">{</span>
+            <span class="n">setResponse</span><span class="o">(</span> <span class="k">new</span> <span class="n">StartTransactionResponseImpl</span><span class="o">()</span> <span class="o">);</span>
+        <span class="o">}</span>
+
+        <span class="k">return</span> <span class="o">(</span> <span class="n">StartTransactionResponse</span> <span class="o">)</span> <span class="n">getResponse</span><span class="o">();</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>We just implement the method that returns the associated response.</p>
+<p>Now for the response, which has an opaque value, here is the interface :</p>
+<div class="codehilite"><pre><span class="kn">package</span> <span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">directory</span><span class="o">.</span><span class="na">api</span><span class="o">.</span><span class="na">ldap</span><span class="o">.</span><span class="na">extras</span><span class="o">.</span><span class="na">extended</span><span class="o">.</span><span class="na">startTransaction</span><span class="o">;</span>
+
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.ExtendedResponse</span><span class="o">;</span>
+
+
+<span class="cm">/**</span>
+<span class="cm"> * The interface for Start Transaction Extended Response. It&#39;s described in RFC 5805 :</span>
+<span class="cm"> * </span>
+<span class="cm"> * &lt;pre&gt;</span>
+<span class="cm"> * ExtendedResponse ::= [APPLICATION 24] SEQUENCE {</span>
+<span class="cm"> *            COMPONENTS OF LDAPResult,</span>
+<span class="cm"> *            responseName     [10] LDAPOID OPTIONAL,</span>
+<span class="cm"> *            responseValue    [11] OCTET STRING OPTIONAL }</span>
+<span class="cm"> * &lt;/pre&gt;</span>
+<span class="cm"> * </span>
+<span class="cm"> * where the responseName is not present, and the responseValue contain</span>
+<span class="cm"> * a transaction identifier when the result is SUCCESS.</span>
+<span class="cm"> * </span>
+<span class="cm"> * @author &lt;a href=&quot;mailto:dev@directory.apache.org&quot;&gt;Apache Directory Project&lt;/a&gt;</span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">StartTransactionResponse</span> <span class="kd">extends</span> <span class="n">ExtendedResponse</span>
+<span class="o">{</span>
+    <span class="cm">/** The OID for the Start Transaction extended operation response. */</span>
+    <span class="n">String</span> <span class="n">EXTENSION_OID</span> <span class="o">=</span> <span class="n">StartTransactionRequest</span><span class="o">.</span><span class="na">EXTENSION_OID</span><span class="o">;</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * @return The transaction ID if success</span>
+<span class="cm">     */</span>
+    <span class="kt">byte</span><span class="o">[]</span> <span class="nf">getTransactionId</span><span class="o">();</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>As the response value is opaque, we return it as a <em>byte[]</em>.</p>
+<p>Here is the implementation :</p>
+<div class="codehilite"><pre><span class="kn">package</span> <span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">directory</span><span class="o">.</span><span class="na">api</span><span class="o">.</span><span class="na">ldap</span><span class="o">.</span><span class="na">extras</span><span class="o">.</span><span class="na">extended</span><span class="o">.</span><span class="na">startTransaction</span><span class="o">;</span>
+
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.i18n.I18n</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.ExtendedResponseImpl</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.ResultCodeEnum</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.util.Strings</span><span class="o">;</span>
+
+
+<span class="cm">/**</span>
+<span class="cm"> * The interface for Start Transaction Extended Response. It&#39;s described in RFC 5805 :</span>
+<span class="cm"> * </span>
+<span class="cm"> * &lt;pre&gt;</span>
+<span class="cm"> * ExtendedResponse ::= [APPLICATION 24] SEQUENCE {</span>
+<span class="cm"> *            COMPONENTS OF LDAPResult,</span>
+<span class="cm"> *            responseName     [10] LDAPOID OPTIONAL,</span>
+<span class="cm"> *            responseValue    [11] OCTET STRING OPTIONAL }</span>
+<span class="cm"> * &lt;/pre&gt;</span>
+<span class="cm"> * </span>
+<span class="cm"> * where the responseName is not present, and the responseValue contain</span>
+<span class="cm"> * a transaction identifier when the result is SUCCESS.</span>
+<span class="cm"> * </span>
+<span class="cm"> *</span>
+<span class="cm"> * @author &lt;a href=&quot;mailto:dev@directory.apache.org&quot;&gt;Apache Directory Project&lt;/a&gt;</span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">StartTransactionResponseImpl</span> <span class="kd">extends</span> <span class="n">ExtendedResponseImpl</span> <span class="kd">implements</span> <span class="n">StartTransactionResponse</span>
+<span class="o">{</span>
+    <span class="cm">/** The transaction ID if the request was successful */</span>
+    <span class="kd">private</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">transactionId</span><span class="o">;</span>
+
+    <span class="cm">/**</span>
+<span class="cm">     * Create a new StartTransactionResponseImpl object</span>
+<span class="cm">     * </span>
+<span class="cm">     * @param messageId The messageId</span>
+<span class="cm">     * @param rcode the result code</span>
+<span class="cm">     * @param transactionId The transaction ID </span>
+<span class="cm">     */</span>
+    <span class="kd">public</span> <span class="nf">StartTransactionResponseImpl</span><span class="o">(</span> <span class="kt">int</span> <span class="n">messageId</span><span class="o">,</span> <span class="n">ResultCodeEnum</span> <span class="n">resultCode</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">transactionId</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="kd">super</span><span class="o">(</span> <span class="n">messageId</span> <span class="o">);</span>
+
+        <span class="k">switch</span> <span class="o">(</span> <span class="n">resultCode</span> <span class="o">)</span>
+        <span class="o">{</span>
+            <span class="k">case</span> <span class="nl">SUCCESS:</span>
+                <span class="k">this</span><span class="o">.</span><span class="na">transactionId</span> <span class="o">=</span> <span class="n">Strings</span><span class="o">.</span><span class="na">copy</span><span class="o">(</span> <span class="n">transactionId</span> <span class="o">);</span>
+                <span class="c1">// pass through ...</span>
+            <span class="k">case</span> <span class="nl">CANCELED:</span>
+            <span class="k">case</span> <span class="nl">CANNOT_CANCEL:</span>
+            <span class="k">case</span> <span class="nl">NO_SUCH_OPERATION:</span>
+            <span class="k">case</span> <span class="nl">TOO_LATE:</span>
+                <span class="k">break</span><span class="o">;</span>
+
+            <span class="k">default</span><span class="o">:</span>
+                <span class="k">throw</span> <span class="k">new</span> <span class="nf">IllegalArgumentException</span><span class="o">(</span> <span class="n">I18n</span><span class="o">.</span><span class="na">err</span><span class="o">(</span> <span class="n">I18n</span><span class="o">.</span><span class="na">ERR_04166</span><span class="o">,</span> <span class="n">ResultCodeEnum</span><span class="o">.</span><span class="na">SUCCESS</span><span class="o">,</span>
+                    <span class="n">ResultCodeEnum</span><span class="o">.</span><span class="na">OPERATIONS_ERROR</span><span class="o">,</span> <span class="n">ResultCodeEnum</span><span class="o">.</span><span class="na">INSUFFICIENT_ACCESS_RIGHTS</span> <span class="o">)</span> <span class="o">);</span>
+        <span class="o">}</span>
+
+        <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setMatchedDn</span><span class="o">(</span> <span class="kc">null</span> <span class="o">);</span>
+        <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setResultCode</span><span class="o">(</span> <span class="n">resultCode</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * Create a new StartTransactionResponseImpl instance</span>
+<span class="cm">     * </span>
+<span class="cm">     * @param messageId The request&#39;s messageId</span>
+<span class="cm">     * @param transactionId The transaction ID </span>
+<span class="cm">     */</span>
+    <span class="kd">public</span> <span class="nf">StartTransactionResponseImpl</span><span class="o">(</span> <span class="kt">int</span> <span class="n">messageId</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">transactionId</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="kd">super</span><span class="o">(</span> <span class="n">messageId</span> <span class="o">);</span>
+        <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setMatchedDn</span><span class="o">(</span> <span class="kc">null</span> <span class="o">);</span>
+        <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setResultCode</span><span class="o">(</span> <span class="n">ResultCodeEnum</span><span class="o">.</span><span class="na">SUCCESS</span> <span class="o">);</span>
+        <span class="k">this</span><span class="o">.</span><span class="na">transactionId</span> <span class="o">=</span> <span class="n">Strings</span><span class="o">.</span><span class="na">copy</span><span class="o">(</span> <span class="n">transactionId</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * Create a new StartTransactionResponseImpl instance</span>
+<span class="cm">     * </span>
+<span class="cm">     * @param transactionId The transaction ID </span>
+<span class="cm">     */</span>
+    <span class="kd">public</span> <span class="nf">StartTransactionResponseImpl</span><span class="o">(</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">transactionId</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="kd">super</span><span class="o">(</span> <span class="n">StartTransactionRequest</span><span class="o">.</span><span class="na">EXTENSION_OID</span> <span class="o">);</span>
+        <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setMatchedDn</span><span class="o">(</span> <span class="kc">null</span> <span class="o">);</span>
+        <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setResultCode</span><span class="o">(</span> <span class="n">ResultCodeEnum</span><span class="o">.</span><span class="na">SUCCESS</span> <span class="o">);</span>
+        <span class="k">this</span><span class="o">.</span><span class="na">transactionId</span> <span class="o">=</span> <span class="n">Strings</span><span class="o">.</span><span class="na">copy</span><span class="o">(</span> <span class="n">transactionId</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * Create a new StartTransactionResponseImpl instance</span>
+<span class="cm">     */</span>
+    <span class="kd">public</span> <span class="nf">StartTransactionResponseImpl</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="kd">super</span><span class="o">(</span> <span class="n">StartTransactionRequest</span><span class="o">.</span><span class="na">EXTENSION_OID</span> <span class="o">);</span>
+        <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setMatchedDn</span><span class="o">(</span> <span class="kc">null</span> <span class="o">);</span>
+        <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setResultCode</span><span class="o">(</span> <span class="n">ResultCodeEnum</span><span class="o">.</span><span class="na">UNWILLING_TO_PERFORM</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * Gets the OID uniquely identifying this extended response (a.k.a. its</span>
+<span class="cm">     * name). It&#39;s a null value for the Cancel response</span>
+<span class="cm">     * </span>
+<span class="cm">     * @return the OID of the extended response type.</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">String</span> <span class="nf">getResponseName</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="s">&quot;&quot;</span><span class="o">;</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="kt">int</span> <span class="nf">hashCode</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="kt">int</span> <span class="n">hash</span> <span class="o">=</span> <span class="mi">37</span><span class="o">;</span>
+
+        <span class="k">if</span> <span class="o">(</span> <span class="n">transactionId</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+        <span class="o">{</span>
+            <span class="k">for</span> <span class="o">(</span> <span class="kt">byte</span> <span class="n">b</span> <span class="o">:</span> <span class="n">transactionId</span> <span class="o">)</span>
+            <span class="o">{</span>
+                <span class="n">hash</span> <span class="o">+=</span> <span class="n">hash</span> <span class="o">*</span> <span class="mi">17</span> <span class="o">+</span> <span class="n">b</span><span class="o">;</span>
+            <span class="o">}</span>
+        <span class="o">}</span>
+
+        <span class="n">hash</span> <span class="o">=</span> <span class="n">hash</span> <span class="o">*</span> <span class="mi">17</span> <span class="o">+</span> <span class="n">getClass</span><span class="o">().</span><span class="na">getName</span><span class="o">().</span><span class="na">hashCode</span><span class="o">();</span>
+
+        <span class="k">return</span> <span class="n">hash</span><span class="o">;</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * @see Object#equals(Object)</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span> <span class="n">Object</span> <span class="n">obj</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">if</span> <span class="o">(</span> <span class="n">obj</span> <span class="o">==</span> <span class="k">this</span> <span class="o">)</span>
+        <span class="o">{</span>
+            <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
+        <span class="o">}</span>
+
+        <span class="k">if</span> <span class="o">(</span> <span class="o">!(</span> <span class="n">obj</span> <span class="k">instanceof</span> <span class="n">StartTransactionResponseImpl</span> <span class="o">)</span> <span class="o">)</span>
+        <span class="o">{</span>
+            <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
+        <span class="o">}</span>
+
+        <span class="k">return</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span> <span class="n">transactionId</span><span class="o">,</span> <span class="o">(</span> <span class="o">(</span> <span class="n">StartTransactionResponseImpl</span> <span class="o">)</span> <span class="n">obj</span> <span class="o">).</span><span class="na">transactionId</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="kt">byte</span><span class="o">[]</span> <span class="nf">getTransactionId</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="n">Strings</span><span class="o">.</span><span class="na">copy</span><span class="o">(</span> <span class="n">transactionId</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setTransactionId</span><span class="o">(</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">transactionId</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">this</span><span class="o">.</span><span class="na">transactionId</span> <span class="o">=</span> <span class="n">Strings</span><span class="o">.</span><span class="na">copy</span><span class="o">(</span> <span class="n">transactionId</span> <span class="o">);</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>There is nothing special in this implementation, we just make it so the <em>transactionId</em> bytes are copied to be sure they can't be altered from the outside. Basically, the payload is transfered pristine into the instance.</p>
+<p>Now that we have the interfaces and implementations, we need to add the decorators and the factory. The factory is used to initialize the <strong>API</strong> with the list of available extended operaiton at startup, as a mean to make the <strong>API</strong> extensible. It creates request and response, and the associated decorator.</p>
+<p>Here is the factory code, declared in the <em><extra-codec></em> module :</p>
+<div class="codehilite"><pre><span class="kn">package</span> <span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">directory</span><span class="o">.</span><span class="na">api</span><span class="o">.</span><span class="na">ldap</span><span class="o">.</span><span class="na">extras</span><span class="o">.</span><span class="na">extended</span><span class="o">.</span><span class="na">ads_impl</span><span class="o">.</span><span class="na">startTransaction</span><span class="o">;</span>
+
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.asn1.DecoderException</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.codec.api.ExtendedOperationFactory</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.codec.api.LdapApiService</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.cancel.CancelRequest</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionRequest</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionRequestImpl</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionResponse</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionResponseImpl</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.ExtendedRequest</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.ExtendedResponse</span><span class="o">;</span>
+
+
+<span class="cm">/**</span>
+<span class="cm"> * An {@link ExtendedOperationFactory} for creating cancel extended request response </span>
+<span class="cm"> * pairs.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @author &lt;a href=&quot;mailto:dev@directory.apache.org&quot;&gt;Apache Directory Project&lt;/a&gt;</span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">StartTransactionFactory</span> <span class="kd">implements</span> <span class="n">ExtendedOperationFactory</span>
+<span class="o">{</span>
+    <span class="kd">private</span> <span class="n">LdapApiService</span> <span class="n">codec</span><span class="o">;</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * Creates a new instance of CancelFactory.</span>
+<span class="cm">     *</span>
+<span class="cm">     * @param codec The codec for this factory.</span>
+<span class="cm">     */</span>
+    <span class="kd">public</span> <span class="nf">StartTransactionFactory</span><span class="o">(</span> <span class="n">LdapApiService</span> <span class="n">codec</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">this</span><span class="o">.</span><span class="na">codec</span> <span class="o">=</span> <span class="n">codec</span><span class="o">;</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">String</span> <span class="nf">getOid</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="n">CancelRequest</span><span class="o">.</span><span class="na">EXTENSION_OID</span><span class="o">;</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">StartTransactionResponse</span> <span class="nf">newResponse</span><span class="o">(</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">encodedValue</span> <span class="o">)</span> <span class="kd">throws</span> <span class="n">DecoderException</span>
+    <span class="o">{</span>
+        <span class="n">StartTransactionResponseDecorator</span> <span class="n">response</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StartTransactionResponseDecorator</span><span class="o">(</span> <span class="n">codec</span><span class="o">,</span> <span class="k">new</span> <span class="n">StartTransactionResponseImpl</span><span class="o">()</span> <span class="o">);</span>
+        <span class="n">response</span><span class="o">.</span><span class="na">setResponseValue</span><span class="o">(</span> <span class="n">encodedValue</span> <span class="o">);</span>
+
+        <span class="k">return</span> <span class="n">response</span><span class="o">;</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">StartTransactionRequest</span> <span class="nf">newRequest</span><span class="o">(</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">value</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="k">new</span> <span class="nf">StartTransactionRequestDecorator</span><span class="o">(</span> <span class="n">codec</span><span class="o">,</span> <span class="k">new</span> <span class="n">StartTransactionRequestImpl</span><span class="o">()</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">StartTransactionRequestDecorator</span> <span class="nf">decorate</span><span class="o">(</span> <span class="n">ExtendedRequest</span> <span class="n">modelRequest</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">if</span> <span class="o">(</span> <span class="n">modelRequest</span> <span class="k">instanceof</span> <span class="n">StartTransactionRequestDecorator</span> <span class="o">)</span>
+        <span class="o">{</span>
+            <span class="k">return</span> <span class="o">(</span> <span class="n">StartTransactionRequestDecorator</span> <span class="o">)</span> <span class="n">modelRequest</span><span class="o">;</span>
+        <span class="o">}</span>
+
+        <span class="k">return</span> <span class="k">new</span> <span class="nf">StartTransactionRequestDecorator</span><span class="o">(</span> <span class="n">codec</span><span class="o">,</span> <span class="kc">null</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">StartTransactionResponseDecorator</span> <span class="nf">decorate</span><span class="o">(</span> <span class="n">ExtendedResponse</span> <span class="n">decoratedMessage</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">if</span> <span class="o">(</span> <span class="n">decoratedMessage</span> <span class="k">instanceof</span> <span class="n">StartTransactionResponseDecorator</span> <span class="o">)</span>
+        <span class="o">{</span>
+            <span class="k">return</span> <span class="o">(</span> <span class="n">StartTransactionResponseDecorator</span> <span class="o">)</span> <span class="n">decoratedMessage</span><span class="o">;</span>
+        <span class="o">}</span>
+
+        <span class="k">return</span> <span class="k">new</span> <span class="nf">StartTransactionResponseDecorator</span><span class="o">(</span> <span class="n">codec</span><span class="o">,</span> <span class="kc">null</span> <span class="o">);</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The decorator are very simple : they just encapsulate the requets or response instance. It's because encoding or decoding is non existant for this operation. Decorators are declared in the <em><extra-codec></em> module.</p>
+<p>Here is teh code for both those decorators :</p>
+<div class="codehilite"><pre><span class="kn">package</span> <span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">directory</span><span class="o">.</span><span class="na">api</span><span class="o">.</span><span class="na">ldap</span><span class="o">.</span><span class="na">extras</span><span class="o">.</span><span class="na">extended</span><span class="o">.</span><span class="na">ads_impl</span><span class="o">.</span><span class="na">startTransaction</span><span class="o">;</span>
+
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.codec.api.ExtendedRequestDecorator</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.codec.api.LdapApiService</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionRequest</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionResponse</span><span class="o">;</span>
+
+
+<span class="cm">/**</span>
+<span class="cm"> * A Decorator for startTransaction request.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @author &lt;a href=&quot;mailto:dev@directory.apache.org&quot;&gt;Apache Directory Project&lt;/a&gt;</span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">StartTransactionRequestDecorator</span> <span class="kd">extends</span> <span class="n">ExtendedRequestDecorator</span><span class="o">&lt;</span><span class="n">StartTransactionRequest</span><span class="o">&gt;</span> <span class="kd">implements</span>
+    <span class="n">StartTransactionRequest</span>
+<span class="o">{</span>
+    <span class="cm">/** The internal startTransaction request */</span>
+    <span class="kd">private</span> <span class="n">StartTransactionRequest</span> <span class="n">startTransactionRequest</span><span class="o">;</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * Creates a new instance of StartTransactionRequestDecorator.</span>
+<span class="cm">     * </span>
+<span class="cm">     * @param codec The LDAP Service to use</span>
+<span class="cm">     * @param decoratedMessage The canceled request</span>
+<span class="cm">     */</span>
+    <span class="kd">public</span> <span class="nf">StartTransactionRequestDecorator</span><span class="o">(</span> <span class="n">LdapApiService</span> <span class="n">codec</span><span class="o">,</span> <span class="n">StartTransactionRequest</span> <span class="n">decoratedMessage</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="kd">super</span><span class="o">(</span> <span class="n">codec</span><span class="o">,</span> <span class="n">decoratedMessage</span> <span class="o">);</span>
+        <span class="n">startTransactionRequest</span> <span class="o">=</span> <span class="n">decoratedMessage</span><span class="o">;</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">StartTransactionResponse</span> <span class="nf">getResultResponse</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="o">(</span> <span class="n">StartTransactionResponse</span> <span class="o">)</span> <span class="n">startTransactionRequest</span><span class="o">.</span><span class="na">getResultResponse</span><span class="o">();</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>and for the response :</p>
+<div class="codehilite"><pre><span class="kn">package</span> <span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">directory</span><span class="o">.</span><span class="na">api</span><span class="o">.</span><span class="na">ldap</span><span class="o">.</span><span class="na">extras</span><span class="o">.</span><span class="na">extended</span><span class="o">.</span><span class="na">ads_impl</span><span class="o">.</span><span class="na">startTransaction</span><span class="o">;</span>
+
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.codec.api.ExtendedResponseDecorator</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.codec.api.LdapApiService</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionResponse</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.util.Strings</span><span class="o">;</span>
+
+
+<span class="cm">/**</span>
+<span class="cm"> * A Decorator for CancelResponses.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @author &lt;a href=&quot;mailto:dev@directory.apache.org&quot;&gt;Apache Directory Project&lt;/a&gt;</span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">StartTransactionResponseDecorator</span> <span class="kd">extends</span> <span class="n">ExtendedResponseDecorator</span><span class="o">&lt;</span><span class="n">StartTransactionResponse</span><span class="o">&gt;</span> <span class="kd">implements</span> <span class="n">StartTransactionResponse</span>
+<span class="o">{</span>
+    <span class="cm">/** The startTransaction response */</span>
+    <span class="kd">private</span> <span class="n">StartTransactionResponse</span> <span class="n">startTransactionResponse</span><span class="o">;</span>
+
+    <span class="cm">/**</span>
+<span class="cm">     * Creates a new instance of CancelResponseDecorator.</span>
+<span class="cm">     *</span>
+<span class="cm">     * @param codec The LDAP service instance</span>
+<span class="cm">     * @param decoratedMessage The decorated message</span>
+<span class="cm">     */</span>
+    <span class="kd">public</span> <span class="nf">StartTransactionResponseDecorator</span><span class="o">(</span> <span class="n">LdapApiService</span> <span class="n">codec</span><span class="o">,</span> <span class="n">StartTransactionResponse</span> <span class="n">decoratedMessage</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="kd">super</span><span class="o">(</span> <span class="n">codec</span><span class="o">,</span> <span class="n">decoratedMessage</span> <span class="o">);</span>
+        <span class="n">startTransactionResponse</span> <span class="o">=</span> <span class="n">decoratedMessage</span><span class="o">;</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setResponseValue</span><span class="o">(</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">responseValue</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">this</span><span class="o">.</span><span class="na">responseValue</span> <span class="o">=</span> <span class="n">Strings</span><span class="o">.</span><span class="na">copy</span><span class="o">(</span> <span class="n">responseValue</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="kt">byte</span><span class="o">[]</span> <span class="nf">getTransactionId</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="n">startTransactionResponse</span><span class="o">.</span><span class="na">getTransactionId</span><span class="o">();</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The last step is to declare the extended operation in the <strong>LDAP API</strong> initialization and <strong>OSGi</strong>. There are two places we have to declare the factory :</p>
+<ul>
+<li><em>CodecFactoryUtil</em> class, in the <em><ldap/codec/standalone></em> module</li>
+<li><em>ExtrasBundleActivator</em> class, in the <em><ldap/extras/codec></em> module</li>
+</ul>
+<p>Here is the added code in the <em>CodecFactoryUtil</em> class :</p>
+<div class="codehilite"><pre><span class="o">...</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.ads_impl.startTls.StartTlsFactory</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.ads_impl.startTransaction.StartTransactionFactory</span><span class="o">;</span>
+<span class="o">...</span>
+
+<span class="cm">/**</span>
+<span class="cm"> * A utility class for adding Codec and extended operation factories.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @author &lt;a href=&quot;mailto:dev@directory.apache.org&quot;&gt;Apache Directory Project&lt;/a&gt;</span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">CodecFactoryUtil</span>
+<span class="o">{</span>
+    <span class="o">...</span>
+    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">loadStockExtendedOperations</span><span class="o">(</span>
+        <span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">ExtendedOperationFactory</span><span class="o">&gt;</span> <span class="n">extendendOperationsFactories</span><span class="o">,</span> <span class="n">LdapApiService</span> <span class="n">apiService</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="o">...</span>
+
+        <span class="n">StartTlsFactory</span> <span class="n">startTlsFactory</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StartTlsFactory</span><span class="o">(</span> <span class="n">apiService</span> <span class="o">);</span>
+        <span class="n">extendendOperationsFactories</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">startTlsFactory</span><span class="o">.</span><span class="na">getOid</span><span class="o">(),</span> <span class="n">startTlsFactory</span> <span class="o">);</span>
+        <span class="n">LOG</span><span class="o">.</span><span class="na">info</span><span class="o">(</span> <span class="s">&quot;Registered pre-bundled extended operation factory: {}&quot;</span><span class="o">,</span> <span class="n">startTlsFactory</span><span class="o">.</span><span class="na">getOid</span><span class="o">()</span> <span class="o">);</span>
+
+        <span class="n">StartTransactionFactory</span> <span class="n">startTransactionFactory</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StartTransactionFactory</span><span class="o">(</span> <span class="n">apiService</span> <span class="o">);</span>
+        <span class="n">extendendOperationsFactories</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">startTransactionFactory</span><span class="o">.</span><span class="na">getOid</span><span class="o">(),</span> <span class="n">startTransactionFactory</span> <span class="o">);</span>
+        <span class="n">LOG</span><span class="o">.</span><span class="na">info</span><span class="o">(</span> <span class="s">&quot;Registered pre-bundled extended operation factory: {}&quot;</span><span class="o">,</span> <span class="n">startTransactionFactory</span><span class="o">.</span><span class="na">getOid</span><span class="o">()</span> <span class="o">);</span>
+        <span class="o">...</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>We just need to instanciate the factory, and to add it to the map of supported extended operations.</p>
+<p>And the added code for the <em>ExtrasBundleActivator</em> class :</p>
+<div class="codehilite"><pre><span class="o">...</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.ads_impl.startTls.StartTlsFactory</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.ads_impl.startTransaction.StartTransactionFactory</span><span class="o">;</span>
+<span class="o">...</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTls.StartTlsRequest</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionRequest</span><span class="o">;</span>
+<span class="o">...</span>
+
+<span class="cm">/**</span>
+<span class="cm"> * A BundleActivator for the ldap codec extras extension: extra ApacheDS and </span>
+<span class="cm"> * Apache Directory Studio specific controls and extended operations. </span>
+<span class="cm"> *</span>
+<span class="cm"> * @author &lt;a href=&quot;mailto:dev@directory.apache.org&quot;&gt;Apache Directory Project&lt;/a&gt;</span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ExtrasBundleActivator</span> <span class="kd">implements</span> <span class="n">BundleActivator</span>
+<span class="o">{</span>
+    <span class="o">...</span>
+    <span class="cm">/**</span>
+<span class="cm">     * Registers all the extras extended operations present in this control pack.</span>
+<span class="cm">     *</span>
+<span class="cm">     * @param codec The codec service.</span>
+<span class="cm">     */</span>
+    <span class="kd">private</span> <span class="kt">void</span> <span class="nf">registerExtrasExtendedOps</span><span class="o">(</span> <span class="n">LdapApiService</span> <span class="n">codec</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="c1">// --------------------------------------------------------------------</span>
+        <span class="c1">// Register Extended Request Factories</span>
+        <span class="c1">// --------------------------------------------------------------------</span>
+        <span class="o">...</span>
+
+        <span class="n">StartTlsFactory</span> <span class="n">startTlsFactory</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StartTlsFactory</span><span class="o">(</span> <span class="n">codec</span> <span class="o">);</span>
+        <span class="n">codec</span><span class="o">.</span><span class="na">registerExtendedRequest</span><span class="o">(</span> <span class="n">startTlsFactory</span> <span class="o">);</span>
+
+        <span class="n">StartTransactionFactory</span> <span class="n">startTransactionFactory</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StartTransactionFactory</span><span class="o">(</span> <span class="n">codec</span> <span class="o">);</span>
+        <span class="n">codec</span><span class="o">.</span><span class="na">registerExtendedRequest</span><span class="o">(</span> <span class="n">startTransactionFactory</span> <span class="o">);</span>
+        <span class="o">...</span>
+    <span class="o">}</span>
+
+
+    <span class="kd">private</span> <span class="kt">void</span> <span class="nf">unregisterExtrasExtendedOps</span><span class="o">(</span> <span class="n">LdapApiService</span> <span class="n">codec</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="o">...</span>
+        <span class="n">codec</span><span class="o">.</span><span class="na">unregisterExtendedRequest</span><span class="o">(</span> <span class="n">StartTlsRequest</span><span class="o">.</span><span class="na">EXTENSION_OID</span> <span class="o">);</span>
+        <span class="n">codec</span><span class="o">.</span><span class="na">unregisterExtendedRequest</span><span class="o">(</span> <span class="n">StartTransactionRequest</span><span class="o">.</span><span class="na">EXTENSION_OID</span> <span class="o">);</span>
+        <span class="o">...</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>We also have to export the package for it to be visible when using <strong>OSGi</strong>. This is done by modifying some <em>pom.xml</em> files.</p>
+<p><em><ldap/extras/codec></em> module <em>pom.xml</em> file :</p>
+<div class="codehilite"><pre>...
+<span class="nt">&lt;configuration&gt;</span>
+  <span class="nt">&lt;manifestLocation&gt;</span>META-INF<span class="nt">&lt;/manifestLocation&gt;</span>
+  <span class="nt">&lt;instructions&gt;</span>
+    <span class="nt">&lt;Bundle-SymbolicName&gt;</span>${project.groupId}.ldap.extras.codec<span class="nt">&lt;/Bundle-SymbolicName&gt;</span>
+    <span class="nt">&lt;Export-Package&gt;</span>
+        {local-packages};version=${project.version};-noimport:=true
+    <span class="nt">&lt;/Export-Package&gt;</span>
+    <span class="nt">&lt;Export-Package&gt;</span>
+      ...
+      org.apache.directory.api.ldap.extras.extended.ads_impl.startTls;version=${project.version};-noimport:=true,
+      org.apache.directory.api.ldap.extras.extended.ads_impl.startTransaction;version=${project.version};-noimport:=true,
+      ...
+    <span class="nt">&lt;/Export-Package&gt;</span>
+    <span class="nt">&lt;Import-Package&gt;</span>
+      ...
+      org.apache.directory.api.ldap.extras.extended.startTls;version=${project.version},
+      org.apache.directory.api.ldap.extras.extended.startTransaction;version=${project.version},
+      ...
+    <span class="nt">&lt;/Import-Package&gt;</span>
+</pre></div>
+
+
+<p><em><ldap/extras/codec-api></em> module <em>pom.xml</em> file :</p>
+<div class="codehilite"><pre>...
+<span class="nt">&lt;configuration&gt;</span>
+  <span class="nt">&lt;manifestLocation&gt;</span>META-INF<span class="nt">&lt;/manifestLocation&gt;</span>
+  <span class="nt">&lt;instructions&gt;</span>
+    <span class="nt">&lt;Bundle-SymbolicName&gt;</span>${project.groupId}.ldap.extras.codec.api<span class="nt">&lt;/Bundle-SymbolicName&gt;</span>
+    <span class="nt">&lt;Export-Package&gt;</span>
+      ...
+      org.apache.directory.api.ldap.extras.extended.startTls;version=${project.version};-noimport:=true,
+      org.apache.directory.api.ldap.extras.extended.startTransaction;version=${project.version};-noimport:=true,
+      ...
+    <span class="nt">&lt;/Export-Package&gt;</span>
+</pre></div>
 
 
     <div class="nav">

Modified: websites/staging/directory/trunk/content/api/internal-design-guide/images/extended-request-decorator.graphml
==============================================================================
Binary files - no diff available.

Modified: websites/staging/directory/trunk/content/api/internal-design-guide/images/extended-request-decorator.png
==============================================================================
Binary files - no diff available.



Mime
View raw message