blob: 7533c18cbb7a60e13816b743ce8b2816d6a19738 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.3">
<title>Deployment Architecture</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
/* Remove comment around @import statement below when using as a custom stylesheet */
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
audio,canvas,video{display:inline-block}
audio:not([controls]){display:none;height:0}
[hidden],template{display:none}
script{display:none!important}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
body{margin:0}
a{background:transparent}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:bold}
dfn{font-style:italic}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
body{-webkit-font-smoothing:antialiased}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.center{margin-left:auto;margin-right:auto}
.spread{width:100%}
p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:none}
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ul.no-bullet{list-style:none}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
abbr{text-transform:none}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
blockquote cite:before{content:"\2014 \0020"}
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
table thead,table tfoot{background:#f7f8f7;font-weight:bold}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
body{tab-size:4}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}
.clearfix:after,.float-group:after{clear:both}
*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menu{color:rgba(0,0,0,.8)}
b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}
b.button:before{content:"[";padding:0 3px 0 2px}
b.button:after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}
#header:after,#content:after,#footnotes:after,#footer:after{clear:both}
#content{margin-top:1.25em}
#content:before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}
#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span:before{content:"\00a0\2013\00a0"}
#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark:before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber:after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media only screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}
@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
.sect1{padding-bottom:.625em}
@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}
.sect1+.sect1{border-top:1px solid #efefed}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}
.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}
table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}
.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}
@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.listingblock>.content{position:relative}
.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
.listingblock:hover code[data-lang]:before{display:block}
.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}
.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}
table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
table.pyhltable td.code{padding-left:.75em;padding-right:0}
pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}
pre.pygments .lineno{display:inline-block;margin-right:.25em}
table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}
.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}
.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}
.quoteblock .quoteblock blockquote:before{display:none}
.verseblock{margin:0 1em 1.25em 1em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract{margin:0 0 1.25em 0;display:block}
.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}
.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}
table.tableblock{max-width:100%;border-collapse:separate}
table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}
table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}
table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0}
table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0}
table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0}
table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0}
table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0}
table.frame-all{border-width:1px}
table.frame-sides{border-width:0 1px}
table.frame-topbot{border-width:1px 0}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
td>div.verse{white-space:pre}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none}
ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em}
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:.85em}
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px}
ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}
ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}
ul.inline>li>*{display:block}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist>table tr>td:first-of-type{padding:0 .75em;line-height:1}
.colist>table tr>td:last-of-type{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
.imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0}
.imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background-color:#00fafa}
.black{color:#000}
.black-background{background-color:#000}
.blue{color:#0000bf}
.blue-background{background-color:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background-color:#fa00fa}
.gray{color:#606060}
.gray-background{background-color:#7d7d7d}
.green{color:#006000}
.green-background{background-color:#007d00}
.lime{color:#00bf00}
.lime-background{background-color:#00fa00}
.maroon{color:#600000}
.maroon-background{background-color:#7d0000}
.navy{color:#000060}
.navy-background{background-color:#00007d}
.olive{color:#606000}
.olive-background{background-color:#7d7d00}
.purple{color:#600060}
.purple-background{background-color:#7d007d}
.red{color:#bf0000}
.red-background{background-color:#fa0000}
.silver{color:#909090}
.silver-background{background-color:#bcbcbc}
.teal{color:#006060}
.teal-background{background-color:#007d7d}
.white{color:#bfbfbf}
.white-background{background-color:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background-color:#fafa00}
span.icon>.fa{cursor:default}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]:after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@media print{@page{margin:1.25cm .75cm}
*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]:after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}
.sect1{padding-bottom:0!important}
.sect1+.sect1{border:0!important}
#header>h1:first-child{margin-top:1.25rem}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span:before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]:before{display:block}
#footer{background:none!important;padding:0 .9375em}
#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
</style>
</head>
<body class="article">
<div id="header">
</div>
<div id="content">
<div class="paragraph">
<p><a id="architecture"></a></p>
</div>
<div class="sect1">
<h2 id="_deployment_architecture">Deployment Architecture</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Virgo for Apache Tomcat offers several choices when it comes to deploying applications. Each
choice offers certain advantages, and it is important to understand those in order to make
the right choice for your application. In this chapter, we take a closer look at the choices
offered, compare them, and provide guidelines in choosing the right one based on your
specific needs.</p>
</div>
<div class="paragraph">
<p>The VTS supports standard self-contained WAR files thus allowing you to
use the Virgo for Apache Tomcat as an enhanced web server. The VTS also supports the
<strong>Shared Libraries</strong> WAR format which allows for slimmer WAR files that
depend on OSGi bundles instead of including JAR files inside the WAR. The <strong>Shared
Services</strong> WAR format allows developers to further reduce the complexity of
standard WARs by deploying services and infrastructure bundles alongside the WAR. A shared
services WAR will then consume the services published by those bundles. To complete the
picture, the VTS supports the new OSGi-standard <strong>Web Application
Bundle</strong> deployment format for web applications that builds on the benefits
provided by a shared services WAR. In addition to this, VTS provides
additional conveniences for developing and deploying Spring MVC-based web applications.</p>
</div>
<div class="paragraph">
<p>For applications consisting of multiple bundles and web applications, plans and the PAR
format are the primary deployment models that take advantage of OSGi capabilities. We will
explore all of these formats and their suitability later in this guide.</p>
</div>
<div class="paragraph">
<p><a id="architecture-deployment-formats"></a></p>
</div>
<div class="sect2">
<h3 id="_supported_deployment_formats">Supported Deployment Formats</h3>
<div class="paragraph">
<p>The Virgo for Apache Tomcat supports applications packaged in the following formats:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p><a href="#architecture-raw-osgi-bundles">Raw OSGi Bundles</a></p>
</li>
<li>
<p><a href="#architecture-wars">Java EE WAR</a></p>
</li>
<li>
<p><a href="#architecture-war-gemini">Web Application Bundles</a></p>
</li>
<li>
<p><a href="#architecture-pars">PARs</a></p>
</li>
<li>
<p><a href="#architecture-plans">Plans</a></p>
</li>
<li>
<p><a href="#architecture-configurations">Configurations</a></p>
</li>
</ol>
</div>
<div class="paragraph">
<p>When you deploy an application to the VTS, each deployment artifact
(e.g., a single bundle, WAR, PAR, or plan) passes through a deployment pipeline. This
deployment pipeline is responsible for processing applications of certain types (i.e.,
application type). The 3.7.0.RELEASE release of the VTS natively
supports deployers analogous to each of the aforementioned packaging options.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s take a closer look now at each of the supported deployment and packaging
options to explore which one is best suited to your application.</p>
</div>
<div class="paragraph">
<p><a id="architecture-raw-osgi-bundles"></a></p>
</div>
<div class="sect3">
<h4 id="_raw_osgi_bundles">Raw OSGi Bundles</h4>
<div class="paragraph">
<p>At its core, the Virgo for Apache Tomcat is an OSGi container. Thus any OSGi-compliant
bundle can be deployed directly on the VTS unmodified. You&#8217;ll
typically deploy an application as a single bundle or a set of stand-alone bundles
if you&#8217;d like to publish or consume services globally within the container via
the OSGi Service Registry.</p>
</div>
<div class="paragraph">
<p><a id="architecture-wars"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_war_deployment_formats">WAR Deployment Formats</h4>
<div class="paragraph">
<p>For Web Application Archives (WAR), the Virgo for Apache Tomcat provides support for the
following three formats.</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p><a href="#architecture-standard-war">Standard WAR</a></p>
</li>
<li>
<p><a href="#architecture-shared-libraries-war">Shared Libraries WAR</a></p>
</li>
<li>
<p><a href="#architecture-shared-services-war">Shared Services WAR</a></p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Each of these formats plays a distinct role in the incremental migration path
from a standard Java EE WAR to an OSGi-ified web application.</p>
</div>
<div class="paragraph">
<p><a id="architecture-standard-war"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_standard_war">Standard WAR</h4>
<div class="paragraph">
<p>Standard WAR files are supported directly in the VTS. At
deployment time, the WAR file is transformed into an OSGi bundle and installed
into Tomcat. All the standard WAR contracts are honoured, and your existing WAR
files should just drop in and deploy without change. Support for standard,
unmodified WAR files allows you to try out the Virgo for Apache Tomcat on your existing
web applications and then gradually migrate toward the <strong>Shared
Libraries WAR</strong> and <strong>Shared Services WAR</strong> formats.</p>
</div>
<div class="paragraph">
<p>In addition to the standard support for WARs that you would expect from
Tomcat, the VTS also enables the following features:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Spring-driven load-time weaving (see Section 6.8.4, “Load-time weaving
with AspectJ in the Spring Framework").
Diagnostic information such as FFDC (first failure data capture)</p>
</li>
<li>
<p>The main benefit of this application style is familiarity&#8201;&#8212;&#8201;developers know
how to create a WAR file! You can take advantage of the
VTS&#8217;s added feature set without modifying the
application. The application can also be deployed on other Servlet containers or
Java EE application servers.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>You may choose this application style if the application is fairly simple and
small. You may also prefer this style even for large and complex applications as
a starting point and migrate to the other styles over time as discussed in <a href="#migrating-to-osgi">[migrating-to-osgi]</a>.</p>
</div>
<div class="paragraph">
<p><a id="architecture-shared-libraries-war"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_shared_libraries_war">Shared Libraries WAR</h4>
<div class="paragraph">
<p>If you have experience with developing and packaging web applications using
the standard WAR format, you&#8217;re certainly familiar with the pains of
library bloat. So, unless you&#8217;re installing shared libraries in a common
library folder for your Servlet container, you have to pack all JARs required by
your web application in <code>/WEB-INF/lib</code>. Prior to the release of
the Virgo for Apache Tomcat, such library bloat has essentially been the norm for web
applications, but now there is a better solution! The Shared Libraries WAR
format reduces your application&#8217;s deployment footprint and eradicates
library bloat by allowing you to declare dependencies on libraries via standard
OSGi manifest headers such as <code>Import-Package</code> and <code>Require-Bundle</code> . The VTS provides additional
support for simplifying dependency management via the <code>Import-Library</code> and <code>Import-Bundle</code> manifest headers
which are essentially macros that get expanded into OSGi-compliant <code>Import-Package</code> statements.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">Tip</div>
</td>
<td class="content">
<div class="paragraph">
<p>For detailed information on which libraries are already available, check
out the <a href="http://www.eclipse.org/ebr">EBR</a>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p><a id="architecture-shared-services-war"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_shared_services_war">Shared Services WAR</h4>
<div class="paragraph">
<p>Once you&#8217;ve begun taking advantage of declarative dependency management
with a Shared Libraries WAR, you&#8217;ll likely find yourself wanting to take
the next step toward reaping further benefits of an OSGi container: sharing
services between your OSGi-compliant bundles and your web applications. By
building on the power and simplicity of Gemini Blueprint, the <strong>Shared Services
WAR</strong> format puts the OSGi Service Registry at your finger tips. As
a best practice you&#8217;ll typically publish services from your domain,
service, and infrastructure bundles via <code>&lt;osgi:service &#8230;&#8203;&gt;</code> and then consume them in your web application&#8217;s
ApplicationContext via <code>&lt;osgi:reference &#8230;&#8203; &gt;</code>. Doing so
promotes programming to interfaces and allows you to completely decouple your
web-specific deployment artifacts from your domain model, service layer, etc.,
and that&#8217;s certainly a step in the right direction. Of the three supported
WAR deployment formats, the Shared Services WAR is by far the most attractive in
terms of modularity and reduced overall footprint of your web applications.</p>
</div>
<div class="paragraph">
<p><a id="architecture-war-gemini"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_wars_and_the_gemini_web_container">WARs and the Gemini Web Container</h4>
<div class="paragraph">
<p>Virgo for Apache Tomcat fully supports the OSGi Web Applications standard. Using the
reference implementation from Gemini Web that was developed by SpringSource from
an offshoot of the original VTS codebase. This RI is now fully
integrated in VTS as the basis of the support for web
application deployment.</p>
</div>
<div class="paragraph">
<p>The OSGi Web Applications specification introduces the concept of a <strong>Web
Application Bundle</strong>, which is a WAR that is also a bundle. The
specification defines how WAR files are transformed into bundles automatically
as needed.</p>
</div>
<div class="paragraph">
<p>You can find an introduction to the Web Container in blog entries written by
the Virgo team <a href="http://blog.springsource.com/2009/05/27/introduction-to-the-osgi-web-container/">here</a>
and <a href="http://blog.springsource.com/2009/06/01/what-the-osgi-web-container-means-for-dm-server/">here</a>.</p>
</div>
<div class="paragraph">
<p><a id="architecture-war-gemini-extensions"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_extensions_to_the_web_container">Extensions to the Web Container</h4>
<div class="paragraph">
<p>Virgo for Apache Tomcat provides a variety of extensions to the Web Container that
allow you to construct sophisticated applications. The table below
summarises the extensions that are available or in development.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Feature</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Instrumentable ClassLoaders</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">All web bundle ClassLoaders are
instrumentable by Spring&#8217;s load-time weaving infrastructure.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Support for exploded bundles/WARs</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Bundles/WARs in directory form can
be deployed as Web Application Bundles</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Support for scanning TLDs in dependencies</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">As per the Web Application
specification, all TLDs located inside a web bundle are located using
the rules defined in the JSP 2.1 specification. In
VTS, the dependencies of a Web Application
Bundle are also scanned for TLDs following the rules outlined in JSP 2.1</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p><a id="architecture-pars"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_par">PAR</h4>
<div class="paragraph">
<p>A PAR is a standard JAR which contains all of the modules of your application
(e.g., service, domain, and infrastructure bundles as well as a WAR or web module
for web applications) in a single deployment unit. This allows you to deploy,
refresh, and undeploy your entire application as a single entity. If you are
familiar with Java EE, it is worth noting that a PAR can be considered a replacement
for an EAR (Enterprise Archive) within the context of an OSGi container. As an added
bonus, modules within a PAR can be refreshed independently and on-the-fly, for
example via the Virgo Eclipse IDE Tooling (see the Virgo Tools Guide).</p>
</div>
<div class="paragraph">
<p>Many of the benefits of the PAR format are due to the underlying OSGi
infrastructure, including:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Fundamentally modularized applications: instead of relying on fuzzy
boundaries between logical modules in a monolithic application, this
style promotes physically separated modules in the form of OSGi bundles.
Then each module may be developed separately, promoting parallel
development and loose coupling.</p>
</li>
<li>
<p>Robust versioning of various modules: the versioning capability
offered by OSGi is much more comprehensive than alternatives. Each
module can specify a version range for each of its dependencies. Bundles
are isolated from each other in such a way that multiple versions of a
bundle may be used simultaneously in an application.</p>
</li>
<li>
<p>Improved manageability: each bundle may be deployed or undeployed in
a running application. This allows modifying the existing application to
fix bugs, improve performance, and even to add new features without
having to restart the application.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Furthermore, PARs scope the bundles of your application within the
VTS. Scoping provides both a physical and logical application
boundary, effectively shielding the internals of your application from other PARs
deployed within the VTS. This means your application doesn&#8217;t
have to worry about clashing with other running applications (e.g., in the OSGi
Service Registry). You get support for load-time weaving, classpath scanning,
context class loading, etc., and the VTS does the heavy lifting for
you to make all this work seamlessly in an OSGi environment. If you want to take
full advantage of all that the Virgo for Apache Tomcat and OSGi have to offer, packaging and
deploying your applications as a PAR is a good choice, although plans are an even
better one, as described in the next section.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">Tip</div>
</td>
<td class="content">
<div class="title">OSGi != multiple JARs</div>
<div class="paragraph">
<p>Note that while physically separated modules can, in theory, be implemented
simply using multiple JARs, complex versioning requirements often make this
impractical. For example, consider the situation depicted in the diagram below.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Bundle A depends on version <code>1.0.0</code> of bundle <code>B</code> and version <code>2.0.0</code> of bundle <code>C</code>.</p>
</li>
<li>
<p>Bundle B depends on version <code>1.0.0</code> of bundle <code>C</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Suppose that versions <code>1.0.0</code> and <code>2.0.0</code> of bundle <code>C</code> are neither
backward nor forward compatible. Traditional monolithic applications cannot
handle such situations: either bundle <code>A</code> or bundle <code>B</code> would need reworking which
undermines truly independent development. OSGi&#8217;s versioning scheme enables
this scenario to be implemented in a robust manner. If it is desirable to rework
the application to share a single version of <code>C</code>, then this can be planned in and
is not forced.</p>
</div>
<div class="imageblock">
<div class="content">
<img src="assets/images/architecture-bundle-versioning.png" alt="architecture bundle versioning">
</div>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p><a id="architecture-plans"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_plans">Plans</h4>
<div class="paragraph">
<p>A plan is similar to a PAR in that it encapsulates all of the artifacts of your
application in a single deployment unit. The main difference, however, is that a
plan is simply an XML file that lists the artifacts of your application; a PAR, by
contrast, is an actual JAR file that physically contains the artifacts. Just like a
PAR, you deploy, refresh, and undeploy a plan as a single entity. We highly
recommends the use of plans for creating applications.</p>
</div>
<div class="paragraph">
<p>When you create a plan, you can specify that the included bundles and services
are in a scope that isolates them from the rest of Virgo for Apache Tomcat and its
deployments. This scoping ensures that the bundles wire to each other and see each
other&#8217;s services in preference to services from outside the scope. Scoping
also prevents application code from leaking into the global scope or scope of
another application. In addition, a plan can link the lifecycle of a group of
bundles together atomically, which ensures that start, stop, and uninstall
events on a single artifact in the plan are escalated to all artifacts in the plan.
You can, however, disable both of these features by simply setting an attribute in
the plan.</p>
</div>
<div class="paragraph">
<p>The general benefits of using plans are similar to those of using PARs; see <a href="#architecture-pars">PAR</a> for details. Plans offer added benefits,
however, such as the ability to control the deployment order of your application:
the order in which you list artifacts in the plan&#8217;s XML file is the order in
which VTS deploys them. Additionally, because plans specify the
artifacts that make up an application by reference, it is easier to share artifacts
between plans as well as update individual parts of a plan without having to
physically repackage (re-JAR) it.</p>
</div>
<div class="paragraph">
<p><a id="architecture-configurations"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_configurations">Configurations</h4>
<div class="paragraph">
<p>A Configuration is simply a Java properties file. When deployed it will be
recognised by the deployer and installed in to <strong>Configuration
Admin</strong> for later use by your applications. VTS supports
both singleton (ManagedService) and factory (ManagedServiceFactory) configurations.
(see section 104.6 in the Compendium Specification)</p>
</div>
<div class="paragraph">
<p>For a singleton configuration the name that it will be installed under is its filename
minus the <code>.properties</code> extension. Factory Configuration is supported by
specifying the <strong>service.factoryPid</strong> property. In this case the actual PID will
be created by <strong>Configuration Admin</strong> (see section 104.6 in the
Compendium Specification).</p>
</div>
<div class="paragraph">
<p>How to consume configuration data is discussed <a href="#developing-applications-configuration-artifacts">later</a>.</p>
</div>
<div class="paragraph">
<p><a id="architecture-dependency-types"></a></p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_dependency_types">Dependency Types</h3>
<div class="paragraph">
<p>In an OSGi environment, there are two kinds of dependencies between various bundles:
<strong>type</strong> dependency and <strong>service</strong> dependency.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Type dependency</strong>: A bundle may depend on a
type exported by another bundle thus creating a type dependency. Type
dependencies are managed through <code>Import-Package</code> and
<code>Export-Package</code> directives in the OSGi manifest. This
kind of dependency is similar to a JAR file using types in other JAR files
from the classpath. However, as we&#8217;ve seen earlier, there are
significant differences.</p>
</li>
<li>
<p><strong>Service dependency</strong>: A bundle may also
publish services (preferably using Gemini Blueprint), and other bundles may consume
those services. If two bundles depend on the same service, both will be
communicating effectively to the same object. More specifically, any state
for that service will be shared between all the clients of that service.
This kind of arrangement is similar to the commonly seen client-server
interaction through mechanisms such as RMI or Web Services.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_regions">Regions</h3>
<div class="paragraph">
<p>Conceptually, the Eclipse Virgo can be divided into two separate subsystems, called Regions. This
provides a way to keep the Virgo Kernel separate from user applications. Read more about Regions
and the two in Virgo in the <a href="http://www.eclipse.org/virgo/documentation/virgo-documentation-3.7.0.RELEASE/docs/virgo-user-guide/html/index.html">User Guide</a>
concepts section.</p>
</div>
<div class="paragraph">
<p><a id="architecture-forming-bundles"></a></p>
</div>
</div>
<div class="sect2">
<h3 id="_a_guide_to_forming_bundles">A Guide to Forming Bundles</h3>
<div class="paragraph">
<p>So what makes an application suitable for deployment on the Virgo for Apache Tomcat? Since
OSGi is at the heart of the VTS, modular applications consisting of
bundles, which each represent distinct functionality and well-defined boundaries, can
take maximum advantage of the OSGi container&#8217;s capabilities. The core ideas behind
forming bundles require following good software engineering practices: separation of
concerns, loose coupling, and communication through clear interfaces. In this section,
we look at a few approaches that you may use to create modular applications for
Virgo for Apache Tomcat deployment. Please consider the following discussion as guidelines and
not as rules.</p>
</div>
<div class="paragraph">
<p>Bundles can be formed along horizontal slices of layering and vertical slices of
function. The objective is to enable independent development of each bundle and minimize
the skills required to develop each bundle.</p>
</div>
<div class="paragraph">
<p>For example, an application could have the following bundles:
<strong>infrastructure</strong>, <strong>domain</strong>,
<strong>repository</strong>, <strong>service</strong>, and
<strong>web</strong> as shown in the following diagram.</p>
</div>
<div class="imageblock">
<div class="content">
<img src="assets/images/bundle-dependencies-layers.png" alt="bundle dependencies layers">
</div>
</div>
<div class="paragraph">
<p>Each bundle consists of types appropriate for that layer and exports
packages and services to be used by other layers. Let&#8217;s examine each bundle in
more detail:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 1. Bundles across layers</caption>
<colgroup>
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Bundles</th>
<th class="tableblock halign-left valign-top">Imported Packages</th>
<th class="tableblock halign-left valign-top">Exported Packages</th>
<th class="tableblock halign-center valign-top">Consumed Services</th>
<th class="tableblock halign-center valign-top">Published Services</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Infrastructure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Third-party libraries</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Infrastructure interfaces</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">None</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">None</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Depends: for example,
if JPA is used to
annotate persistent
types, then JPA
packages.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Public domain types</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">None</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">None</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Web</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain, Service</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">None</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">Service beans</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">None</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Service</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain,
Infrastructure,
Repository</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Service interfaces</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">Repository beans</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">Service beans</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Repository</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain,
Third-party libraries,
ORM bundles, etc.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Repository interfaces</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">DataSources,
ORM session/entity managers,
etc.</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">Repository beans</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Within each layer, you may create bundles for each subsystem representing a vertical
slice of business functionality. For example, as shown in the following figure, the
service layer is divided into two bundles each representing separate business
functions.
<span class="image"><img src="assets/images/bundle-dependencies-verticals.png" alt="bundle dependencies verticals"></span></p>
</div>
<div class="paragraph">
<p>You can similarly separate the repositories, domain classes, and web controllers
based on the business role they play.</p>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2017-02-23 21:06:43 +01:00
</div>
</div>
</body>
</html>