directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Directory Server v1.5: Mitosis Development Guide (page edited)
Date Sun, 11 Jan 2009 22:21:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence" />
    <style type="text/css">
    <!--
    body, p, td, table, tr, .bodytext, .stepfield {
	font-family: Verdana, arial, sans-serif;
	font-size: 11px;
	line-height: 16px;
	color: #000000;
	font-weight: normal;
}
#PageContent {
	text-align: left;
	background-color: #fff;
	padding: 0px;
	margin: 0px;
    padding-bottom:20px;
}
/*
** when this stylesheet is used for the Tiny MCE Wysiwyg editor's edit area, we can't
** use an id=PageContent or class=wiki-content, so we must
** set the body style to that used for PageContent, and p to that used for wiki-content.
*/

body {
	margin: 0px;
	padding: 0px;
	text-align: center;
    background-color: #f0f0f0;
}

@media print {

body {
    background-color: #fff;
}

}

.monospaceInput {
    font:12px monospace
}

.wiki-content p, .commentblock p {
    margin: 16px 0px 16px 0px;
    padding: 0px;
}

.wiki-content-preview {
    padding: 5px;
    border-left: 1px solid #3c78b5;
    border-right: 1px solid #3c78b5;
}

ul, ol {
    margin-top: 2px;
    margin-bottom: 2px;
    padding-top: 0px;
    padding-bottom: 0px;
}

pre {
    padding: 0px;
    margin-top: 5px;
    margin-left: 15px;
    margin-bottom: 5px;
    margin-right: 5px;
    text-align: left;
}

.helpheading {
    font-weight: bold;
    background-color: #D0D9BD;
        border-bottom: 1px solid #3c78b5;
        padding: 4px 4px 4px 4px;
        margin: 0px;
        margin-top: 10px;
}
.helpcontent {
        padding: 4px 4px 20px 4px;
    background-color: #f5f7f1;
}

.code {
 	border: 1px dashed #3c78b5;
    font-size: 11px;
	font-family: Courier;
    margin: 10px;
	line-height: 13px;
}

.focusedComment {
    background: #ffffce;
}

.commentBox, .focusedComment {
    padding: 10px;
    margin: 5px 0 5px 0;
    border: 1px #bbb solid;
}

.codeHeader {
    background-color: #f0f0f0;
 	border-bottom: 1px dashed #3c78b5;
    padding: 3px;
	text-align: center;
}

.codeContent {
    text-align: left;
    background-color: #f0f0f0;
    padding: 3px;
}

.preformatted {
 	border: 1px dashed #3c78b5;
    font-size: 11px;
	font-family: Courier;
    margin: 10px;
	line-height: 13px;
}

.preformattedHeader {
    background-color: #f0f0f0;
 	border-bottom: 1px dashed #3c78b5;
    padding: 3px;
	text-align: center;
}

.preformattedContent {
    background-color: #f0f0f0;
    padding: 3px;
}

.panel {
 	border: 1px dashed #3c78b5;
    margin: 10px;
    margin-top: 0px;
}

.panelHeader {
    background-color: #f0f0f0;
 	border-bottom: 1px dashed #3c78b5;
    padding: 3px;
	text-align: center;
}

.panelContent {
    background-color: #f0f0f0;
    padding: 5px;
}

.anonymousAlert {
    background-color: #f0f0f0;
 	border: 1px dashed red;
    font-size: 11px;
    padding: 10px 5px 10px 5px;
    margin: 4px;
	line-height: 13px;
}

.lockAlert {
    background-color: #f0f0f0;
    width: 50%;
 	border: 1px dashed red;
    font-size: 11px;
    padding: 10px 5px 10px 5px;
    margin: 4px;
	line-height: 13px;
}


.code-keyword {
  color: #000091;
  background-color: inherit;
}

.code-object {
  color: #910091;
  background-color: inherit;
}

.code-quote {
  color: #009100;
  background-color: inherit;
}

.code-comment {
  color: #808080;
  background-color: inherit;
}


.code-xml .code-keyword {
  color: inherit;
  font-weight: bold;
}

.code-tag {
  color: #000091;
  background-color: inherit;
}

.breadcrumbs {
    background-color: #f0f0f0;
 	border-color: #3c78b5;
	border-width: 1px 0px 1px 0px;
	border-style: solid;
    font-size: 11px;
    padding: 3px 0px 3px 0px;
}

.navmenu {
    border: 1px solid #ccc;
}

.menuheading {
    font-weight: bold;
    background-color: #f0f0f0;
 	border-bottom: 1px solid #3c78b5;
	padding: 4px 4px 2px 4px;
}

.menuitems {
	padding: 4px 4px 20px 4px;
}

.rightpanel {
    border-left: 1px solid #ccc;
    border-bottom: 1px solid #ccc;
}

#helpheading {
    text-align: left;
    font-weight: bold;
    background-color: #D0D9BD;
 	border-bottom: 1px solid #3c78b5;
	padding: 4px 4px 4px 4px;
	margin: 0px;
}
#helpcontent {
	padding: 4px 4px 4px 4px;
    background-color: #f5f7f1;
}
.helptab-unselected {
    font-weight: bold;
	padding: 5px;
    background-color: #f5f7f1;
}
.helptab-selected {
    font-weight: bold;
    background-color: #D0D9BD;
	padding: 5px;
}
.helptabs {
    margin: 0px;
    background-color: #f5f7f1;
	padding: 5px;
}
.infopanel-heading {
    font-weight: bold;
	padding: 4px 0px 2px 0px;
}

.pagebody {
}

.pageheader {
	padding: 5px 5px 5px 0px;
 	border-bottom: 1px solid #3c78b5;
}

.pagetitle {
	font-size: 22px;
	font-weight: bold;
	font-family: Arial, sans-serif;
	color: #003366;
}

.newpagetitle {
    color: #ccc !important;
}

.steptitle {
	font-size: 18px;
	font-weight: bold;
	font-family: Arial, sans-serif;
	color: #003366;
	margin-bottom: 7px;
}

.substeptitle {
    font-size: 12px;
    font-weight: bold;
    font-family: Arial, sans-serif;
    color: #003366;
    margin: 2px 4px 4px 4px;
    padding: 2px 4px 1px 4px;
}

.stepdesc {
    font-family: Verdana, arial, sans-serif;
	font-size: 11px;
	line-height: 16px;
	font-weight: normal;
    color: #666666;
    margin-top: 7px;
    margin-bottom: 7px;
}

.steplabel {
    font-weight: bold;
    margin-right: 4px;
    color: black;
    float: left;
    width: 15%;
    text-align: right;
}

.stepfield {
    background: #f0f0f0;
    padding: 5px;
}

.submitButtons{
    margin-top:5px;
    text-align:right;
}

.formtitle {
	font-size: 12px;
	font-weight: bold;
	font-family: Arial, sans-serif;
	color: #003366;
}

.sectionbottom {
    border-bottom: 1px solid #3c78b5;
}

.topRow {
    border-top: 2px solid #3c78b5;
}

.tabletitle {
	font-size: 14px;
	font-weight: bold;
	font-family: Arial, sans-serif;
    padding: 3px 0px 2px 0px;
    margin: 8px 4px 2px 0px;
	color: #003366;
	border-bottom: 2px solid #3c78b5;
}
.pagesubheading {
    color: #666666;
    font-size: 10px;
    padding: 0px 0px 5px 0px;
}

HR {
	color: 3c78b5;
	height: 1;
}

A:link, A:visited, A:active, A:hover {
	color: #003366;
}

h1 A:link, h1 A:visited, h1 A:active {
	text-decoration: none;
}

h1 A:hover {
    border-bottom: 1px dotted #003366;
}

.wiki-content > :first-child, .commentblock > :first-child {
    margin-top: 3px;
}

.logocell {
    padding: 10px;
}

input {
	font-family: verdana, geneva, arial, sans-serif;
	font-size: 11px;
	color: #000000;
}

textarea, textarea.editor {
	font-family: verdana, geneva, arial, sans-serif;
	font-size: 11px;
	color: #333333;
}

/* use logoSpaceLink instead.
.spacenametitle {
	font: 21px/31px Impact, Arial, Helvetica;
    font-weight: 100;
    color: #999999;
	margin: 0px;
}
.spacenametitle img {
  margin: 0 0 -4px 0;
}
.spacenametitle a {
    text-decoration: none;
    color: #999999;
}
.spacenametitle a:visited {
    text-decoration: none;
    color: #999999;
}*/

.spacenametitle-printable {
	font: 20px/25px Impact, Arial, Helvetica;
    font-weight: 100;
    color: #999999;
	margin: 0px;
}
.spacenametitle-printable a {
    text-decoration: none;
    color: #999999;
}
.spacenametitle-printable a:visited {
    text-decoration: none;
    color: #999999;
}

.blogDate {
	font-weight: bold;
	text-decoration: none;
	color: black;
}

.blogSurtitle {
    background: #f0f0f0;
 	border: 1px solid #ddd;
	padding: 3px;
	margin: 1px 1px 10px 1px;
}

.blogHeading {
    font-size: 20px;
    line-height: normal;
    font-weight: bold;
    padding: 0px;
    margin: 0px;
}

.blogHeading a {
   text-decoration: none;
   color: black;
}

.endsection {
	align: right;
	color: #666666;
	margin-top: 10px;
}
.endsectionleftnav {
	align: right;
	color: #666666;
	margin-top: 10px;
}

h1 {
	font-size: 24px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	color: #003366;
 	border-bottom: 1px solid #3c78b5;
	padding: 2px;
	margin: 36px 0px 4px 0px;
}

h2 {
	font-size: 18px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
 	border-bottom: 1px solid #3c78b5;
	padding: 2px;
	margin: 27px 0px 4px 0px;
}

h3 {
	font-size: 14px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	padding: 2px;
	margin: 21px 0px 4px 0px;
}

h4 {
	font-size: 12px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	padding: 2px;
	margin: 18px 0px 4px 0px;
}

h4.search {
	font-size: 12px;
	line-height: normal;
	font-weight: normal;
	background-color: #f0f0f0;
	padding: 4px;
	margin: 18px 0px 4px 0px;
}

h5 {
	font-size: 10px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	padding: 2px;
	margin: 14px 0px 4px 0px;
}

h6 {
	font-size: 8px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	padding: 2px;
	margin: 14px 0px 4px 0px;
}

.smallfont {
    font-size: 10px;
}
.descfont {
    font-size: 10px;
    color: #666666;
}
.smallerfont {
    font-size: 9px;
}
.smalltext {
    color: #666666;
    font-size: 10px;
}
.smalltext a {
    color: #666666;
}
.smalltext-blue {
    color: #3c78b5;
    font-size: 10px;
}
.surtitle {
    margin-left: 1px;
    margin-bottom: 5px;
    font-size: 14px;
    color: #666666;
}

/* css hack found here:  http://www.fo3nix.pwp.blueyonder.co.uk/tutorials/css/hacks/ */
.navItemOver { font-size: 10px; font-weight: bold; color: #ffffff; background-color: #003366; cursor: hand; voice-family: '\'}\''; voice-family:inherit; cursor: pointer;}
.navItemOver a { color: #ffffff; background-color:#003366; text-decoration: none; }
.navItemOver a:visited { color: #ffffff; background-color:#003366; text-decoration: none; }
.navItemOver a:hover { color: #ffffff; background-color:#003366; text-decoration: none; }
.navItem { font-size: 10px; font-weight: bold; color: #ffffff; background-color: #3c78b5; }
.navItem a { color: #ffffff; text-decoration: none; }
.navItem a:hover { color: #ffffff; text-decoration: none; }
.navItem a:visited { color: #ffffff; text-decoration: none; }

div.padded { padding: 4px; }
div.thickPadded { padding: 10px; }
h3.macrolibrariestitle {
    margin: 0px 0px 0px 0px;
}

div.centered { text-align: center; margin: 10px; }
div.centered table {margin: 0px auto; text-align: left; }

.tableview table {
    margin: 0;
}

.tableview th {
    text-align: left;
    color: #003366;
    font-size: 12px;
    padding: 5px 0px 0px 5px;
    border-bottom: 2px solid #3c78b5;
}
.tableview td {
    text-align: left;
    border-color: #ccc;
    border-width: 0px 0px 1px 0px;
    border-style: solid;
    margin: 0;
    padding: 4px 10px 4px 5px;
}

.grid {
    margin: 2px 0px 5px 0px;
    border-collapse: collapse;
}
.grid th  {
    border: 1px solid #ccc;
    padding: 2px 4px 2px 4px;
    background: #f0f0f0;
    text-align: center;
}
.grid td  {
    border: 1px solid #ccc;
    padding: 3px 4px 3px 4px;
}
.gridHover {
	background-color: #f9f9f9;
}

td.infocell {
    background-color: #f0f0f0;
}
.label {
	font-weight: bold;
	color: #003366;
}

label {
	font-weight: bold;
	color: #003366;
}

.error {
	background-color: #fcc;
}

.errorBox {
	background-color: #fcc;
    border: 1px solid #c00;
    padding: 5px;
    margin: 5px;
}

.errorMessage {
	color: #c00;
}

.success {
	background-color: #dfd;
}

.successBox {
	background-color: #dfd;
    border: 1px solid #090;
    padding: 5px;
    margin-top:5px;
    margin-bottom:5px;
}

blockquote {
	padding-left: 10px;
	padding-right: 10px;
	margin-left: 5px;
	margin-right: 0px;
	border-left: 1px solid #3c78b5;
}

table.confluenceTable
{
    margin: 5px;
    border-collapse: collapse;
}

/* Added as a temporary fix for CONF-4223. The table elements appear to be inheriting the border: none attribute from the sectionMacro class */
table.confluenceTable td.confluenceTd
{
    border-width: 1px;
    border-style: solid;
    border-color: #ccc;
    padding: 3px 4px 3px 4px;
}

/* Added as a temporary fix for CONF-4223. The table elements appear to be inheriting the border: none attribute from the sectionMacro class */
table.confluenceTable th.confluenceTh
{
    border-width: 1px;
    border-style: solid;
    border-color: #ccc;
    padding: 3px 4px 3px 4px;
    background-color: #f0f0f0;
    text-align: center;
}

td.confluenceTd
{
    border-width: 1px;
    border-style: solid;
    border-color: #ccc;
    padding: 3px 4px 3px 4px;
}

th.confluenceTh
{
    border-width: 1px;
    border-style: solid;
    border-color: #ccc;
    padding: 3px 4px 3px 4px;
    background-color: #f0f0f0;
    text-align: center;
}

DIV.small {
	font-size: 9px;
}

H1.pagename {
	margin-top: 0px;
}

IMG.inline  {}

.loginform {
    margin: 5px;
    border: 1px solid #ccc;
}

/* The text how the "This is a preview" comment should be shown. */
.previewnote { text-align: center;
                font-size: 11px;
                    color: red; }

/* How the preview content should be shown */
.previewcontent { background: #E0E0E0; }

/* How the system messages should be shown (DisplayMessage.jsp) */
.messagecontent { background: #E0E0E0; }

/* How the "This page has been modified..." -comment should be shown. */
.conflictnote { }

.createlink {
    color: maroon;
}
a.createlink {
    color: maroon;
}
.templateparameter {
    font-size: 9px;
    color: darkblue;
}

.diffadded {
    background: #ddffdd;
    padding: 1px 1px 1px 4px;
	border-left: 4px solid darkgreen;
}
.diffdeleted {
    color: #999;
    background: #ffdddd;
    padding: 1px 1px 1px 4px;
	border-left: 4px solid darkred;
}
.diffnochange {
    padding: 1px 1px 1px 4px;
	border-left: 4px solid lightgrey;
}
.differror {
    background: brown;
}
.diff {
    font-family: lucida console, courier new, fixed-width;
	font-size: 12px;
	line-height: 14px;
}
.diffaddedchars {
    background-color:#99ff99;
    font-weight:bolder;
}
.diffremovedchars {
    background-color:#ff9999;
    text-decoration: line-through;
    font-weight:bolder;
}

.greybackground {
    background: #f0f0f0
}

.greybox {
 	border: 1px solid #ddd;
	padding: 3px;
	margin: 1px 1px 10px 1px;
}

.borderedGreyBox {
    border: 1px solid #cccccc;
    background-color: #f0f0f0;
    padding: 10px;
}

.greyboxfilled {
 	border: 1px solid #ddd;
    background: #f0f0f0;
    padding: 3px;
	margin: 1px 1px 10px 1px;
}

.navBackgroundBox {
    padding: 5px 5px 5px 5px;
    font-size: 22px;
	font-weight: bold;
	font-family: Arial, sans-serif;
	color: white;
    background: #3c78b5;
    text-decoration: none;
}

.previewBoxTop {
	background-color: #f0f0f0;
    border-width: 1px 1px 0px 1px;
    border-style: solid;
    border-color: #3c78b5;
    padding: 5px;
    margin: 5px 0px 0px 0px;
    text-align: center;
}
.previewContent {
    background-color: #fff;
 	border-color: #3c78b5;
	border-width: 0px 1px 0px 1px;
	border-style: solid;
	padding: 10px;
	margin: 0px;
}
.previewBoxBottom {
	background-color: #f0f0f0;
    border-width: 0px 1px 1px 1px;
    border-style: solid;
    border-color: #3c78b5;
    padding: 5px;
    margin: 0px 0px 5px 0px;
    text-align: center;
}

.functionbox {
    background-color: #f0f0f0;
 	border: 1px solid #3c78b5;
	padding: 3px;
	margin: 1px 1px 10px 1px;
}

.functionbox-greyborder {
    background-color: #f0f0f0;
 	border: 1px solid #ddd;
	padding: 3px;
	margin: 1px 1px 10px 1px;
}

.search-highlight {
    background-color: #ffffcc;
}

/* normal (white) background */
.rowNormal {
    background-color: #ffffff;
 }

/* alternate (pale yellow) background */
.rowAlternate {
    background-color: #f7f7f7;
}

/* used in the list attachments table */
.rowAlternateNoBottomColor {
    background-color: #f7f7f7;
}

.rowAlternateNoBottomNoColor {
}

.rowAlternateNoBottomColor td {
    border-bottom: 0px;
}

.rowAlternateNoBottomNoColor td {
    border-bottom: 0px;
}

/* row highlight (grey) background */
.rowHighlight {
    background-color: #f0f0f0;

}

TD.greenbar {FONT-SIZE: 2px; BACKGROUND: #00df00; BORDER: 1px solid #9c9c9c; PADDING: 0px; }
TD.redbar {FONT-SIZE: 2px; BACKGROUND: #df0000; BORDER: 1px solid #9c9c9c; PADDING: 0px; }
TD.darkredbar {FONT-SIZE: 2px; BACKGROUND: #af0000; BORDER: 1px solid #9c9c9c; PADDING: 0px; }

TR.testpassed {FONT-SIZE: 2px; BACKGROUND: #ddffdd; PADDING: 0px; }
TR.testfailed {FONT-SIZE: 2px; BACKGROUND: #ffdddd; PADDING: 0px; }

.toolbar  {
    margin: 0px;
    border-collapse: collapse;
}

.toolbar td  {
    border: 1px solid #ccc;
    padding: 2px 2px 2px 2px;
    color: #ccc;
}

td.noformatting {
    border-width: 0px;
    border-style: none;
    text-align: center;
	padding: 0px;
}

.commentblock {
    margin: 12px 0 12px 0;
}

/*
 * Divs displaying the license information, if necessary.
 */
.license-eval, .license-none, .license-nonprofit {
    border-top: 1px solid #bbbbbb;
    text-align: center;
    font-size: 10px;
    font-family: Verdana, Arial, Helvetica, sans-serif;
}

.license-eval, .license-none {
    background-color: #ffcccc;
}

.license-eval b, .license-none b {
    color: #990000
}

.license-nonprofit {
    background-color: #ffffff;
}

/*
 * The shadow at the bottom of the page between the main content and the
 * "powered by" section.
 */
.bottomshadow {
    height: 12px;
    background-image: url("$req.contextPath/images/border/border_bottom.gif");
    background-repeat: repeat-x;
}

/*
 * Styling of the operations box
 */
.navmenu .operations li, .navmenu .operations ul {
    list-style: none;
    margin-left: 0;
    padding-left: 0;
}

.navmenu .operations ul {
    margin-bottom: 9px;
}

.navmenu .label {
    font-weight: inherit;
}

/*
 * Styling of ops as a toolbar
 */
.toolbar div {
    display: none;
}

.toolbar .label {
    display: none;
}

.toolbar .operations {
    display: block;
}

.toolbar .operations ul {
    display: inline;
    list-style: none;
    margin-left: 10px;
    padding-left: 0;
}

.toolbar .operations li {
    list-style: none;
    display: inline;
}

/* list page navigational tabs */
#foldertab {
padding: 3px 0px 3px 8px;
margin-left: 0;
border-bottom: 1px solid #3c78b5;
font: bold 11px Verdana, sans-serif;
}

#foldertab li {
list-style: none;
margin: 0;
display: inline;
}

#foldertab li a {
padding: 3px 0.5em;
margin-left: 3px;
border: 1px solid #3c78b5;
border-bottom: none;
background: #3c78b5;
text-decoration: none;
}

#foldertab li a:link { color: #ffffff; }
#foldertab li a:visited { color: #ffffff; }

#foldertab li a:hover {
color: #ffffff;
background: #003366;
border-color: #003366;
}

#foldertab li a.current {
background: white;
border-bottom: 1px solid white;
color: black;
}

#foldertab li a.current:link { color: black; }
#foldertab li a.current:visited { color: black; }
#foldertab li a.current:hover {
background: white;
border-bottom: 1px solid white;
color: black;
}

/* alphabet list */
ul#squaretab {
margin-left: 0;
padding-left: 0;
white-space: nowrap;
font: bold 8px Verdana, sans-serif;
}

#squaretab li {
display: inline;
list-style-type: none;
}

#squaretab a {
padding: 2px 6px;
border: 1px solid #3c78b5;
}

#squaretab a:link, #squaretab a:visited {
color: #fff;
background-color: #3c78b5;
text-decoration: none;
}

#squaretab a:hover {
color: #ffffff;
background-color: #003366;
border-color: #003366;
text-decoration: none;
}

#squaretab li a#current {
background: white;
color: black;
}

.blogcalendar * {
    font-family:verdana, arial, sans-serif;
    font-size:x-small;
    font-weight:normal;
    line-height:140%;
    padding:2px;
}


table.blogcalendar {
    border: 1px solid #3c78b5;
}

.blogcalendar th.calendarhead, a.calendarhead {
    font-size:x-small;
    font-weight:bold;
    padding:2px;
    text-transform:uppercase;
    background-color: #3c78b5;
    color: #ffffff;
    letter-spacing: .3em;
    text-transform: uppercase;
}

.calendarhead:visited {color: white;}
.calendarhead:active {color: white;}
.calendarhead:hover {color: white;}

.blogcalendar th {
    font-size:x-small;
    font-weight:bold;
    padding:2px;
    background-color:#f0f0f0;
}

.blogcalendar td {
    font-size:x-small;
    font-weight:normal;
}

.searchGroup { padding: 0 0 10px 0; background: #f0f0f0; }
.searchGroupHeading { font-size: 10px; font-weight: bold; color: #ffffff; background-color: #3c78b5; padding: 2px 4px 1px 4px; }
.searchItem { padding: 1px 4px 1px 4px; }
.searchItemSelected { padding: 1px 4px 1px 4px; font-weight: bold; background: #ddd; }

/* permissions page styles */
.permissionHeading {
    border-bottom: #bbb; border-width: 0 0 1px 0; border-style: solid; font-size: 16px; text-align: left;
}
.permissionTab {
    border-width: 0 0 0 1px; border-style: solid; background: #3c78b5; color: #ffffff; font-size: 10px;
}
.permissionSuperTab {
    border-width: 0 0 0 1px; border-style: solid; background: #003366; color: #ffffff;
}
.permissionCell {
    border-left: #bbb; border-width: 0 0 0 1px; border-style: solid;
}

/* warning panel */
.warningPanel { background: #FFFFCE; border:#F0C000 1px solid; padding: 8px; margin: 10px; }
/* alert panel */
.alertPanel { background: #FFCCCC; border:#C00 1px solid; padding: 8px; margin: 10px; }
/* info panel */
.infoPanel { background: #D8E4F1; border:#3c78b5 1px solid; padding: 8px; margin: 10px; }

/* side menu highlighting (e.g. space content screen) */
.optionPadded { padding: 2px; }
.optionSelected { background-color: #ffffcc; padding: 2px; border: 1px solid #ddd; margin: -1px; }
.optionSelected a { font-weight: bold; text-decoration: none; color: black; }

/* information macros */
.noteMacro { border-style: solid; border-width: 1px; border-color: #F0C000; background-color: #FFFFCE; text-align:left; margin-top: 5px; margin-bottom: 5px}
.warningMacro { border-style: solid; border-width: 1px; border-color: #c00; background-color: #fcc; text-align:left; margin-top: 5px; margin-bottom: 5px}
.infoMacro { border-style: solid; border-width: 1px; border-color: #3c78b5; background-color: #D8E4F1; text-align:left; margin-top: 5px; margin-bottom: 5px}
.tipMacro { border-style: solid; border-width: 1px; border-color: #090; background-color: #dfd; text-align:left; margin-top: 5px; margin-bottom: 5px}
.informationMacroPadding { padding: 5px 0 0 5px; }

table.infoMacro td, table.warningMacro td, table.tipMacro td, table.noteMacro td, table.sectionMacro td {
    border: none;
}

table.sectionMacroWithBorder td.columnMacro { border-style: dashed; border-width: 1px; border-color: #cccccc;}

.pagecontent
{
    padding: 10px;
    text-align: left;
}

/* styles for links in the top bar */
.topBarDiv a:link {color: #ffffff;}
.topBarDiv a:visited {color: #ffffff;}
.topBarDiv a:active {color: #ffffff;}
.topBarDiv a:hover {color: #ffffff;}
.topBarDiv {color: #ffffff;}

.topBar {
    background-color: #003366;
}


/* styles for extended operations */
.greyLinks a:link {color: #666666; text-decoration:underline;}
.greyLinks a:visited {color: #666666; text-decoration:underline;}
.greyLinks a:active {color: #666666; text-decoration:underline;}
.greyLinks a:hover {color: #666666; text-decoration:underline;}
.greyLinks {color: #666666; display:block; padding: 10px}

.logoSpaceLink {color: #999999; text-decoration: none}
.logoSpaceLink a:link {color: #999999; text-decoration: none}
.logoSpaceLink a:visited {color: #999999; text-decoration: none}
.logoSpaceLink a:active {color: #999999; text-decoration: none}
.logoSpaceLink a:hover {color: #003366; text-decoration: none}

/* basic panel (basicpanel.vmd) style */
.basicPanelContainer {border: 1px solid #3c78b5; margin-top: 2px; margin-bottom: 8px; width: 100%}
.basicPanelTitle {padding: 5px; margin: 0px; background-color: #f0f0f0; color: black; font-weight: bold;}
.basicPanelBody {padding: 5px; margin: 0px}

.separatorLinks a:link {color: white}
.separatorLinks a:visited {color: white}
.separatorLinks a:active {color: white}

.greynavbar {background-color: #f0f0f0; border-top: 1px solid #3c78b5; margin-top: 2px}

div.headerField {
    float: left;
    width: auto;
    height: 100%;
}

.headerFloat {
    margin-left: auto;
    width: 50%;
}

.headerFloatLeft {
    float: left;
    margin-right: 20px;
    margin-bottom: 10px;
}

#headerRow {
    padding: 10px;
}

div.license-personal {
   background-color: #003366;
   color: #ffffff;
}

div.license-personal a {
   color: #ffffff;
}

.greyFormBox {
    border: 1px solid #cccccc;
    padding: 5px;
}

/* IE automatically adds a margin before and after form tags. Use this style to remove that */
.marginlessForm {
    margin: 0px;
}

.openPageHighlight {
    background-color: #ffffcc;
    padding: 2px;
    border: 1px solid #ddd;
}

.editPageInsertLinks, .editPageInsertLinks a
{
    color: #666666;
    font-weight: bold;
    font-size: 10px;
}

/* Style for label heatmap. */
.top10 a {
    font-weight: bold;
    font-size: 2em;
    color: #003366;
}
.top25 a {
    font-weight: bold;
    font-size: 1.6em;
    color: #003366;
}
.top50 a {
    font-size: 1.4em;
    color: #003366;
}
.top100 a {
    font-size: 1.2em;
    color: #003366;
}

.heatmap {
    list-style:none;
    width: 95%;
    margin: 0px auto;
}

.heatmap a {
    text-decoration:none;
}

.heatmap a:hover {
    text-decoration:underline;
}

.heatmap li {
    display: inline;
}

.minitab {
padding: 3px 0px 3px 8px;
margin-left: 0;
margin-top: 1px;
margin-bottom: 0px;
border-bottom: 1px solid #3c78b5;
font: bold 9px Verdana, sans-serif;
text-decoration: none;
float:none;
}
.selectedminitab {
padding: 3px 0.5em;
margin-left: 3px;
margin-top: 1px;
border: 1px solid #3c78b5;
background: white;
border-bottom: 1px solid white;
color: #000000;
text-decoration: none;
}
.unselectedminitab {
padding: 3px 0.5em;
margin-left: 3px;
margin-top: 1px;
border: 1px solid #3c78b5;
border-bottom: none;
background: #3c78b5;
color: #ffffff;
text-decoration: none;
}

a.unselectedminitab:hover {
color: #ffffff;
background: #003366;
border-color: #003366;
}

a.unselectedminitab:link { color: white; }
a.unselectedminitab:visited { color: white; }

a.selectedminitab:link { color: black; }
a.selectedminitab:visited { color: black; }

.linkerror { background-color: #fcc;}

a.labelOperationLink:link {text-decoration: underline}
a.labelOperationLink:active {text-decoration: underline}
a.labelOperationLink:visited {text-decoration: underline}
a.labelOperationLink:hover {text-decoration: underline}

a.newLabel:link {background-color: #ddffdd}
a.newLabel:active {background-color: #ddffdd}
a.newLabel:visited {background-color: #ddffdd}
a.newLabel:hover {background-color: #ddffdd}

ul.square {list-style-type: square}

.inline-control-link {
    background: #ffc;
    font-size: 9px;
    color: #666;
    padding: 2px;
    text-transform: uppercase;
    text-decoration: none;
}


.inline-control-link a:link {text-decoration: none}
.inline-control-link a:active {text-decoration: none}
.inline-control-link a:visited {text-decoration: none}
.inline-control-link a:hover {text-decoration: none}

.inline-control-link {
    background: #ffc;
    font-size: 9px;
    color: #666;
    padding: 2px;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
}

div.auto_complete {
    width: 350px;
    background: #fff;
}
div.auto_complete ul {
    border: 1px solid #888;
    margin: 0;
    padding: 0;
    width: 100%;
    list-style-type: none;
}
div.auto_complete ul li {
    margin: 0;
    padding: 3px;
}
div.auto_complete ul li.selected {
    background-color: #ffb;
}
div.auto_complete ul strong.highlight {
    color: #800;
    margin: 0;
    padding: 0;
}

/******* Edit Page Styles *******/
.toogleFormDiv{
    border:1px solid #A7A6AA;
    background-color:white;
    padding:5px;
    margin-top: 5px;
}

.toogleInfoDiv{
    border:1px solid #A7A6AA;
    background-color:white;
    display:none;
    padding:5px;
    margin-top: 10px;
}

.inputSection{
    margin-bottom:20px;
}

#editBox{
   border:1px solid lightgray;
   background-color:#F0F0F0;
}

/******* Left Navigation Theme Styles ********/
.leftnav li a {
    text-decoration:none;
    color:white;
    margin:0px;
    display:block;
    padding:2px;
    padding-left:5px;
    background-color: #3c78b5;
    border-top:1px solid #3c78b5;
}

.leftnav li a:active {color:white;}
.leftnav li a:visited {color:white;}
.leftnav li a:hover {background-color: #003366; color:white;}

/* Added by Shaun during i18n */
.replaced
{
    background-color: #33CC66;
}

.topPadding
{
    margin-top: 20px;
}

/* new form style */
.form-block {
    padding: 6px;
}
.form-error-block {
    padding: 6px;
    background: #fcc;
    border-top: #f0f0f0 1px solid;
    border-bottom: #f0f0f0 1px solid;
    margin-bottom: 6px;
    padding: 0 12px 0 12px;
}
.form-element-large {
    font-size: 16px;
    font-weight: bold;
    font-family: Arial, sans-serif;
    color: #003366;
}

.form-element-small {
    font-size: 12px;
    font-weight: bold;
    font-family: Arial, sans-serif;
    color: #003366;
}

.form-header {
    background: lightyellow;
    border-top: #f0f0f0 1px solid;
    border-bottom: #f0f0f0 1px solid;
    margin-bottom: 6px;
    padding: 0 12px 0 12px;
}
.form-header p, .form-block p, .form-error-block p {
    line-height: normal;
    margin: 12px 0 12px 0;
}
.form-example {
    color: #888;
    font-size: 11px;
}
.form-divider {
    border-bottom: #ccc 1px solid;
    margin-bottom: 6px;
}
.form-buttons {
    margin-top: 6px;
    border-top: #ccc 1px solid;
    border-bottom: #ccc 1px solid;
    background: #f0f0f0;
    padding: 10px;
    text-align: center;
}
.form-buttons input {
    width: 100px;
}
.form-block .error {
    padding: 6px;
    margin-bottom: 6px;
}
    -->
    </style>
</head>
<body>

<div id="PageContent">
<table class="pagecontent" border="0" cellpadding="0" cellspacing="0" width="100%"><tr>
<td valign="top" class="pagebody">

    <div class="pageheader">
        <span class="pagetitle">
            Page Edited :
            <a href="http://cwiki.apache.org/confluence/display/DIRxSRVx11">DIRxSRVx11</a> :
            <a href="http://cwiki.apache.org/confluence/display/DIRxSRVx11/Mitosis+Development+Guide">Mitosis Development Guide</a>
        </span>
    </div>

     <p>
        <a href="http://cwiki.apache.org/confluence/display/DIRxSRVx11/Mitosis+Development+Guide">Mitosis Development Guide</a>
        has been edited by             <a href="http://cwiki.apache.org/confluence/display/~elecharny">Emmanuel Lécharny</a>
            <span class="smallfont">(Jan 11, 2009)</span>.
     </p>
    
     <p>
                 <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=106600&originalVersion=9&revisedVersion=10">(View changes)</a>
     </p>

    <span class="label">Content:</span><br/>
    <div class="greybox wiki-content"><h1><a name="MitosisDevelopmentGuide-Tableofcontent"></a>Table of content</h1>
<div>
<ul>
  <li><a href='#MitosisDevelopmentGuide-Tableofcontent'>Table of content</a></li>
  <li><a href='#MitosisDevelopmentGuide-Glossary'>Glossary</a></li>
  <li><a href='#MitosisDevelopmentGuide-Replicationanalysis'>Replication analysis</a>
<ul>
  <li><a href='#MitosisDevelopmentGuide-Baseoperations'>Base operations</a></li>
</ul></li>
  <li><a href='#MitosisDevelopmentGuide-Datastructure'>Data structure</a>
<ul>
  <li><a href='#MitosisDevelopmentGuide-CSNandUUID'>CSN and UUID</a>
<ul>
  <li><a href='#MitosisDevelopmentGuide-CSNstructure'>CSN structure</a></li>
  <li><a href='#MitosisDevelopmentGuide-UUIDstructure'>UUID structure</a></li>
</ul></li>
</ul></li>
  <li><a href='#MitosisDevelopmentGuide-Network'>Network</a>
<ul>
  <li><a href='#MitosisDevelopmentGuide-Networkinitialization'>Network initialization</a></li>
</ul></li>
  <li><a href='#MitosisDevelopmentGuide-Store'>Store</a>
<ul>
  <li><a href='#MitosisDevelopmentGuide-Databasestructure'>Database structure</a>
<ul>
  <li><a href='#MitosisDevelopmentGuide-REPLICATIONMETADATAstructure'>REPLICATION_METADATA structure</a></li>
  <li><a href='#MitosisDevelopmentGuide-REPLICATIONUUIDstructure'>REPLICATION_UUID structure</a></li>
  <li><a href='#MitosisDevelopmentGuide-REPLICATIONLOGstructure'>REPLICATION_LOG structure</a></li>
</ul></li>
  <li><a href='#MitosisDevelopmentGuide-Operationstorage'>Operation storage</a></li>
</ul></li>
  <li><a href='#MitosisDevelopmentGuide-Configuration'>Configuration</a></li>
  <li><a href='#MitosisDevelopmentGuide-Thereplicationinterceptor'>The replication interceptor</a>
<ul>
  <li><a href='#MitosisDevelopmentGuide-Interceptorinitialization'>Interceptor initialization</a></li>
  <li><a href='#MitosisDevelopmentGuide-Operationsclasses'>Operations classes</a>
<ul>
  <li><a href='#MitosisDevelopmentGuide-Operations'>Operations</a>
<ul>
  <li><a href='#MitosisDevelopmentGuide-Addoperation'>Add operation</a></li>
  <li><a href='#MitosisDevelopmentGuide-Deleteoperation'>Delete operation</a></li>
</ul></li>
</ul></li>
</ul></li>
</ul></div>

<h1><a name="MitosisDevelopmentGuide-Glossary"></a>Glossary</h1>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Term </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> <b>CSN</b> </td>
<td class='confluenceTd'> <b>C</b>hange <b>S</b>equence <b>N</b>umber </td>
</tr>
<tr>
<td class='confluenceTd'> <b>MMR</b> </td>
<td class='confluenceTd'> <b>M</b>ulti-<b>M</b>aster <b>R</b>eplication </td>
</tr>
<tr>
<td class='confluenceTd'> <b>UUID</b> </td>
<td class='confluenceTd'> <b>U</b>niversally <b>U</b>nique <b>ID</b>entifier </td>
</tr>
</tbody></table>

<h1><a name="MitosisDevelopmentGuide-Replicationanalysis"></a>Replication analysis</h1>


<h2><a name="MitosisDevelopmentGuide-Baseoperations"></a>Base operations</h2>

<p>Replication is meant to transpose a modification done on one server into the associated servers. We should also insure that a modification done on an entry in more than one server does not lead to inconsistencies.</p>

<p>As the remote servers may not be available, due to network conditions, we also have to wait for the synchronization to be done before we can validate a full replication for an entry. For instance, if we delete an entry on server A, it can be deleted for real only when all the remote servers has confirmed that the deletion was successful.</p>

<h1><a name="MitosisDevelopmentGuide-Datastructure"></a>Data structure</h1>


<h2><a name="MitosisDevelopmentGuide-CSNandUUID"></a>CSN and UUID</h2>

<p>We will use two tags, stored within each entry, to manage the replication. The <b>CSN</b> (Change Sequence Number) stores when and where (which server) the entry was last modified. A replicated entry on 3 servers will have the same <b>CSN</b>. Before replication they may be different. The <b>UUID</b> (Universal Unique Identifier) is associated with an entry, and only one. So if we have an entry replicated on 3 servers, it will have one <b>CSN</b> (as the entry is at the same version for all servers) and only one <b>UUID</b> (as it's the same entry).  The <b>UUID</b> is not currently used.  The <b>CSN</b> stored in the entry is used to prevent older modifications overwriting newer ones.  Unfortunately this leads to inconsistent servers (see <span class="nobr"><a href="https://issues.apache.org/jira/browse/DIRSERVER-894" title="Visit page outside Confluence" rel="nofollow">DIRSERVER-894<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span>) - we need to check the CSN for each attribute instead.  Once this is fixed the <b>CSN</b> stored on each entry will no longer be used.</p>

<h3><a name="MitosisDevelopmentGuide-CSNstructure"></a>CSN structure</h3>

<p>A CSN is a composition of a timestamp, a replica ID and a operation sequence number. It's described in <span class="nobr"><a href="http://tools.ietf.org/html/draft-sermersheim-ldap-csn-02" title="Visit page outside Confluence" rel="nofollow">The LDAP Change Sequence Number<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span>. We have defined a simpler version, as the current RFC is still a draft, where we use a unique operationSequence instead of two integers (timeCount and changeCount) to disambiguate entries changed at the same time.</p>

<p>As the timestamp is computed using a <em>System.currentTimeMillis()</em> call, the accuracy is around 10 ms. We may have at hundreds of changes done in this interval. This is the reason we have a additional <em>operationSequence</em> number.</p>

<p>The <b>CSN</b> class structure is described by the following schema :</p>

<p><img src="/confluence/download/attachments/106600/CSN.png" align="absmiddle" border="0" /></p>

<p>Basically, from the user POV, a CSN syntax is <b>[timestamp:replicaId:operationSequence]</b></p>

<h3><a name="MitosisDevelopmentGuide-UUIDstructure"></a>UUID structure</h3>

<p>We use Java 5 UUID implementation, which is based on variant 2 of <span class="nobr"><a href="http://www.ietf.org/rfc/rfc4122.txt" title="Visit page outside Confluence" rel="nofollow">RFC 4122<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span></p>

<h1><a name="MitosisDevelopmentGuide-Network"></a>Network</h1>

<p>As Mitosis is a multi-master replication system, so each server has to be connected to the server it replicates with, and accept incoming connections from those servers.</p>

<p>We have two components :</p>
<ul>
	<li>an Acceptor, for incoming replication operations</li>
	<li>N connectors, one per connected server.</li>
</ul>


<p>The biggest problem we have is to connect to remote servers. As a starting server will have to reconnect to the remote servers, we will two problems :</p>
<ul>
	<li>if the remote server is also starting, but has not yet established is listener, we won't be able to establish the connection</li>
	<li>if the servers are not time synchronized, we may not be able to correctly replicate a time based operation.</li>
</ul>


<h2><a name="MitosisDevelopmentGuide-Networkinitialization"></a>Network initialization</h2>

<p>When a server starts, after having initialized the internal LDAP service, it has to start the network layer. The following algorithm is used :</p>
<div class="code"><div class="codeContent">
<pre class="code-java">start the Acceptor

set a retry interval to 2 seconds

until each remote server is connected <span class="code-keyword">do</span>
  <span class="code-keyword">for</span> each not connected remote replica <span class="code-keyword">do</span>
    start a connector

    <span class="code-keyword">if</span> the connection is established
      remove it from the list of disconnected server
  done

  <span class="code-keyword">if</span> we have unconnected remote server
    <span class="code-object">double</span> the retry interval
  <span class="code-keyword">else</span>
    exit
done</pre>
</div></div>
<p>Basically, we try to connect to a remote server, and if we don't success, we wait for an increasing period of time before retrying. When we reach 60 seconds for this interval, we stop increasing the interval and simply try every minute.</p>

<p>Obviously, this is costly, and fragile, as a broken connection has to be detected and immediately restored, otherwise we can't replicate. Plus we don't manage scheduled downtime, as the server still tries to connect to the shutdown server even if it's on purpose.</p>

<p>Plus we have to store the pending operation until the connection is re-established.</p>
<table cellpadding='5' width='85%' cellspacing='8px' class='noteMacro' border="0" align='center'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>
<p>Another approach would be to rely on a asynchronous system (Messages) to handle the server to server communication. The biggest advantage would be to rely on an proven system to manage connection and retries, instead of coding our own system inside ADS, with all the burden it brings. ActiveMQ could be a good option.</p></td></tr></table>

<h1><a name="MitosisDevelopmentGuide-Store"></a>Store</h1>

<p>We use a Database to store pending operations.</p>

<h2><a name="MitosisDevelopmentGuide-Databasestructure"></a>Database structure</h2>

<p>We use 3 tables : <b>REPLICATION_METADATA</b>, <b>REPLICATION_UUID</b> and <b>REPLICATION_LOG</b>.</p>

<table cellpadding='5' width='85%' cellspacing='8px' class='noteMacro' border="0" align='center'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>
<p>The "REPLICATION_" prefix can be configured, for instance if one want to define more than one ADS locally. It would make more sense to use the replicaID instead of this prefix, though.</p></td></tr></table>

<h3><a name="MitosisDevelopmentGuide-REPLICATIONMETADATAstructure"></a>REPLICATION_METADATA structure</h3>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> field </th>
<th class='confluenceTh'> type </th>
<th class='confluenceTh'> Primary key </th>
<th class='confluenceTh'> description </th>
</tr>
<tr>
<td class='confluenceTd'> M_KEY </td>
<td class='confluenceTd'> VARCHAR(30) NOT NULL </td>
<td class='confluenceTd'> Yes </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> M_VALUE </td>
<td class='confluenceTd'> VARCHAR(100) NOT NULL </td>
<td class='confluenceTd'> No </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
</tbody></table>

<h3><a name="MitosisDevelopmentGuide-REPLICATIONUUIDstructure"></a>REPLICATION_UUID structure</h3>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> field </th>
<th class='confluenceTh'> type </th>
<th class='confluenceTh'> Primary key </th>
<th class='confluenceTh'> description </th>
</tr>
<tr>
<td class='confluenceTd'> UUID </td>
<td class='confluenceTd'> CHAR(36) NOT NULL </td>
<td class='confluenceTd'> Yes </td>
<td class='confluenceTd'> The entry UUID </td>
</tr>
<tr>
<td class='confluenceTd'> DN </td>
<td class='confluenceTd'> CLOB NOT NULL </td>
<td class='confluenceTd'> No </td>
<td class='confluenceTd'> The entry DN </td>
</tr>
</tbody></table>

<h3><a name="MitosisDevelopmentGuide-REPLICATIONLOGstructure"></a>REPLICATION_LOG structure</h3>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> field </th>
<th class='confluenceTh'> type </th>
<th class='confluenceTh'> Primary key </th>
<th class='confluenceTh'> description </th>
</tr>
<tr>
<td class='confluenceTd'> CSN_REPLICA_ID </td>
<td class='confluenceTd'> VARCHAR(16) NOT NULL </td>
<td class='confluenceTd'> Yes </td>
<td class='confluenceTd'> The replica ID </td>
</tr>
<tr>
<td class='confluenceTd'> CSN_TIMESTAMP </td>
<td class='confluenceTd'> BIGINT NOT NULL </td>
<td class='confluenceTd'> Yes </td>
<td class='confluenceTd'> The Timestamp </td>
</tr>
<tr>
<td class='confluenceTd'> CSN_OP_SEQ </td>
<td class='confluenceTd'> INTEGER NOT NULL </td>
<td class='confluenceTd'> Yes </td>
<td class='confluenceTd'> The op sequence </td>
</tr>
<tr>
<td class='confluenceTd'> OPERATION </td>
<td class='confluenceTd'> BLOB NOT NULL </td>
<td class='confluenceTd'> no </td>
<td class='confluenceTd'> The replication operation </td>
</tr>
</tbody></table>

<h2><a name="MitosisDevelopmentGuide-Operationstorage"></a>Operation storage</h2>

<p>Each operation is logged into the REPLICATION_LOG table. It has to be serialized first to be put into the OPERATION field. The CSN is spread in three columns for a better search.</p>

<p>The serialized Operation structure will depend on the operation. In any case, its a triplet &lt;OpType, CSN, [serialized op]&gt;, where the [serialized op] can be composite. For instance, we may have something like &lt;OpType, CSN, &lt;OpType, CSN, entry&gt; &lt;Optype, CSN, entry&gt;&gt; if we deal with a composite operation.</p>

<p>The AddEntry operation is serialized as &lt;OpType, CSN, Entry&gt;<br/>
The XXXAttribute operations are serialized as &lt;OpType, CSN, &lt;dn, id, attribute&gt;&gt;<br/>
The composite operations are serialized as &lt;OpType, CSN, list of serialized children&gt;</p>

<table cellpadding='5' width='85%' cellspacing='8px' class='noteMacro' border="0" align='center'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>
<p>The CSN is already a part of the entry for an Add operation, it's not necessary to serialize it.<br/>
The Id is already stored in the Attribute for every attribute operations, we can avoid serializing it.</p></td></tr></table>

<table cellpadding='5' width='85%' cellspacing='8px' class='noteMacro' border="0" align='center'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>
<p>We use a specific serialization, Java based, to store the operation. It would be way better to store a LDIF, assuming we always consider the CSN as a modified attribute.</p></td></tr></table>



<h1><a name="MitosisDevelopmentGuide-Configuration"></a>Configuration</h1>

<p>The replication system is a Multi-Master replication, ie, each server can update any server it is connected to. The way you tell a server to replicate to others is simple :</p>
<div class="code"><div class="codeContent">
<pre class="code-java">&lt;replicationInterceptor&gt;
      &lt;configuration&gt;
        &lt;replicationConfiguration logMaxAge=<span class="code-quote">"5"</span>
                                  replicaId=<span class="code-quote">"instance_a"</span>
                                  replicationInterval=<span class="code-quote">"2"</span>
                                  responseTimeout=<span class="code-quote">"10"</span>
                                  serverPort=<span class="code-quote">"10390"</span>&gt;
          &lt;s:property name=<span class="code-quote">"peerReplicas"</span>&gt;
            &lt;s:set&gt;
              &lt;s:value&gt;instance_b@localhost:1234&lt;/s:value&gt;
              &lt;s:value&gt;instance_c@localhost:1234&lt;/s:value&gt;
            &lt;/s:set&gt;
          &lt;/s:property&gt;
        &lt;/replicationConfiguration&gt;
      &lt;/configuration&gt;
    &lt;/replicationInterceptor&gt;</pre>
</div></div>
<p>Here, for the server <b>instance_a" we have associated two replicas : &#42;instance_b</b> and <b>instance_c</b>. Basically, you just give the list of remote server you want to be connected to.</p>

<h1><a name="MitosisDevelopmentGuide-Thereplicationinterceptor"></a>The replication interceptor</h1>

<p>The MITOSIS service is implemented as an interceptor in the current version (1.5.4). The following operations are handled :</p>
<ul>
	<li>add</li>
	<li>delete</li>
	<li>hasEntry</li>
	<li>list</li>
	<li>lookup</li>
	<li>modify</li>
	<li>move</li>
	<li>moveAndRename</li>
	<li>rename</li>
	<li>search</li>
</ul>


<p>The hasEntry, list, lookup and search operations are only handled to prevent tombstoned (deleted) entries being returned.</p>

<h2><a name="MitosisDevelopmentGuide-Interceptorinitialization"></a>Interceptor initialization</h2>

<p>When the interceptor is injected into the chain, its init() method is called, and it will initialize the full replication system. Here are the steps the init() method goes through :</p>
<ol>
	<li>Validate the replication configuration</li>
	<li>Initialize the store</li>
	<li>Start the CSNFactory</li>
	<li>Start the networking sub-system</li>
	<li>Purge the aged data from the store</li>
</ol>


<p>Then the service is ready to process new operations.</p>

<table cellpadding='5' width='85%' cellspacing='8px' class='warningMacro' border="0" align='center'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/forbidden.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>
<p>The purge of old data is not done atm unless the server is restarted. It has to be completed.</p></td></tr></table>

<h2><a name="MitosisDevelopmentGuide-Operationsclasses"></a>Operations classes</h2>

<p>We are using <b>Operation</b> objects to manage replications inside the interceptor. Here is the <b>Operation</b> classes hierarchy :</p>

<p><img src="/confluence/download/attachments/106600/replicationOperation.png" align="absmiddle" border="0" /></p>

<p>Each of the interceptor's method handling an entry modification will use one of those classes to store the resulting modification.</p>

<h3><a name="MitosisDevelopmentGuide-Operations"></a>Operations</h3>
<h4><a name="MitosisDevelopmentGuide-Addoperation"></a>Add operation</h4>

<p>It creates a <b>AddEntryOperation</b> object, with a ADD_ENTRY operation type (how useful is it, considering that we are already defined a specific class for such an operation ???), an entry and a CSN.</p>

<p>The newly created entry will contain two new AttributeType :</p>
<ul>
	<li>an <b>entryUUID</b> with a newly generated UUID</li>
	<li>an <b>entryDeleted</b> set to <b>FALSE</b></li>
</ul>


<p>If the added entry already exists in the current server, then we should consider that the entry can't be added.</p>
<table cellpadding='5' width='85%' cellspacing='8px' class='noteMacro' border="0" align='center'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>
<p>Currently, we check for more than the existence of the entry in the base. Either the entry is absent, and we can add it, or it's present, and we should discard the new entry, throwing an error.</p>

<p>Or another option is to consider that the entry has been created on more than one remote server, and then been created locally. We may have to replace the old entry by the new one, even if they are different. This is the current implementation.</p></td></tr></table>
<table cellpadding='5' width='85%' cellspacing='8px' class='noteMacro' border="0" align='center'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>
<p>What if the entry already exists, but with a pending 'deleted' state ? This has to be checked.</p></td></tr></table>
<table cellpadding='5' width='85%' cellspacing='8px' class='noteMacro' border="0" align='center'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>
<p>As we may receive a Add request from a remote server - per replication activation &#45;, we currently create so called <b>glue-entries</b>. There are necessary if we consider that an entry is added when the underlaying tree is absent. This can happen in a MMR scenario where those missing entries have not been received yet, but the leaves have been. </p></td></tr></table>

<h4><a name="MitosisDevelopmentGuide-Deleteoperation"></a>Delete operation</h4>

<p>It creates a <b>CompositeOperation</b> object, which contains a <b>ReplaceAttributeOperation</b>, as the entry is not deleted, but instead a <b>entryDeleted</b> AttributeType is added to the entry, and a <b>ReplaceAttributeOperation</b> containing the injection of a <b>entryCSN</b> AttributeType, with a newly created CSN.</p>

<p>So here are the operation content :</p>
<ul>
	<li>ReplaceAttributeOperation</li>
	<li><b>entryDeleted</b>, value <b>TRUE</b></li>
	<li>ReplaceAttributeOperation</li>
	<li><b>entryCSN</b>, with a new CSN
<table cellpadding='5' width='85%' cellspacing='8px' class='noteMacro' border="0" align='center'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>
<p>The delete operation should be a simple attribute Modification. Currently, two requests are sent to the backend (one for each added attribute), which is useless.</p></td></tr></table></li>
</ul>
</div>


</td></tr></table></div>
<p>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td height="12" background="http://cwiki.apache.org/confluence/images/border/border_bottom.gif"><img src="http://cwiki.apache.org/confluence/images/border/spacer.gif" width="1" height="1" border="0"/></td>
    </tr>
</table>

<div class="smalltext">
    Powered by
    <a href="http://www.atlassian.com/software/confluence/default.jsp?clicked=footer" class="smalltext">Atlassian Confluence</a>
    (Version: 2.2.9 Build:#527 Sep 07, 2006)
    -
    <a href="http://jira.atlassian.com/secure/BrowseProject.jspa?id=10470" class="smalltext">Bug/feature request</a><br/>
    <br>
    <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action">Unsubscribe or edit your notifications preferences</a>

</div>

</body>
</html>


Mime
View raw message