This documentation provides a comprehensive explanation of the proposed system, focusing on its ability to manage conditional events and support dynamic adaptation. The structure follows a logical flow, from an introduction to detailed architectural explanations, using a component diagram, sequence diagram, and class diagram.
- Introduction
- Architecture Overview
- Metrics Collection
- Scenario Overview
- Adaptation Actions
- Applications
- Conclusion
The proposed system is designed to dynamically respond to changing conditions using a combination of metrics evaluation, event management, and adaptation actions. The key objectives include:
- Management of Conditional Events: The system evaluates metrics against predefined conditions and triggers events when conditions are met.
- Observer Pattern Integration: Observers (subscribers) are notified of events to execute relevant adaptation actions.
- Dynamic Adaptation: Enables the system to respond to changes in metrics by triggering specific actions, such as scaling resources or modifying system behavior.
- Flexibility and Extensibility: The modular design supports various metrics, conditions, and actions, making it adaptable to diverse scenarios.
The component diagram provides a high-level view of the system's components and their interactions. The main components include:
- Metrics Collector: Collects real-time metrics (e.g., CPU usage, response times).
- Event Manager: Central component that evaluates conditions and manages events.
- Condition Evaluators: Evaluate whether metrics meet predefined conditions (e.g.,
GreaterThanEvaluator). - Event Subscribers: Observers notified when events are triggered.
- Adaptation Actions: Actions executed in response to triggered events.
- Metrics Collection:
- Metrics are collected periodically by the
Metrics Collector.
- Metrics are collected periodically by the
- Condition Evaluation:
- The
Event Managerevaluates collected metrics against conditions usingCondition Evaluators.
- The
- Event Triggering:
- If a condition is satisfied, the
Event Managertriggers an event and notifies subscribers.
- If a condition is satisfied, the
- Adaptation Action Execution:
- Subscribers execute adaptation actions, such as scaling resources or enabling specific features.
- Monitoring CPU Usage:
- The system monitors server CPU usage using a
LocalCpuUsageCollectorto gather metrics. When the CPU usage exceeds 80%, theIncreaseEventis triggered. This event notifies a list of subscribers, which areEventSubscriberinstances that execute theLowPowerModeadaptation action to reduce load. Similarly, if usage falls below 50%, aDecreaseEventtriggers the subscribers to switch back to aNormalMode. The process is dynamically managed through theContinuousObservationScheduler, as illustrated below:
- The system monitors server CPU usage using a
// Define adaptation actions
List<IAdaptationAction> lowPowerActions = List.of(new LowPowerMode());
List<IAdaptationAction> normalModeActions = List.of(new NormalMode());
// Create event subscribers
List<Observer<Double>> highUsageSubscribers = List.of(new EventSubscriber<>(lowPowerActions));
List<Observer<Double>> lowUsageSubscribers = List.of(new EventSubscriber<>(normalModeActions));
// Set up metrics collector and threshold
IMetricsCollector<Double> cpuCollector = new LocalCpuUsageCollector();
ThresholdProvider<Double> highUsageThreshold = () -> 80.0;
ThresholdProvider<Double> lowUsageThreshold = () -> 50.0;
// Create and configure events
IncreaseEvent<Double> highUsageEvent = new IncreaseEvent<>(cpuCollector, highUsageThreshold);
highUsageEvent.subscribeAll(highUsageSubscribers);
DecreaseEvent<Double> lowUsageEvent = new DecreaseEvent<>(cpuCollector, lowUsageThreshold);
lowUsageEvent.subscribeAll(lowUsageSubscribers);
// Schedule continuous event listening
ContinuousObservationScheduler scheduler = new ContinuousObservationScheduler(
List.of(highUsageEvent, lowUsageEvent), EVENT_LISTENING_INTERVAL_MS);
scheduler.start();
The sequence diagram illustrates the runtime interaction between components. The primary steps include:
- Observation Scheduler Initiation:
- The
Observation Schedulerinitiates monitoring and requests metrics periodically.
- The
- Metrics Collection:
- The
Metrics Collectorgathers metrics and sends them to theEvent Manager.
- The
- Condition Evaluation:
- The
Event Managerevaluates metrics against conditions usingCondition Evaluators. For example, it checks ifCPU > 80%.
- The
- Event Notification:
- The
Event Managernotifies subscribers about the triggered event.
- The
- Action Execution:
- Subscribers execute adaptation actions. For example, one subscriber logs the event, while another scales resources.
- Response Time Monitoring:
- The system monitors web server response time.
- If response time exceeds 1 second, an event is triggered.
- Subscribers execute actions like enabling caching or throttling traffic.
The class diagram provides a detailed view of the system's architecture, showcasing its main classes, interfaces, and relationships.
-
Interfaces:
- IMetricsCollector: Defines the interface for collecting metrics.
- Method:
get()- Retrieves the current metric value.
- Method:
- ThresholdProvider: Supplies threshold values for condition evaluation.
- Method:
getThreshold()- Returns a threshold value.
- Method:
- IMetricsCollector: Defines the interface for collecting metrics.
-
Classes:
- Event: Base class representing a generic event.
- Main Methods:
subscribe(Observer<T>)- Registers an observer.notifyObservers(T metricValue)- Notifies all observers/subscribers of a metric value.
- Main Methods:
- Example:
- IncreaseEvent, DecreaseEvent: Handle conditions involving metric increases or decreases.
- Condition Evaluators:
- Examples:
GreaterThanEvaluator,LessThanEvaluatorevaluate metrics against conditions. - Method:
test(T metric)- Returns true/false based on the value of the metric collected.
- Examples:
- ObservationScheduler: Manages events observation.
- Subclasses:
SingleObservationScheduler: Triggers an observation.ContinuousObservationScheduler: Triggers observations periodically.
- Subclasses:
- EventSubscriber: Listens for notifications and executes actions.
- Fields:
actions: List of actions to perform.conditionEvaluator: Evaluates conditions for triggering actions.
- Fields:
- Event: Base class representing a generic event.
- Uses:
- The
Eventclass usesIMetricsCollectorto access metrics. ConditionEvaluatorinteracts withThresholdProviderto fetch thresholds.
- The
- Inheritance:
GreaterThanEvaluator,LessThanEvaluator, and others inherit fromConditionEvaluator.
- Composition:
EventSubscribercontains a list ofAdaptationActionobjects.
public class GreaterThanEvaluator<T extends Comparable<T>> implements ConditionEvaluator<T> {
private T bound;
public GreaterThanEvaluator(T bound) {
this.bound = bound;
}
@Override
public boolean test(T metric) {
return metric.compareTo(bound) > 0;
}
}
Event<Integer> highCpuEvent = new IncreaseEvent<>(new CpuMetricsCollector(), new ThresholdProvider<>(80));
highCpuEvent.subscribe(new ResourceScalerAction());Metrics collection is at the core of the Adaptation Framework, ensuring that real-time data is available for adaptive decision-making. The framework supports various types of metrics, including CPU, memory, requests, database performance, service state, and response time.
The framework provides a family of collectors to support various system metrics:
| Category | Collectors (Local & Remote) |
|---|---|
| CPU Usage | LocalCpuUsageCollector, RemoteCpuUsageCollector, RemoteCpuUsagePerInstanceCollector, RemoteCpuUsageAllLoadBalancedServiceCollector, RemoteCpuUsageAllServiceCollector, RemoteRegistryCpuUsageCollector |
| Memory Usage | LocalMemoryUsageCollector, RemoteMemoryUsageCollector, RemoteMemoryUsagePerInstanceCollector, RemoteMemoryUsageAllLoadBalancedServiceCollector, RemoteMemoryUsageAllServiceCollector, RemoteRegistryMemoryUsageCollector |
| Requests | LocalRequestMetricsCollector, RemoteRequestMetricsCollector, RemoteRequestMetricsPerInstanceCollector, RemoteRequestMetricsAllLoadBalancedServiceCollector, RemoteRequestMetricsAllServiceCollector, RemoteRegistryRequestMetricsCollector |
| Response Time | RemoteResponseTimeCollector, RemoteResponseTimePerInstanceCollector, RemoteResponseTimeAllLoadBalancedServiceCollector, RemoteResponseTimeAllServiceCollector, RemoteRegistryResponseTimeCollector |
| Database | LocalDatabaseMetricsCollector, RemoteDatabaseMetricsCollector, LocalDatabaseResponseTimeCollector, RemoteDatabaseResponseTimeCollector |
| Service State | RemoteServiceStateCollector, RemoteServiceStatePerInstanceCollector, RemoteServiceStateAllLoadBalancedCollector, RemoteServiceStateAllServiceCollector, RemoteRegistryStateCollector |
| Service Status | RemoteServiceStatusCollector, RemoteServiceStatusPerInstanceCollector, RemoteServiceStatusAllLoadBalancedCollector, RemoteServiceStatusAllServiceCollector, RemoteRegistryStatusCollector |
Each collector is designed to either:
- Collect local system metrics from a running service.
- Fetch remote metrics via REST API calls.
The LocalCpuUsageCollector retrieves CPU usage metrics from the Java Management Extensions (JMX).
LocalCpuUsageCollector cpuUsageCollector = new LocalCpuUsageCollector();
double currentCpuUsage = cpuUsageCollector.get();
System.out.println("Current CPU Usage: " + currentCpuUsage + "%")The RemoteCpuUsageCollector fetches CPU metrics from a remote service using a REST API call.
RemoteCpuUsageCollector cpuUsageCollector = new RemoteCpuUsageCollector(Service.AUTH, "metrics/cpu");
double currentCpuUsage = cpuUsageCollector.get();
System.out.println("Current Remote CPU Usage: " + currentCpuUsage + "%");This allows monitoring CPU usage across microservices in a distributed system.
Note: Each service in the Adaptable TeaStore exposes a REST API endpoint to provide its metrics.
| Metric | Endpoint | HTTP Method |
|---|---|---|
| CPU Usage | /metrics/cpu |
GET |
| Memory Usage | /metrics/memory |
GET |
| Request Count | /metrics/requests |
GET |
| Response Time | /metrics/status |
GET |
| Database Status | /metrics/database |
POST |
| Service State | /metrics/state |
GET |
| Service Status | /metrics/status |
GET |
curl -X GET http://service-instance:8080/metrics/cpu| Adaptation Action | Description | Applicable Services |
|---|---|---|
| OpenCircuitBreaker | Opens the circuit breaker to prevent service failures. | Auth, Image, Registry, Persistence, Recommender, WebUI |
| HighPerformanceMode | Switches to high-performance mode using an optimized algorithm. | Recommender |
| LowPowerMode | Switches to low-power mode, disabling recommendations. | Recommender |
| NormalMode | Restores the recommender to normal operation. | Recommender |
| EnableCache | Enables caching to improve database performance. | Persistence |
| DisableCache | Disables caching to reduce memory usage. | Persistence |
| MaintenanceMode | Activates a maintenance page to inform users of issues. | WebUI |
In a distributed system, an attacker might attempt a brute-force attack by sending thousands of authentication requests to the Auth Service in a short time. This could cause the service to slow down or crash, impacting system availability.
By opening the circuit breaker, the system temporarily blocks access to the authentication service, preventing excessive resource consumption.
// Block authentication requests for 60 seconds
IAdaptationAction openCircuitBreaker = new OpenCircuitBreaker(60);
openCircuitBreaker.perform();- Once executed, authentication requests will be blocked for 60 seconds, mitigating the attack.
- After the timeout expires, the circuit breaker automatically resets, allowing normal authentication requests.
Note: All services of the Adaptable TeaStore expose these REST API endpoints, allowing adaptation actions to be triggered dynamically.
| Action Type | Endpoint | HTTP Method | Request Parameters |
|---|---|---|---|
| Execute multiple actions | /adapt |
POST |
Body (JSON): A list of action names to be executed. Example: ["OpenCircuitBreaker", "EnableCache"] |
| Execute a single action | /adapt/single |
POST |
Query Parameter: actionName - The name of the action to execute. Example: ?actionName=OpenCircuitBreaker |
curl -X POST "http://auth-service:8080/adapt/single?actionName=OpenCircuitBreaker"The system is applicable in various domains, including:
-
Monitoring and Alerts:
- Detecting anomalies (e.g., high error rates) and triggering notifications.
- Example: Sending alerts when memory usage exceeds a threshold.
-
Dynamic Resource Allocation:
- Adjusting resources based on system load.
- Example: Scaling up servers during high traffic.
-
Performance Optimization:
- Automating actions to optimize performance.
- Example: Enabling caching when response time increases.
-
Real-Time Decision Systems:
- Adapting system behavior based on real-time conditions.
- Example: Throttling API requests during peak usage.
The proposed system is a robust framework for dynamic event management and adaptation. Its modular design ensures:
- Scalability: Easily handles complex adaptation strategies.
- Flexibility: Supports new metrics, conditions, and actions.
- Maintainability: Clear separation of concerns simplifies development and extension.
By understanding the architecture and components described above, stakeholders can effectively implement and extend the system to meet evolving requirements.


