To realize self-adaptation, a software system is equipped with a feedback loop that monitors and analyzes the system and if needed, plans and executes adaptation to the system. For this purpose, the feedback loop uses knowledge (cf. MAPE-K ). To achieve architectural self-adaptation, the feedback loop maintains a runtime model , as part of its knowledge, which represents the architecture of the system under adaptation. This paves the way for dynamic architectures, in which issues can be identified and handled by architectural self-adaptation .
There are various ways of how self-adaptation can be realized. On the one hand, rule-based approaches [5, 7] prescribe the adaptation (i.e., actions) to be executed if specific events occur and if specific conditions are satisfied. Therefore, the adaptation rules are encoded as event-condition-action rules. Such approaches employ the predefined adaptation rules of a rule set and usually result in a scalable solution, however, often only with at most sufficient adaptation decisions. On the other hand, utility-driven approaches [9, 4] often enable optimal decisions by searching the possible space of adaptations to find the optimal one according to a utility function , but usually do not scale well for larger problems. A utility function is an objective policy which expresses the value of each possible configuration of the system in its domain and identifies the degree to which goals of the system have been satisfied.
Extensive research has been made on utility functions and utility-driven decision-making policies that operates at the level of the software architecture and architectural features. However, the utility-driven approaches proposed in literature all pursue a search-based optimization in the solution space that often does not scale well for complex systems with large solution spaces [4, 10], or they define the utility function over a pre-defined and hence bounded configuration space [3, 6].
Consequently, we propose combining rule-based and utility-driven approaches to achieve the beneficial properties of each of them for dynamic architectures. Defining the utility function and the adaptation rules in a pattern-based way at the architectural level allows us to combine both approaches and particularly to estimate the impact of each application of an adaptation rule on the overall utility at runtime.
The paper is organized as follows: In Sec. II, we introduce the pattern-based definition of utility functions for dynamic architectures. In Sec. III, we link the adaptation rules to the utility function and discuss related observations we exploited for the implementation. Finally, we report on a preliminary evaluation, conclude, and outline future work.
Ii Utility Functions for Dynamic Architectures
Desirable or undesirable issues for a dynamic architecture can be expressed as positive respectively negative model patterns such that concrete issues relate to occurrences of these patterns in a runtime model . We denote that an occurrence as a match for a pattern in the runtime model exists by . Therefore, we propose defining a utility function for a dynamic architecture represented in a runtime model with patterns.
For any utility function for a dynamic architecture must hold that (i) the optimal architectural configuration where all the system goals are optimally fulfilled must gain the maximum utility and that (ii) if any constraint or goal is violated, it must lead to a decrease of the utility. Thus, we employ positive architectural utility patterns and capture their impact on the utility accordingly using utility sub-functions to address case (i). Similarly, we employ negative architectural utility patterns and capture their impact on the utility accordingly using utility sub-functions to address case (ii). It has to be noted that the impact of each pattern occurrence on the overall utility, which is captured by a utility sub-function, may vary for each occurrence depending on the specific characteristics of the context (e.g., for self-healing, the attributes of a failing component may indicate the criticality of this component or the severity of the observed failures, which determines the negative impact on the utility).
As an example, we use mRUBiS , a component-based system realizing an online marketplace that hosts an arbitrary number of shops. Each shop consists of 18 components and runs isolated from the other shops. We are particularly interested into self-healing, that is, the automatic repairing of runtime failures by architectural self-adaptation. Therefore, we equip mRUBiS with a MAPE-K loop that uses a runtime model representing the mRUBiS architecture. The model captures the hosted Shops, their structuring into Components (with ProvidedInterfaces and RequiredInterfaces) and Connectors linking required and provided interfaces, as well as runtime Failures. Thereby, each Component is of a specific ComponentType.
For the example, Fig. 1 shows the positive architectural utility pattern with its utility sub-function . For each started (i.e., running) component of a shop, the utility of the shop is increased by . We may define as the product of the criticality of the specific component, the reliability of the component type, and the connectivity of the component (i.e., the number of associated connectors). This pattern is applied to all shops on the marketplace to obtain the total positive impact on the overall utility of the marketplace.
Similarly, Fig. 2 presents the negative architectural utility pattern with its utility sub-function
for the example. This pattern matches if the usage of a provided interface of a started component in a shop has caused five or more failures (exceptions), which decreases the utility of the shop by. We may define similar to and apply this pattern for all shops to obtain the total negative impact on the overall utility.
In general, we define multiple positive and negative patterns, that is, and . All matches of these patterns determine the overall utility for the current architecture represented in the runtime model . We define the set of all matches for the positive pattern in as and the set of all matches for the negative pattern in as . Given these sets, the overall utility can be defined and computed as follows:
Hence, the overall utility is the sum of all for each match in accumulated over all positive patterns in minus the sum of all for each match in accumulated over all negative patterns in . As discussed previously, the impact of a match on the overall utility is influenced by the specific context of the match. Thus, the utility sub-functions and are paramterized by the runtime model and the specific match , which capture the context of the match.
In general, matches of positive and negative patterns result from changes of the environment. While existing matches of positive patterns are usually not affected by the adaptation rules (i.e., the adaptation does not do any harm to the system), matches of negative patterns should be addressed by the rules (i.e., the adaptation repairs the system). Finally, the kind of utility functions as presented here is restricted to linear functions, which are often used for optimization (cf. ).
Iii Linking Adaptation Rules & Utility Functions
Based on the idea of architectural utility patterns, we describe the condition of an adaptation rule , which must be fulfilled in order to apply , as a model pattern . For a rule with the pattern , we denote that can be applied for a match of in the runtime model as . Actually applying for in results in a modified runtime model , which we denote as .
For any adaptation logic based on the presented kind of utility functions and adaptation rules, the following observations must hold: (1) If there is no match of any negative pattern, there is no need for any adaptation since no improvement of the utility is possible. (2) Any possible improvement of the utility must necessarily resolve matches of negative patterns, otherwise no improvement of the utility would be possible.
Consequently, we can assume that (A1) for any rule in the rule set must hold that a negative pattern exists such that any match for includes a match for . Otherwise, could be applied even though no utility improvement can be achieved. This would contradict observation (1). However, might require more context compared to such that patterns of rules may extend the negative patterns. Furthermore, it is plausible to assume that (A2) for any rule in and any match for that includes a match for the related negative pattern holds that applying for will make the match for invalid. Otherwise, would not resolve the identified match for and thus would not lead to an improvement of the utility as we would expect from observation (2).
Iv Discussion, Conclusion, & Future Work
For a preliminary evaluation of the approach, we set up mRUBiS with shops resulting in a system with components. For this large case study, we were able to follow the proposed scheme by defining accordingly a utility function and linking several self-healing rules (e.g., restart, redeploy, replace a component) to the function. This gives us initial confidence about the applicability and benefits of the approach.
In this paper, we proposed combining rule-based and utility-driven approaches to achieve the beneficial properties of each of them. Therefore, we define both, the utility function and the adaptation rules in a pattern-based way at the architectural level, which enables their linking. As future work, we plan to exploit this link for the efficient and optimal execution of the rules, and to investigate non-linear utility functions.
-  mRUBiS. http://www.mdelab.de [Online; accessed 09-May-2016].
-  G. Blair et al. Models@run.time. Computer, 42(10):22–27, 2009.
-  S.-W. Cheng and D. Garlan. Stitch: A language for architecture-based self-adaptation. Journal of Systems and Software, 85(12), 2012.
-  N. Esfahani et al. A learning-based framework for engineering feature-oriented self-adaptive software systems. TSE, 39(11):1467–1493, 2013.
-  F. Fleurey et al. Modeling and validating dynamic adaptation. In Models in Software Engineering, volume 5421 of LNCS, pages 97–108. Springer, 2009.
-  J. Floch et al. Using architecture models for runtime adaptability. IEEE Software, 23(2):62–70, 2006.
-  J. Keeney and V. Cahill. Chisel: A policy-driven, context-aware, dynamic adaptation framework. In POLICY ’03, pages 3–14. IEEE, 2003.
-  J. O. Kephart and D. Chess. The vision of autonomic computing. Computer, 36(1):41–50, 2003.
J. O. Kephart and W. E. Walsh.
An artificial intelligence perspective on autonomic computing policies.In POLICY’04, pages 3–12. IEEE, 2004.
-  R. Rouvoy et al. Music: Middleware support for self-adaptation in ubiquitous and service-oriented environments. In SEfSAS, volume 5525 of LNCS, pages 164–182. Springer, 2009.