From 06fa009c632c19e57693005ff8eb21c0a1daabde Mon Sep 17 00:00:00 2001
From: git <git@787980.no-reply.drupal.org>
Date: Tue, 10 Jan 2017 12:06:14 -0500
Subject: [PATCH] Adds LoggingTrait and LoggingLevels class

Updates QueueHandler to use LoggingTrait
Improves commenting in QueueHandler
Updates TestQueueHandler to override LoggingTrait::log under test
Adds too many queue item test to QueuehandlerTest
---
 modules/salesforce_pull/src/QueueHandler.php  | 52 +++++++++++++------
 src/LoggingLevels.php                         | 29 +++++++++++
 src/LoggingTrait.php                          | 30 +++++++++++
 .../src/salesforce_pull/TestQueueHandler.php  | 11 +++-
 4 files changed, 103 insertions(+), 19 deletions(-)
 create mode 100644 src/LoggingLevels.php
 create mode 100644 src/LoggingTrait.php

diff --git a/modules/salesforce_pull/src/QueueHandler.php b/modules/salesforce_pull/src/QueueHandler.php
index 3ccd5fe5..4aa7877f 100644
--- a/modules/salesforce_pull/src/QueueHandler.php
+++ b/modules/salesforce_pull/src/QueueHandler.php
@@ -9,6 +9,8 @@ use Drupal\salesforce\Rest\RestClient;
 use Drupal\salesforce_mapping\Entity\SalesforceMapping;
 use Drupal\salesforce_mapping\Entity\SalesforceMappingInterface;
 use Drupal\salesforce\Exception;
+use Drupal\salesforce\LoggingTrait;
+use Drupal\salesforce\LoggingLevels;
 
 /**
  * Handles pull cron queue set up.
@@ -17,6 +19,9 @@ use Drupal\salesforce\Exception;
  */
 
 class QueueHandler {
+
+  use LoggingTrait;
+
   protected $sfapi;
   protected $queue;
   protected $mappings;
@@ -34,7 +39,11 @@ class QueueHandler {
    * Chainable instantiation method for class
    *
    * @param object
-   *  RestClient object
+   *   RestClient object
+   * @param array
+   *   Arry of SalesforceMapping objects
+   *
+   * @return QueueHandler
    */
   public static function create(RestClient $sfapi, array $mappings, QueueInterface $queue) {
     return new QueueHandler($sfapi, $mappings, $queue);
@@ -45,18 +54,27 @@ class QueueHandler {
    *
    * Executes a SOQL query based on defined mappings, loops through the results,
    * and places each updated SF object into the queue for later processing.
+   *
+   * @return boolean
    */
   public function getUpdatedRecords() {
     // Avoid overloading the processing queue and pass this time around if it's
     // over a configurable limit.
     if ($this->queue->numberOfItems() > $this->stateGet('salesforce_pull_max_queue_size', 100000)) {
-      // @TODO add admin / logging alert here. This is a critical condition. When our queue is maxed out, pulls will be completely blocked.
-      return;
+      $this->log(
+        'Salesforce Pull',
+        LoggingLevels::ALERT,
+        'Pull Queue contains %noi items, exceeding the max size of %max items. Pull processing will be blocked until the number of items in the queue is reduced to below the max size.',
+        [
+          '%noi' => $this->queue->numberOfItems(),
+          '%max' => $this->stateGet('salesforce_pull_max_queue_size', 100000),
+        ]
+      );
+      return false;
     }
 
     // Iterate over each field mapping to determine our query parameters.
     foreach ($this->mappings as $mapping) {
-      // @TODO: This may need a try-catch? all of the following methods will exception catch themselves
       $results = $this->doSfoQuery($mapping);
       $this->insertIntoQueue($mapping, $results->records());
       $this->handleLargeRequests($mapping, $results);
@@ -69,12 +87,8 @@ class QueueHandler {
   }
 
   /**
-   * Fetches all mappings, sortes them by the SF object type, and adds an
-   * array of pull fields to each mappings
-   *
-   * @return array
-   *   Array of array of distinct mappings indexed by SF object type and array
-   *   of field mappings
+   * Iterates over the mappings and mergeds the pull fields array with object's
+   * array of pull fields to form a set of unique fields to pull.
    */
   protected function organizeMappings() {
     foreach($this->mappings as $mapping) {
@@ -91,8 +105,8 @@ class QueueHandler {
    * @param SalesforceMappingInterface
    *   Mapping for which to execute pull
    *
-   * @return array
-   *   Array of field smappings
+   * @return SelectQueryResult
+   *   returned result object from Salesforce
    */
   protected function doSfoQuery(SalesforceMappingInterface $mapping) {
     // @TODO figure out the new way to build the query.
@@ -124,10 +138,12 @@ class QueueHandler {
   }
 
   /**
-   * Handle requests larger than the batch limit (usually 2000).
+   * Handle requests larger than the batch limit (usually 2000) recursively.
    *
-   * @param array
-   *   Original list of results, which includes batched records fetch URL
+   * @param SalesforceMappingInterface
+   *   Mapping object currently being processed
+   * @param SelectQueryResult
+   *   Results, which includes batched records fetch URL
    */
   protected function handleLargeRequests(SalesforceMappingInterface $mapping, SelectQueryResult $results) {
    if ($results->nextRecordsUrl() != null) {
@@ -147,8 +163,10 @@ class QueueHandler {
   /**
    * Inserts results into queue
    *
-   * @param object
-   *   Result set
+   * @param SalesforceMappingInterface
+   *   Mapping object currently being processed
+   * @param array
+   *   Result record set
    */
   protected function insertIntoQueue(SalesforceMappingInterface $mapping, array $records) {
     try {
diff --git a/src/LoggingLevels.php b/src/LoggingLevels.php
new file mode 100644
index 00000000..a0541b78
--- /dev/null
+++ b/src/LoggingLevels.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\salesforce;
+
+/**
+ * Defines events for Salesforce.
+ *
+ * @see \Drupal\salesforce\SalesforceEvent
+ */
+final class LoggingLevels {
+
+  /**
+   * Name of the logging level method using in Drupal::logger.
+   *
+   * Restricts list to valid levels
+   *
+   * @Level
+   *
+   * @var string
+   */
+  const EMERGENCY = 'emergency';
+  const ALERT = 'alert';
+  const CRITIAL = 'critical';
+  const ERROR = 'error';
+  const WARNING = 'warning';
+  const NOTICE = 'notice';
+  const INFO = 'info';
+  const DEBUG = 'debug';  
+}
diff --git a/src/LoggingTrait.php b/src/LoggingTrait.php
new file mode 100644
index 00000000..26087dca
--- /dev/null
+++ b/src/LoggingTrait.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Drupal\salesforce;
+
+/**
+ * Provides a trait for Drupal logger wrapper method.
+ */
+trait LoggingTrait {
+
+  /**
+   * Wrapper method for logging, added for testability
+   *
+   * @param string
+   *   Module name
+   * @param string
+   *   Severity level, see LoggingLevels
+   * @param string
+   *   message, with tokens is appropriate
+   * @param array
+   *   placeholders for tokens, if appriate
+   */
+   public function log($name, $level, $message, array $placeholders = []) {
+     if (!empty($placeholders)) {
+       \Drupal::logger($name)->$level($message, $placeholders);
+     }
+     else {
+       \Drupal::logger($name)->$level($message);
+     }
+   }
+}
diff --git a/tests/src/salesforce_pull/TestQueueHandler.php b/tests/src/salesforce_pull/TestQueueHandler.php
index fb97a9ec..de26a637 100644
--- a/tests/src/salesforce_pull/TestQueueHandler.php
+++ b/tests/src/salesforce_pull/TestQueueHandler.php
@@ -10,6 +10,7 @@ use Drupal\salesforce\Rest\RestClient;
 use Drupal\salesforce_mapping\Entity\SalesforceMapping;
 use Drupal\salesforce_mapping\Entity\SalesforceMappingInterface;
 use Drupal\salesforce\Exception;
+
 /**
  * Handles pull cron queue set up.
  *
@@ -54,7 +55,7 @@ class TestQueueHandler extends QueueHandler {
   }
 
   /**
-   * Overrides parent:: requestTime()
+   * Overrides parent::requestTime()
    * Wrapper for \Drupal::request()
    */
   protected function requestTime() {
@@ -62,9 +63,15 @@ class TestQueueHandler extends QueueHandler {
   }
 
   /**
-   * Overrides parent:: watchdogException
+   * Overrides parent::watchdogException
    * Wrapper for watchdog_exception()
    */
   protected function watchdogException(\Exception $e) {
   }
+
+  /**
+   * Ovverides parent::log()
+   */
+  public function log($name, $level, $message, array $placeholders = []) {
+  }
 }
-- 
GitLab