QoS-Aware Dependency Management for Component-Based Systems

This paper discusses dependencies analysis significance when updating component-based system dynamically. It presents a service-based matrix model and nested graph as approaches to capture components' dependencies; it discusses using dependencies analysis for safe dynamic updating in component-based software systems; we advocate using service-based dependencies rather than component-based which refelect accurate effect during dynamic reconfiguration.


INTRODUCTION
Component-based software systems are those built by assembling pre-exiting components, which provides high flexibility and reusability. The major work with component-based development (CBD) is component integrating rather than writing code and developing everything from scratch. In conventional software development, the concept of complexity is related to the difficulty to analyze source code, modify, and maintain its modules. However, this concept is different in CB systems because the maintenance and reconfiguration only involves replacing, adding, and deleting components rather than source code changes. Therefore, in CB systems, the complexity resides in the dependencies among components, which is captured by the system architecture [1]. In this paper, we discuss managing components' dependencies in our framework (Dynamic Protocol-based Component-based Software-DPICS) [2], which supports building software systems by wiring software components. In DPICS, the functionality of the system is accomplished through protocol-based interaction between components routed by soft bus. DPICS aims to support updating the system during runtime. Traditionally, software modifications require shutting down the system, update the system, and restarting it. This approach is not suitable for critical systems that require 24/ 7/365 availability, such as banking or telecommunications systems, or systems that are critical-mission systems such as air-traffic controllers. Therefore, such systems require dynamic updating which means modifying the system at run-time without service interruption. In component-based software systems, dynamic updating includes adding, removing, and replacing a component on the fly. Updating the system dynamically requires exploring the effects of this modification on the rest of system's components in order not to lead the system to inconsistent state.
Dependency between components can be defined as the reliance of a component on other(s) to support a specific functionality; therefore, we consider dependency as binary relationship between two components: antecedent, and dependent [3] . Antecedent is the free component that has an effect on the dependent one if it is removed or modified, on the other hand, dependent component is the one that related to its antecedents where changes in them might lead dependent to malfunction or fail (see Fig. .1).

Fig .1: Dependency Relationship
Formally, Larsson and Crnkovic [4] define a relation called "depend on", where C i C j means that component C i is the dependent and it requires correct operation of C j (the antecedent) in order to function correctly. For a component-based system that has a set of components S, the set of all dependencies is defined as

Λ ∈ S Ci Cj}
According to this, the current configuration is set of all component and their dependencies

Requirements
for Dependency Analysis: Dependences analysis is fundamental task for understanding, maintaining, and updating software systems [5,6]. Traditionally, dependence analysis was based on investigating the source program to find dependencies such control and data flow relationships among program variables and functions in order to optimize compilation process [7]. In component-based system, dependency management is essential part of system configuration [6,8]. Moreover, updating system at runtime lacks the test phase when developing software which makes such updating more risky, thus analyzing dependencies between components is necessary in order to safely keep the system running continuously and not crash the system. In this section, we discuss the significance of analyzing the dependencies when dynamically updating the system.

When adding a new Component:
Before the new component can be added to the system, it is needed to understand its relationships with other components and its roles as dependent and antecedent. As dependent component, components that would provide services to this new one should be recognized and checked if they are already among systems' components or needed to be loaded. As antecedent, the added component will offer new services to others components; this might require creating new dependencies or might require adding or replacing other components that could be dependents on this one. More specifically, when adding a new component, dependency analysis should answer the following questions Q1) If there are components in the system need also to be updated in order to benefit of the services provided by this new one (antecedent role), what is the order of updating those components safely ? Q2) What are the new dependencies (direct and indirect) if this new component will depend on preexisted ones (dependent role)?
Formally, we can define the configuration of the system after adding a new component safely as

Con'=(S',D')
The difference between original configuration Con and the new one Con' is the new components and new dependencies which can be defined foramll as following

The new component C new ∈ S d and S d =S I S'
The new dependency is the set

D new ={ (C new ,C): C new C} ∪ {(C,C new ): C C new }
When deleting an existing components: Before deleting a component from the system, dependencies management is necessary to understand the effect of removing that component. Removing a component might not only have effect on its direct dependents but might affect others transitively, which requires tracing these dependencies from a component to other. Such management of dependency is important for system safety as removing a required component might lead the system to crash which is not accepted with continuously running systems. When removing a component from the system, dependency analysis should answer the following questions: Q3) What are the components in the system that will get affected by removing this component directly or transitively? Q4) What is the order of updating the dependents on removed one ? Formally, the deleted component Therefore, it has no effect on its dependents as it still provides the same services with same interfaces.

(B,A), (B, D), (C, D), (C, B), (E, B), (E,D)}
To represent components' dependencies using adjacency matrix, a matrix M n x n is used, where each component is represented by a column and a row. If Component C i depends on C j then MD i,j =1 , and in general.
According to this the previous dependency described in Fig. 3 can be represented using adjacent matrix as depicted in Fig. 3 A Fig. 3 Fig. 3. which has the same components, it includes direct and indirect dependencies. In Fig. 4, when calculating transitive closure, self dependency is excluded as the component is the module of updating and our concern here is the intercomponents dependencies. Correspondingly, indirect dependency can be represented in a matrix by calculating the transitivity using Warshall's algorithm showed in Fig.  5. The algorithm uses the matrix represents direct dependencies MD n x n to produce the matrix MA n x n   [11]. According to this, during dynamic updating, modifying an antecedent component not necessary to result in inconsistencies with its dependents. For example, in Fig. 7, C1 depends on C3 where its service S11 requires S31 in order to accomplish its functionality. C2 depends also on C3 where its service S21 requires S32 from C3.

Fig. 7: Service Level Dependencies
Considering only component level dependency, If C 3 got updated; both C 2 and C 3 are considered to be affected, which might not be completely true. Assume that service S 31 in the new version of C 3 has no changes comparing to that in old version, and S 32 has changed, then only component C 2 will be affected with this replacement. Therefore, component level of dependency is not enough to trace effects of component updating. On the other hand, service level of dependency will help understand more detail about the consequence of component modification. Moreover, service dependency can be used to discover all true direct and indirect components dependencies. For example, in Fig. 3.8 service S11 in component C 1 depends on service S21 in Component C 2 , and C2 depends on C3 where C2 has a service, S22, which depends on service S31 in C3. Taking into account only component level of dependency, C 1 would depend on C3 indirectly, but with more details through service dependency, C 1 does not depend on C3. But what if service S21 depends on S22 (intracomponent dependencies) in Fig. 8 ? Likewise what if service S31 depends on S32 in Fig. 7. As a result of that, with service dependencies, intra-component dependencies (dependencies between component's services) play a rule when calculating components dependencies.

Service Level Dependencies Representation:
Using graph and adjacent matrix are sufficient to model dependencies in component-based system as component level, but that is not enough to trace component dependencies accurately. Hence, instead of using simple graph to represent component dependencies, nested graph is used to model dependencies at service level, which gives more details of components relationships. The Service Level Dependency Graph (SLDG)=(C,S,A) is a nested graph where C is a finite nonempty set vertices represent system's components, S is a finite nonempty set of inner vertices represent component's services, and A is set of edges between two vertices(inner vertices) such that (S i , S j ) ∈ D means S i S j , where S i , S j ∈( Ci ∪ C j ) and D ⊆ (S X S).  Fig. .3, S x,y =1 if service X depends on service Y. Fig. 3.10 depicts a matrix that represent services dependencies described in Fig. 9, The transitive closure also can be calculated using Warshall's algorithm described in Fig. 5. Fig. 11 depicts the matrix resulted of computing transitive closure, which represents the direct and indirect service dependencies. Now from the matrix in Fig. 11, we can map the service back to its components so we can have clear picture about real direct dependencies between components, for example, from Fig. 3.11, we can find that services belongs to component E has neither direct nor indirect dependencies with services in component A, so updating A will have no effect on E, which is against Fig. 6 indication.

Applying Dependencies Analysis during Dynamic
Updating: When a component is updated dynamically, its dependencies with other components in the system should be checked in order to keep the system running without fail. Adjacent matrix representation of servicebased dependencies is a good computational approach to answer the questions above raised when adding, removing, or modifying a component.
When adding a new component: Adding a new component to the system has no effect on existing components' dependencies but this requires replacing some of old components in order to use the new one. To answer question 1, regarding the order of components updating , first the new component should be added first then starting update the components that will benefit of this new one (its dependents) [12]. Replacing those components requires analysis dependencies related to component replacement which discussed in 4.3. The adjacent matrix will be modified in order to reflect the changes in dependencies structure, new rows and columns are added to represent the direct dependencies added between the new component's services and other components. Also, using Warshall's algorithm, the matrix will be changed when computing new indirect dependencies added with the new component (question 2).