You are here

protected function SensorDataController::handleAssetRequest in farmOS 2.x

Helper function to handle the request once the asset has been loaded.

Parameters

\Drupal\asset\Entity\AssetInterface $asset: The asset.

\Symfony\Component\HttpFoundation\Request $request: The request.

Return value

\Symfony\Component\HttpFoundation\Response The response.

2 calls to SensorDataController::handleAssetRequest()
SensorDataController::uuid in modules/asset/sensor/src/Controller/SensorDataController.php
Respond to GET or POST requests referencing sensor assets by UUID.
SensorListenerController::publicKey in modules/asset/sensor/modules/listener/src/Controller/SensorListenerController.php
Respond to GET or POST requests referencing sensor assets by public_key.

File

modules/asset/sensor/src/Controller/SensorDataController.php, line 91

Class

SensorDataController
Handles requests for basic data streams associated with a sensor.

Namespace

Drupal\farm_sensor\Controller

Code

protected function handleAssetRequest(AssetInterface $asset, Request $request) {

  /** @var \Drupal\data_stream\Entity\DataStreamInterface[] $data_streams */
  $data_streams = $asset
    ->get('data_stream')
    ->referencedEntities();
  $basic_data_streams = array_filter($data_streams, function ($data_stream) {
    return $data_stream
      ->bundle() === 'basic';
  });

  // Get request method.
  $method = $request
    ->getMethod();
  switch ($method) {
    case Request::METHOD_GET:

      // Bail if the sensor is not public and no private_key is provided.
      if (!$asset
        ->get('public')->value && !$this
        ->requestHasValidPrivateKey($asset, $request)) {
        throw new AccessDeniedHttpException();
      }
      $params = $request->query
        ->all();
      $max_limit = 100000;
      $limit = $max_limit;
      if (isset($params['limit'])) {
        $limit = $params['limit'];

        // Bail if more than the max is requested.
        // Only allow 100k max data points to prevent exhausting PHP's memory,
        // which is a potential DDoS vector.
        if ($limit > $max_limit) {
          throw new UnprocessableHttpEntityException();
        }
      }
      $params['limit'] = $limit;
      $data = $this->basicDataStream
        ->storageGetMultiple($basic_data_streams, $params);
      return JsonResponse::create($data);
    case Request::METHOD_POST:

      // Bail if no private_key is provided.
      if (!$this
        ->requestHasValidPrivateKey($asset, $request)) {
        throw new AccessDeniedHttpException();
      }

      // Load the data.
      $data = Json::decode($request
        ->getContent());

      // Check for new named values.
      $unique_names = $this
        ->getUniqueNamedValues($data);
      $existing_names = array_map(function ($data_stream) {
        return $data_stream
          ->label();
      }, $basic_data_streams);

      // Create new data streams for new named values.
      foreach ($unique_names as $name) {
        if (!in_array($name, $existing_names)) {
          $basic_data_streams[] = $this
            ->createDataStream($asset, $name);
        }
      }

      // Allow each data stream to process the data.
      foreach ($basic_data_streams as $data_stream) {
        $this->basicDataStream
          ->storageSave($data_stream, $data);
      }
      return Response::create('', Response::HTTP_CREATED);
  }

  // Else raise error.
  throw new MethodNotAllowedHttpException($this->basicDataStream
    ->apiAllowedMethods());
}