\chapter{Overall Architecture}
\label{chap:architecture}
\index{overall architecture}
\index{architecture}

In the introductory chapter, we saw that modern middleware and operating
systems do not provide proper mechanisms for dependence management in
component-based distributed systems. The lack of such mechanisms leads to
several problems related to administration, reliability, quality of service,
and dynamic configuration. To solve these problems, we present mechanisms for
dependence representation in complex software systems and describe an
integrated architecture that uses these mechanisms to provide
dynamic (re)configuration while still supporting reliability, quality of service,
customizability, and scalability.

\section{The Big Picture}
\index{dynamic (re)configuration} 

Figure \ref{fig:big-picture} presents a schematic view of the major elements
of our architecture. It shows the chapters in which each element is described
in detail.
\begin{figure}[htb]
\centerline{\psfig{file=figs/big-picture.eps,width=12cm}}
\caption{Overall Architecture for Dynamic Configuration}
\label{fig:big-picture}
\end{figure}
\emph{Prerequisite specifications} reify static dependencies of components towards
its environment while \emph{component configurators} reify dynamic, runtime
dependencies. \emph{Automatic configuration} aims at automating management, easing
the work of users and administrators. The automatic configuration process is
based on the prerequisite specifications, and constructs the component
configurators. \emph{Mobile reconfiguration agents}\index{agents}, in turn, improve
management by making it more scalable and efficient.

The contributions\index{contributions} of this thesis focus on the four aspects
on the top of Figure \ref{fig:big-picture}, leveraging the work of others on
standard CORBA Services and on QoS-aware Resource Management\index{resource
management}. Figure \ref{fig:relationships} depicts the relationships among
the six elements in the architecture.

\begin{figure}[htb]
\centerline{\psfig{file=figs/relationships.eps,width=12cm}}
\caption{Relationships}
\label{fig:relationships}
\end{figure}

In the following sections of this chapter, we provide an overview of the major
elements of our architecture explaining the relationships depicted in Figure
\ref{fig:relationships}. In the subsequent chapters, we give a more in-depth
description of each of the aspects of the architecture.

\section{Automatic Configuration}
\label{sec:autoconfig}
\index{automatic configuration}

Software systems are evolving more rapidly than ever before. Vendors release
new versions of web browsers, text editors, and operating systems once every
few months. System administrators and users of personal computers spend an
excessive amount of time and effort configuring their computer accounts,
installing new programs, and, above all, struggling to make all the software
work together\footnote{When even PhD students in Computer Science have trouble
keeping their commodity personal computers functioning properly, one can
notice that something is very wrong in the way that commercial software is
built nowadays.}.

In environments like MS-Windows, the installation of some applications is
partially automated by ``wizard'' interfaces that direct the user through the
installation process. However, it is common to face situations in which the
installation cannot complete or in which it completes but the software package
does not run properly because some of its (unspecified) requirements are not
met. In other cases, after installing a new version of a system component or a
new tool, applications that used to work before the update, stop functioning.
It is typical that applications on MS-Windows cannot be cleanly
uninstalled. Often, after executing special uninstall procedures, ``junk''
libraries and files are left in the system.  The application does not know if
it can remove all the files it has installed because the system does not
provide the clear mechanisms to specify which applications are using which
libraries.

To solve this problem, we need a completely new paradigm for installing,
updating, and removing software from workstations and personal computers. We
propose to automate the process of software maintenance with a mechanism we
call \emph{Automatic Configuration}. In our design of an automatic
configuration service for modern computer environments, we focus on two key
objectives:

\begin{enumerate}
\item Network-Centrism and
\item an ``What You Need Is What You Get'' (WYNIWYG) model.
\end{enumerate}

\emph{Network-Centrism}\index{network-centrism} refers to a model in which all
entities, users, software components, and devices exist in the network and are
represented as distributed objects.  Each entity has a network-wide identity,
a network-wide profile, and dependencies on other network entities.  When a
particular service is configured, the entities that constitute that service
are assembled dynamically.  Users no longer need to keep several different
accounts, one for each device they use. In the network-centric model, a user
has a single network-wide account, with a single network-wide profile that can
be accessed from anywhere in the distributed system. The middleware is
responsible for instantiating user environments dynamically according to
the user's profile, role, and the underlying platform
\cite{carvalho00:environments}.

In contrast to existing operating systems, middleware, and applications where
a large number of non-utilized modules are carried along with the standard
installation, we adopt a \emph{What You Need Is What You Get} model, or
\emph{WYNIWYG}\index{WYNIWYG}.  In other words, the system configures itself
automatically and loads a \emph{minimal} set of components required for
executing the user applications in the most efficient way.  The components are
downloaded from the network, so only a small subset of system services are
needed to bootstrap a node, leading to the construction of
``network-computers''.

In the Automatic Configuration model, system and application software are
composed of network-centric components\index{network-centrism}, i.e.,
components available for download from a \emph{Component
Repository}\index{component repository} present in the network. Component code
is encapsulated in dynamically loadable libraries (known as ``DLLs'' in Windows
and ``shared objects'' in Unix), which enables dynamic linking.

Each application, system, or component\footnote{From now on,
we use the term ``component'' not only to refer to a piece of an application
or system but also to refer to the entire application or system. This is
consistent since, in our model, applications and systems are simply components
that are made of smaller components.} specifies everything that is required
for it to work properly (both hardware and software requirements). This
collection of requirements is called \emph{Prerequisite Specifications} or,
simply, \emph{Prerequisites}.



\subsection{Prerequisites}
\label{sec:prerequisites}
\index{prerequisites|textbf}

The prerequisites for a particular inert component (stored on a local disk or
on a network component repository) must specify any special requirement for
properly loading, configuring, and executing that component. We consider three
different kinds of information that can be contained in a list of
prerequisites.

\begin{enumerate}
\item The nature of the hardware resources the component needs.
\item The capacity of the hardware resources it needs.
\item The software services (i.e., other components) it requires.
\end{enumerate}

The first two items are used by \emph{QoS-Aware Resource Management Services}
\index{resource management} to determine where, how, and when to execute the
component. QoS-aware systems\index{QoS} can use these data to enable proper
admission control, resource negotiation, and resource reservation.  The last
item determines which auxiliary components must be loaded and in which kind of
software environment they will execute.

The first two items -- reminiscent of the Job Control Languages of the
mid-1960s -- can be expressed by modern QoS specification languages
\index{QoS!specification languages} such as QML \cite{QML:coots99} and QoS
aspect languages \cite{QDL:bbn98}, or by using a simpler format such as SPDF
(see Section \ref{sec:SPDF} and \cite{kon99:2k-TR}).  The third item is
equivalent to the \emph{require} clause in architectural description languages
like Darwin \cite{darwin:regis94} and module interconnection languages like
the one used in Polylith \cite{polylith94}.

The prerequisites are instrumental in implementing the WYNIWYG model as they
let the system know what the exact requirements are, for instantiating the
components properly. If the prerequisites are specified correctly, the system
not only executes all the necessary components to activate the user
environment, but also executes a minimal set of components required to achieve
that. 

%As shown in Figure \ref{fig:relationships}, the automatic configuration
%service leverages CORBA technology, relying on entities such as the Naming
%Service and the Component Repository. 

We currently rely on the component programmer to specify component
prerequisites\index{prerequisites}.  Mechanisms for automating the creation of
prerequisite specifications and for verifying their correctness require
further research and are beyond the scope of this thesis. Another interesting
topic for future research is the refinement of prerequisites specifications at
runtime according to what the system can learn from the execution of
components in a certain environment. This can be achieved by using QoS\index{QoS}
profiling tools such as QualProbes \cite{nahrstedt00:qualprobes}.

\section{Component Configurator}
\label{sec:comp-config}
\index{component configurator|(}

The explicit representation of the dynamic dependencies is achieved through
special objects attached to each relevant component at execution time. These
objects are called \emph{component configurators}; they are responsible for
reifying the runtime dependencies for a certain component and for implementing
policies to deal with events coming from other components.

While the Automatic Configuration Service parses the prerequisite
specifications, fetches the required components from the Component Repository,
and dynamically loads their code into the system runtime, it uses the
information in the prerequisite specifications to create component
configurators representing the runtime inter-component dependencies.  Figure
\ref{fig:dependencies} depicts the dependencies that a component configurator
reifies.

\begin{figure}[htbp]
  \begin{center}
    \leavevmode \epsfig{file=figs/dependencies.eps,width=12cm}
    \caption{Reification of Component Dependencies}
    \label{fig:dependencies}
  \end{center}
\end{figure}

Each component $C$ has a set of \emph{hooks}\index{hooks} to which other components
can be attached. These are the components on which $C$ depends and
are called \emph{hooked components}. There might be other
components that depend on $C$, these are called \emph{clients}. In
general, every time one defines that a component $C_1$ depends on a
component $C_2$, the system should perform two actions: 
\begin{enumerate}
\item attach $C_2$ to one of the hooks in $C_1$ and 
\item add $C_1$ to the list of clients of $C_2$.
\end{enumerate}

As an example, consider a web browser that specifies, in its list of
prerequisites, that it requires a TCP/IP service, a window manager, a local
file service, and an implementation of the Java Virtual Machine (JVM). Its
component configurator should maintain a hook for each of these services. When
the browser is loaded, the automatic configuration system must verify whether
these services are available in the local environment. If they are not, it
must create new instances of them. In any case, references to the services are
stored in the browser configurator hooks and may be later retrieved and
updated if necessary.

Component configurators are also responsible for distributing events across
the inter-dependent components. Examples of common events are the failure of a
client and destruction, internal reconfiguration, or replacement of the
implementation of a hooked component. The rationale is that such events affect
all the dependent components. The component configurator is the place where
programmers must insert the code to deal with these configuration-related
events.

Component developers can program specialized versions of component
configurators that are aware of the characteristics of specific
components. These specialized configurators can, therefore, implement
customized policies to deal with component dependencies in an
application-specific way. 

For an example of how customized component configurators could help
applications, consider a QoS-sensitive\index{QoS} video-on-demand client that
reserves a portion of the local CPU for decoding a video stream. The
application developer can program a special configurator that registers itself
with the QoS-aware resource management service\index{resource management}. In
this way, when the resource management service detects a change in resource
availability that would prevent the application from getting the desired level
of service, it notifies the configurator (as shown in Figure
\ref{fig:relationships}). The configurator, with its customized knowledge
about the application, sends a message to the video server requesting that the
latter decrease the video frame rate. Then, with a lower frame rate, the
client is able to process the video while the limited resource availability
persists. When the resources go back to normal, another notification allows
the video-on-demand configurator to re-establish the initial level of service.

\index{component configurator|)}
% If enough time, add a couple figures more using UML.
% Object diagram + some other diagram.


\section{Reconfiguration and Inspection Agents}
\index{automatic configuration}
\index{agents|(}

The automatic configuration mechanism described in Section
\ref{sec:autoconfig} adopts a pull-based approach for code updates and
configuration.  In other words, the service running in a certain network node
takes the initiative to \emph{pull} the code and configuration information
from a Component Repository.  In large-scale systems, this may not be
enough. To support efficient and scalable management, we also need a mechanism
to allow system administrators to \emph{push} code and configuration
information into the network.\index{push and pull} Our architecture achieves
this by using the concept of mobile agents \cite{agents-internet:osr99}.

The architecture comprises of special administrative tools that are used to
create mobile agents and inject them into the network.  The agent traverses the
network and, in each node, is able to perform three kinds of actions:
\begin{enumerate}
\item install the code for new components,
\item reconfigure the node, changing its working parameters and its software
architecture (e.g., by adding, removing, and replacing components), and 
\item collect information about the node's dynamic state. 
\end{enumerate}
After visiting all the nodes specified by the administrator, the agent
returns to the administrator tool and displays the results of its actions along with
the collected information.

At each node, the agent inspects and reconfigures the components through their
component configurators so that the dependencies are still managed properly.
Reconfiguration and inspection agents can be built over low-level mechanisms
such as sockets and simple command interpreters. They can also use more sophisticated
facilities like the CORBA Naming Service for locating the nodes to be visited,
the CORBA middleware for communication, and a Java virtual machine for agent
execution.

\index{agents|)}

\vspace{1cm}

The following chapters present an in-depth description of the issues associated with
each of the architectural elements presented in this chapter and discusses their
implementation in more detail.

