All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.hyperfoil.http.handlers.MultiplexStatusHandler Maven / Gradle / Ivy

There is a newer version: 0.27.1
Show newest version
package io.hyperfoil.http.handlers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.kohsuke.MetaInfServices;

import io.hyperfoil.api.config.BenchmarkDefinitionException;
import io.hyperfoil.api.config.Name;
import io.hyperfoil.api.config.PartialBuilder;
import io.hyperfoil.http.api.HttpRequest;
import io.hyperfoil.http.api.StatusHandler;
import io.hyperfoil.api.session.ResourceUtilizer;
import io.hyperfoil.api.session.Session;
import io.hyperfoil.core.builders.ServiceLoadedBuilderProvider;

public class MultiplexStatusHandler extends BaseRangeStatusHandler implements ResourceUtilizer {
   private final StatusHandler[][] handlers;
   private final StatusHandler[] other;

   public MultiplexStatusHandler(int[] ranges, StatusHandler[][] handlers, StatusHandler[] other) {
      super(ranges);
      this.handlers = handlers;
      this.other = other;
   }

   @Override
   protected void onStatusRange(HttpRequest request, int status, int index) {
      for (StatusHandler h : handlers[index]) {
         h.handleStatus(request, status);
      }
   }

   @Override
   protected void onOtherStatus(HttpRequest request, int status) {
      if (other != null) {
         for (StatusHandler h : other) {
            h.handleStatus(request, status);
         }
      }
   }

   @Override
   public void reserve(Session session) {
      for (StatusHandler[] hs : handlers) {
         ResourceUtilizer.reserve(session, (Object[]) hs);
      }
      ResourceUtilizer.reserve(session, (Object[]) other);
   }

   /**
    * Multiplexes the status based on range into different status handlers.
    */
   @MetaInfServices(StatusHandler.Builder.class)
   @Name("multiplex")
   public static class Builder implements StatusHandler.Builder, PartialBuilder {
      private final Map> handlers = new HashMap<>();

      /**
       * Run another handler if the range matches. Use range as the key and another status handler in the mapping.
       * Possible values of the status should be separated by commas (,). Ranges can be set using low-high (inclusive) (e.g. 200-299), or replacing lower digits with 'x' (e.g. 2xx).
       *
       * @param range Status range.
       * @return Builder
       */
      @Override
      public ServiceLoadedBuilderProvider withKey(String range) {
         List handlers = new ArrayList<>();
         add(range, handlers);
         return new ServiceLoadedBuilderProvider<>(StatusHandler.Builder.class, handlers::add);
      }

      public Builder add(String range, List handlers) {
         if (this.handlers.putIfAbsent(range, handlers) != null) {
            throw new BenchmarkDefinitionException("Range '" + range + "' is already set.");
         }
         return this;
      }

      @Override
      public MultiplexStatusHandler build() {
         List ranges = new ArrayList<>();
         List handlers = new ArrayList<>();
         StatusHandler[] other = checkAndSortRanges(this.handlers, ranges, handlers, list -> list.stream().map(StatusHandler.Builder::build).toArray(StatusHandler[]::new));
         return new MultiplexStatusHandler(ranges.stream().mapToInt(Integer::intValue).toArray(), handlers.toArray(new StatusHandler[0][]), other);
      }
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy