/**
  * @param Application $app
  */
 protected function bootstrapDreamFactory($app)
 {
     //  Get an instance of the cluster service
     $app->register(new ClusterServiceProvider($app));
     /** @type ClusterService $_cluster */
     $_cluster = ClusterServiceProvider::service($app);
     $_vars = ['DF_CACHE_PREFIX' => $_cluster->getCachePrefix(), 'DF_CACHE_PATH' => $_cluster->getCachePath(), 'DF_LIMITS_CACHE_STORE' => ManagedDefaults::DEFAULT_LIMITS_STORE, 'DF_LIMITS_CACHE_PATH' => Disk::path([$_cluster->getCacheRoot(), '.limits'], true), 'DF_MANAGED_SESSION_PATH' => Disk::path([$_cluster->getCacheRoot(), '.sessions'], true), 'DF_MANAGED_LOG_FILE' => $_cluster->getHostName() . '.log', 'DF_MANAGED' => true, 'DB_DRIVER' => 'mysql'];
     //  Get the cluster database information
     foreach ($_cluster->getDatabaseConfig() as $_key => $_value) {
         $_vars['DB_' . strtr(strtoupper($_key), '-', '_')] = $_value;
     }
     //  Throw in some paths
     if (!empty($_paths = $_cluster->getConfig('paths', []))) {
         foreach ($_paths as $_key => $_value) {
             $_vars['DF_MANAGED_' . strtr(strtoupper($_key), '-', '_')] = $_value;
         }
     }
     //  If this is a console request, denote it as such
     $_vars['DF_CONSOLE_KEY'] = $_cluster->getConsoleKey();
     //  Is it a console request? Validate
     /** @type Request $_request */
     $_request = $app->make('request');
     $_vars['DF_IS_VALID_CONSOLE_REQUEST'] = $_vars['DF_CONSOLE_KEY'] == $_request->header(ManagedDefaults::CONSOLE_X_HEADER, $_request->query('console_key'));
     //  Now jam everything into the environment
     foreach ($_vars as $_key => $_value) {
         putenv($_key . '=' . $_value);
         $_ENV[$_key] = $_value;
         $_SERVER[$_key] = $_value;
     }
     //  Finally, let the cluster service push some middleware onto the stack
     if ($_cluster instanceof HasMiddleware) {
         $_cluster->pushMiddleware($app->make('Illuminate\\Contracts\\Http\\Kernel'));
     }
 }
 /**
  * Handle an incoming request.
  *
  * @param  \Illuminate\Http\Request $request
  * @param  \Closure                 $next
  *
  * @return mixed
  */
 public function handle(Request $request, Closure $next)
 {
     /**
      * It is assumed, if you get this far, that ClusterServiceProvider was registered via
      * the ManagedInstance bootstrapper. If not, you're in a world of shit.
      *
      * We use provider's service() method because Facades are not loaded yet
      */
     $_cluster = ClusterServiceProvider::service();
     //  Get limits or bail
     if (!$_cluster instanceof ProvidesManagedLimits || empty($limits = $_cluster->getLimits())) {
         return $next($request);
     }
     $this->testing = config('api_limits_test', 'testing' == env('APP_ENV'));
     if (!empty($limits)) {
         $userName = $this->getUser(Session::getCurrentUserId());
         $userRole = $this->getRole(Session::getRoleId());
         $apiName = $this->getApiKey(Session::getApiKey());
         $clusterName = $_cluster->getClusterId();
         $instanceName = $_cluster->getInstanceName();
         $serviceName = $this->getServiceName($request);
         $limits = json_encode($limits);
         //TODO: Update dfe-console to properly set this, but right now, we want to touch as few files as possible
         if (!$this->testing) {
             $limits = str_replace(['cluster.default', 'instance.default'], [$clusterName, $clusterName . '.' . $instanceName], $limits);
         }
         //  Convert to an array
         $limits = json_decode($limits, true);
         //  Build the list of API Hits to check
         $apiKeysToCheck = [$clusterName . '.' . $instanceName => 0];
         $serviceKeys = [];
         if ($serviceName) {
             $serviceKeys[$serviceName] = 0;
             $userRole && ($serviceKeys[$serviceName . '.' . $userRole] = 0);
             $userName && ($serviceKeys[$serviceName . '.' . $userName] = 0);
         }
         if ($apiName) {
             $apiKeysToCheck[$clusterName . '.' . $instanceName . '.' . $apiName] = 0;
             $userRole && ($apiKeysToCheck[$clusterName . '.' . $instanceName . '.' . $apiName . '.' . $userRole] = 0);
             $userName && ($apiKeysToCheck[$clusterName . '.' . $instanceName . '.' . $apiName . '.' . $userName] = 0);
             foreach ($serviceKeys as $key => $value) {
                 $apiKeysToCheck[$apiName . '.' . $key] = $value;
             }
         }
         if ($clusterName) {
             $apiKeysToCheck[$clusterName] = 0;
             $userRole && ($apiKeysToCheck[$clusterName . '.' . $instanceName . '.' . $userRole] = 0);
             $userName && ($apiKeysToCheck[$clusterName . '.' . $instanceName . '.' . $userName] = 0);
             foreach ($serviceKeys as $key => $value) {
                 $apiKeysToCheck[$clusterName . '.' . $instanceName . '.' . $key] = $value;
             }
         }
         /* Per Ben, we want to increment every limit they hit, not stop after the first one */
         $overLimit = [];
         try {
             foreach (array_keys($apiKeysToCheck) as $key) {
                 foreach ($this->periods as $period) {
                     $_checkKey = $key . '.' . $period;
                     /** @noinspection PhpUndefinedMethodInspection */
                     if (array_key_exists($_checkKey, $limits['api'])) {
                         $_limit = $limits['api'][$_checkKey];
                         // For any cache drivers that make use of the cache prefix, we need to make sure we use
                         // a prefix that every instance can see.  But first, grab the current value
                         $dfCachePrefix = env('DF_CACHE_PREFIX');
                         putenv('DF_CACHE_PREFIX' . '=' . 'df_limits');
                         $_ENV['DF_CACHE_PREFIX'] = $_SERVER['DF_CACHE_PREFIX'] = 'df_limits';
                         //  Increment counter
                         $cacheValue = $this->cache()->get($_checkKey, 0);
                         $cacheValue++;
                         if ($cacheValue > $_limit['limit']) {
                             // Push the name of the rule onto the over-limit array so we can give the name in the 429 error message
                             $overLimit[] = array_get($_limit, 'name', $_checkKey);
                         } else {
                             // Only increment the counter if we are not over the limit.  Fixes DFE-205
                             $this->cache()->put($_checkKey, $cacheValue, $_limit['period']);
                         }
                         // And now set it back
                         putenv('DF_CACHE_PREFIX' . '=' . $dfCachePrefix);
                         $_ENV['DF_CACHE_PREFIX'] = $_SERVER['DF_CACHE_PREFIX'] = $dfCachePrefix;
                     }
                 }
             }
         } catch (\Exception $_ex) {
             return ResponseFactory::getException(new InternalServerErrorException('Unable to update cache: ' . $_ex->getMessage()), $request);
         }
         if ($overLimit) {
             /* Per Ben, we want to increment every limit they hit, not stop after the first one */
             return ResponseFactory::getException(new TooManyRequestsException('API limit(s) exceeded: ' . implode(', ', $overLimit)), $request);
         }
     }
     return $next($request);
 }