blob: f03c4f4f166c6cdf0f50c0510923e686b0b5a744 [file] [log] [blame]
<!DOCTYPE HTML>
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (11.0.11) on Wed May 12 10:10:59 EDT 2021 -->
<title>AbstractMechanism (Qpid ProtonJ2 Parent 1.0.0-M1 API)</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="dc.created" content="2021-05-12">
<link rel="stylesheet" type="text/css" href="../../../../../../../stylesheet.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../../../../../jquery/jquery-ui.css" title="Style">
<script type="text/javascript" src="../../../../../../../script.js"></script>
<script type="text/javascript" src="../../../../../../../jquery/jszip/dist/jszip.min.js"></script>
<script type="text/javascript" src="../../../../../../../jquery/jszip-utils/dist/jszip-utils.min.js"></script>
<!--[if IE]>
<script type="text/javascript" src="../../../../../../../jquery/jszip-utils/dist/jszip-utils-ie.min.js"></script>
<![endif]-->
<script type="text/javascript" src="../../../../../../../jquery/jquery-3.5.1.js"></script>
<script type="text/javascript" src="../../../../../../../jquery/jquery-ui.js"></script>
</head>
<body>
<script type="text/javascript"><!--
try {
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="AbstractMechanism (Qpid ProtonJ2 Parent 1.0.0-M1 API)";
}
}
catch(err) {
}
//-->
var data = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10};
var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
var altColor = "altColor";
var rowColor = "rowColor";
var tableTab = "tableTab";
var activeTableTab = "activeTableTab";
var pathtoroot = "../../../../../../../";
var useModuleDirectories = true;
loadScripts(document, 'script');</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<header role="banner">
<nav role="navigation">
<div class="fixedNav">
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a id="navbar.top">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.top" title="Skip navigation links">Skip navigation links</a></div>
<a id="navbar.top.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../../../../index.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="class-use/AbstractMechanism.html">Use</a></li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../../../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../../../../../index-all.html">Index</a></li>
<li><a href="../../../../../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../../../../../../../allclasses.html">All&nbsp;Classes</a></li>
</ul>
<ul class="navListSearch">
<li><label for="search">SEARCH:</label>
<input type="text" id="search" value="search" disabled="disabled">
<input type="reset" id="reset" value="reset" disabled="disabled">
</li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
</div>
<div>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li>Nested&nbsp;|&nbsp;</li>
<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
<li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li><a href="#field.detail">Field</a>&nbsp;|&nbsp;</li>
<li><a href="#constructor.detail">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.detail">Method</a></li>
</ul>
</div>
<a id="skip.navbar.top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
</div>
<div class="navPadding">&nbsp;</div>
<script type="text/javascript"><!--
$('.navPadding').css('padding-top', $('.fixedNav').css("height"));
//-->
</script>
</nav>
</header>
<!-- ======== START OF CLASS DATA ======== -->
<main role="main">
<div class="header">
<div class="subTitle"><span class="packageLabelInType">Package</span>&nbsp;<a href="package-summary.html">org.apache.qpid.protonj2.engine.sasl.client</a></div>
<h2 title="Class AbstractMechanism" class="title">Class AbstractMechanism</h2>
</div>
<div class="contentContainer">
<ul class="inheritance">
<li>java.lang.Object</li>
<li>
<ul class="inheritance">
<li>org.apache.qpid.protonj2.engine.sasl.client.AbstractMechanism</li>
</ul>
</li>
</ul>
<div class="description">
<ul class="blockList">
<li class="blockList">
<dl>
<dt>All Implemented Interfaces:</dt>
<dd><code><a href="Mechanism.html" title="interface in org.apache.qpid.protonj2.engine.sasl.client">Mechanism</a></code></dd>
</dl>
<dl>
<dt>Direct Known Subclasses:</dt>
<dd><code><a href="AnonymousMechanism.html" title="class in org.apache.qpid.protonj2.engine.sasl.client">AnonymousMechanism</a></code>, <code><a href="CramMD5Mechanism.html" title="class in org.apache.qpid.protonj2.engine.sasl.client">CramMD5Mechanism</a></code>, <code><a href="ExternalMechanism.html" title="class in org.apache.qpid.protonj2.engine.sasl.client">ExternalMechanism</a></code>, <code><a href="PlainMechanism.html" title="class in org.apache.qpid.protonj2.engine.sasl.client">PlainMechanism</a></code>, <code><a href="ScramSHA1Mechanism.html" title="class in org.apache.qpid.protonj2.engine.sasl.client">ScramSHA1Mechanism</a></code>, <code><a href="ScramSHA256Mechanism.html" title="class in org.apache.qpid.protonj2.engine.sasl.client">ScramSHA256Mechanism</a></code>, <code><a href="ScramSHA512Mechanism.html" title="class in org.apache.qpid.protonj2.engine.sasl.client">ScramSHA512Mechanism</a></code>, <code><a href="XOauth2Mechanism.html" title="class in org.apache.qpid.protonj2.engine.sasl.client">XOauth2Mechanism</a></code></dd>
</dl>
<hr>
<pre>public abstract class <span class="typeNameLabel">AbstractMechanism</span>
extends java.lang.Object
implements <a href="Mechanism.html" title="interface in org.apache.qpid.protonj2.engine.sasl.client">Mechanism</a></pre>
<div class="block">Base class for SASL Authentication Mechanism that implements the basic
methods of a Mechanism class.</div>
</li>
</ul>
</div>
<div class="summary">
<ul class="blockList">
<li class="blockList">
<!-- =========== FIELD SUMMARY =========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="field.summary">
<!-- -->
</a>
<h3>Field Summary</h3>
<table class="memberSummary">
<caption><span>Fields</span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colSecond" scope="col">Field</th>
<th class="colLast" scope="col">Description</th>
</tr>
<tr class="altColor">
<td class="colFirst"><code>protected static <a href="../../../buffer/ProtonBuffer.html" title="interface in org.apache.qpid.protonj2.buffer">ProtonBuffer</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#EMPTY">EMPTY</a></span></code></th>
<td class="colLast">&nbsp;</td>
</tr>
</table>
</li>
</ul>
</section>
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="constructor.summary">
<!-- -->
</a>
<h3>Constructor Summary</h3>
<table class="memberSummary">
<caption><span>Constructors</span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colFirst" scope="col">Constructor</th>
<th class="colLast" scope="col">Description</th>
</tr>
<tr class="altColor">
<th class="colConstructorName" scope="row"><code><span class="memberNameLink"><a href="#%3Cinit%3E()">AbstractMechanism</a></span>()</code></th>
<td class="colLast">&nbsp;</td>
</tr>
</table>
</li>
</ul>
</section>
<!-- ========== METHOD SUMMARY =========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="method.summary">
<!-- -->
</a>
<h3>Method Summary</h3>
<table class="memberSummary">
<caption><span id="t0" class="activeTableTab"><span>All Methods</span><span class="tabEnd">&nbsp;</span></span><span id="t2" class="tableTab"><span><a href="javascript:show(2);">Instance Methods</a></span><span class="tabEnd">&nbsp;</span></span><span id="t4" class="tableTab"><span><a href="javascript:show(8);">Concrete Methods</a></span><span class="tabEnd">&nbsp;</span></span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colSecond" scope="col">Method</th>
<th class="colLast" scope="col">Description</th>
</tr>
<tr id="i0" class="altColor">
<td class="colFirst"><code><a href="../../../buffer/ProtonBuffer.html" title="interface in org.apache.qpid.protonj2.buffer">ProtonBuffer</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#getChallengeResponse(org.apache.qpid.protonj2.engine.sasl.client.SaslCredentialsProvider,org.apache.qpid.protonj2.buffer.ProtonBuffer)">getChallengeResponse</a></span>&#8203;(<a href="SaslCredentialsProvider.html" title="interface in org.apache.qpid.protonj2.engine.sasl.client">SaslCredentialsProvider</a>&nbsp;credentials,
<a href="../../../buffer/ProtonBuffer.html" title="interface in org.apache.qpid.protonj2.buffer">ProtonBuffer</a>&nbsp;challenge)</code></th>
<td class="colLast">
<div class="block">Create a response based on a given challenge from the remote peer.</div>
</td>
</tr>
<tr id="i1" class="rowColor">
<td class="colFirst"><code><a href="../../../buffer/ProtonBuffer.html" title="interface in org.apache.qpid.protonj2.buffer">ProtonBuffer</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#getInitialResponse(org.apache.qpid.protonj2.engine.sasl.client.SaslCredentialsProvider)">getInitialResponse</a></span>&#8203;(<a href="SaslCredentialsProvider.html" title="interface in org.apache.qpid.protonj2.engine.sasl.client">SaslCredentialsProvider</a>&nbsp;credentials)</code></th>
<td class="colLast">
<div class="block">Create an initial response based on selected mechanism.</div>
</td>
</tr>
<tr id="i2" class="altColor">
<td class="colFirst"><code>boolean</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#isEnabledByDefault()">isEnabledByDefault</a></span>()</code></th>
<td class="colLast">
<div class="block">Allows the mechanism to indicate if it is enabled by default, or only when explicitly enabled
through configuring the permitted SASL mechanisms.</div>
</td>
</tr>
<tr id="i3" class="rowColor">
<td class="colFirst"><code>java.lang.String</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#toString()">toString</a></span>()</code></th>
<td class="colLast">&nbsp;</td>
</tr>
<tr id="i4" class="altColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#verifyCompletion()">verifyCompletion</a></span>()</code></th>
<td class="colLast">
<div class="block">Verifies that the SASL exchange has completed successfully.</div>
</td>
</tr>
</table>
<ul class="blockList">
<li class="blockList"><a id="methods.inherited.from.class.java.lang.Object">
<!-- -->
</a>
<h3>Methods inherited from class&nbsp;java.lang.Object</h3>
<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait</code></li>
</ul>
<ul class="blockList">
<li class="blockList"><a id="methods.inherited.from.class.org.apache.qpid.protonj2.engine.sasl.client.Mechanism">
<!-- -->
</a>
<h3>Methods inherited from interface&nbsp;org.apache.qpid.protonj2.engine.sasl.client.<a href="Mechanism.html" title="interface in org.apache.qpid.protonj2.engine.sasl.client">Mechanism</a></h3>
<code><a href="Mechanism.html#getName()">getName</a>, <a href="Mechanism.html#isApplicable(org.apache.qpid.protonj2.engine.sasl.client.SaslCredentialsProvider)">isApplicable</a></code></li>
</ul>
</li>
</ul>
</section>
</li>
</ul>
</div>
<div class="details">
<ul class="blockList">
<li class="blockList">
<!-- ============ FIELD DETAIL =========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="field.detail">
<!-- -->
</a>
<h3>Field Detail</h3>
<a id="EMPTY">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>EMPTY</h4>
<pre>protected static final&nbsp;<a href="../../../buffer/ProtonBuffer.html" title="interface in org.apache.qpid.protonj2.buffer">ProtonBuffer</a> EMPTY</pre>
</li>
</ul>
</li>
</ul>
</section>
<!-- ========= CONSTRUCTOR DETAIL ======== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="constructor.detail">
<!-- -->
</a>
<h3>Constructor Detail</h3>
<a id="&lt;init&gt;()">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>AbstractMechanism</h4>
<pre>public&nbsp;AbstractMechanism()</pre>
</li>
</ul>
</li>
</ul>
</section>
<!-- ============ METHOD DETAIL ========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="method.detail">
<!-- -->
</a>
<h3>Method Detail</h3>
<a id="getInitialResponse(org.apache.qpid.protonj2.engine.sasl.client.SaslCredentialsProvider)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>getInitialResponse</h4>
<pre class="methodSignature">public&nbsp;<a href="../../../buffer/ProtonBuffer.html" title="interface in org.apache.qpid.protonj2.buffer">ProtonBuffer</a>&nbsp;getInitialResponse&#8203;(<a href="SaslCredentialsProvider.html" title="interface in org.apache.qpid.protonj2.engine.sasl.client">SaslCredentialsProvider</a>&nbsp;credentials)
throws javax.security.sasl.SaslException</pre>
<div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="Mechanism.html#getInitialResponse(org.apache.qpid.protonj2.engine.sasl.client.SaslCredentialsProvider)">Mechanism</a></code></span></div>
<div class="block">Create an initial response based on selected mechanism.
May be null if there is no initial response.</div>
<dl>
<dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
<dd><code><a href="Mechanism.html#getInitialResponse(org.apache.qpid.protonj2.engine.sasl.client.SaslCredentialsProvider)">getInitialResponse</a></code>&nbsp;in interface&nbsp;<code><a href="Mechanism.html" title="interface in org.apache.qpid.protonj2.engine.sasl.client">Mechanism</a></code></dd>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>credentials</code> - The credentials that are supplied for this SASL negotiation.</dd>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>the initial response, or null if there isn't one.</dd>
<dt><span class="throwsLabel">Throws:</span></dt>
<dd><code>javax.security.sasl.SaslException</code> - if an error occurs generating the initial response.</dd>
</dl>
</li>
</ul>
<a id="getChallengeResponse(org.apache.qpid.protonj2.engine.sasl.client.SaslCredentialsProvider,org.apache.qpid.protonj2.buffer.ProtonBuffer)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>getChallengeResponse</h4>
<pre class="methodSignature">public&nbsp;<a href="../../../buffer/ProtonBuffer.html" title="interface in org.apache.qpid.protonj2.buffer">ProtonBuffer</a>&nbsp;getChallengeResponse&#8203;(<a href="SaslCredentialsProvider.html" title="interface in org.apache.qpid.protonj2.engine.sasl.client">SaslCredentialsProvider</a>&nbsp;credentials,
<a href="../../../buffer/ProtonBuffer.html" title="interface in org.apache.qpid.protonj2.buffer">ProtonBuffer</a>&nbsp;challenge)
throws javax.security.sasl.SaslException</pre>
<div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="Mechanism.html#getChallengeResponse(org.apache.qpid.protonj2.engine.sasl.client.SaslCredentialsProvider,org.apache.qpid.protonj2.buffer.ProtonBuffer)">Mechanism</a></code></span></div>
<div class="block">Create a response based on a given challenge from the remote peer.</div>
<dl>
<dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
<dd><code><a href="Mechanism.html#getChallengeResponse(org.apache.qpid.protonj2.engine.sasl.client.SaslCredentialsProvider,org.apache.qpid.protonj2.buffer.ProtonBuffer)">getChallengeResponse</a></code>&nbsp;in interface&nbsp;<code><a href="Mechanism.html" title="interface in org.apache.qpid.protonj2.engine.sasl.client">Mechanism</a></code></dd>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>credentials</code> - The credentials that are supplied for this SASL negotiation.</dd>
<dd><code>challenge</code> - The challenge that this Mechanism should response to.</dd>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>the response that answers the given challenge.</dd>
<dt><span class="throwsLabel">Throws:</span></dt>
<dd><code>javax.security.sasl.SaslException</code> - if an error occurs generating the challenge response.</dd>
</dl>
</li>
</ul>
<a id="verifyCompletion()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>verifyCompletion</h4>
<pre class="methodSignature">public&nbsp;void&nbsp;verifyCompletion()
throws javax.security.sasl.SaslException</pre>
<div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="Mechanism.html#verifyCompletion()">Mechanism</a></code></span></div>
<div class="block">Verifies that the SASL exchange has completed successfully. This is
an opportunity for the mechanism to ensure that all mandatory
steps have been completed successfully and to cleanup and resources
that are held by this Mechanism.</div>
<dl>
<dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
<dd><code><a href="Mechanism.html#verifyCompletion()">verifyCompletion</a></code>&nbsp;in interface&nbsp;<code><a href="Mechanism.html" title="interface in org.apache.qpid.protonj2.engine.sasl.client">Mechanism</a></code></dd>
<dt><span class="throwsLabel">Throws:</span></dt>
<dd><code>javax.security.sasl.SaslException</code> - if the outcome of the SASL exchange is not valid for this Mechanism</dd>
</dl>
</li>
</ul>
<a id="isEnabledByDefault()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>isEnabledByDefault</h4>
<pre class="methodSignature">public&nbsp;boolean&nbsp;isEnabledByDefault()</pre>
<div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="Mechanism.html#isEnabledByDefault()">Mechanism</a></code></span></div>
<div class="block">Allows the mechanism to indicate if it is enabled by default, or only when explicitly enabled
through configuring the permitted SASL mechanisms. Any mechanism selection logic should examine
this value along with the configured allowed mechanism and decide if this one should be used.
Typically most mechanisms can be enabled by default but some require explicit configuration
in order to operate which implies that selecting them by default would always cause an authentication
error if that mechanism matches the highest priority value offered by the remote peer.</div>
<dl>
<dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
<dd><code><a href="Mechanism.html#isEnabledByDefault()">isEnabledByDefault</a></code>&nbsp;in interface&nbsp;<code><a href="Mechanism.html" title="interface in org.apache.qpid.protonj2.engine.sasl.client">Mechanism</a></code></dd>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>true if this Mechanism is enabled by default.</dd>
</dl>
</li>
</ul>
<a id="toString()">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>toString</h4>
<pre class="methodSignature">public&nbsp;java.lang.String&nbsp;toString()</pre>
<dl>
<dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
<dd><code>toString</code>&nbsp;in class&nbsp;<code>java.lang.Object</code></dd>
</dl>
</li>
</ul>
</li>
</ul>
</section>
</li>
</ul>
</div>
</div>
</main>
<!-- ========= END OF CLASS DATA ========= -->
<footer role="contentinfo">
<nav role="navigation">
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a id="navbar.bottom">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.bottom" title="Skip navigation links">Skip navigation links</a></div>
<a id="navbar.bottom.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../../../../index.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="class-use/AbstractMechanism.html">Use</a></li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../../../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../../../../../index-all.html">Index</a></li>
<li><a href="../../../../../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../../../../../../../allclasses.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
</div>
<div>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li>Nested&nbsp;|&nbsp;</li>
<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
<li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li><a href="#field.detail">Field</a>&nbsp;|&nbsp;</li>
<li><a href="#constructor.detail">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.detail">Method</a></li>
</ul>
</div>
<a id="skip.navbar.bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</nav>
<p class="legalCopy"><small>Copyright &#169; 2021 <a href="https://www.apache.org/">The Apache Software Foundation</a>. All rights reserved.</small></p>
</footer>
</body>
</html>