  Self-adaptation solutions need to periodically monitor, reason about, and
adapt a running system. The adaptation step involves generating an adaptation
strategy and applying it to the running system whenever an anomaly arises. In
this article, we argue that, rather than generating individual adaptation
strategies, the goal should be to adapt the control logic of the running system
in such a way that the system itself would learn how to steer clear of future
anomalies, without triggering self-adaptation too frequently. While the need
for adaptation is never eliminated, especially noting the uncertain and
evolving environment of complex systems, reducing the frequency of adaptation
interventions is advantageous for various reasons, e.g., to increase
performance and to make a running system more robust. We instantiate and
empirically examine the above idea for software-defined networking -- a key
enabling technology for modern data centres and Internet of Things
applications. Using genetic programming,(GP), we propose a self-adaptation
solution that continuously learns and updates the control constructs in the
data-forwarding logic of a software-defined network. Our evaluation, performed
using open-source synthetic and industrial data, indicates that, compared to a
baseline adaptation technique that attempts to generate individual adaptations,
our GP-based approach is more effective in resolving network congestion, and
further, reduces the frequency of adaptation interventions over time. In
addition, we show that, for networks with the same topology, reusing over
larger networks the knowledge that is learned on smaller networks leads to
significant improvements in the performance of our GP-based adaptation
approach. Finally, we compare our approach against a standard data-forwarding
algorithm from the network literature, demonstrating that our approach
significantly reduces packet loss.
