ApiController::storeValue()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 10
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 17
ccs 11
cts 11
cp 1
crap 3
rs 9.9332
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Interfaces\Http;
6
7
use App\Domain\Model\ObjectEntry;
8
use App\Domain\Service\ObjectStoreInterface;
9
use DateTime;
10
use OpenApi\Annotations as OA;
11
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
12
use Symfony\Component\HttpFoundation\JsonResponse;
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\HttpFoundation\Response;
15
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
16
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
17
use Symfony\Component\Routing\Annotation\Route;
18
19
/**
20
 * @Route("/object")
21
 * @OA\Tag(name="Object Store")
22
 */
23
class ApiController extends AbstractController
24
{
25
    protected ObjectStoreInterface $objectStorage;
26
27 8
    public function __construct(ObjectStoreInterface $objectStorage)
28
    {
29 8
        $this->objectStorage = $objectStorage;
30 8
    }
31
32
    /**
33
     * @OA\RequestBody(
34
     *     description="Key-value pairs to store",
35
     *     required=true,
36
     *     @OA\JsonContent(example={"key": "value"}, @OA\Schema(type="object", additionalProperties=true))
37
     * )
38
     * @OA\Response(
39
     *     response="201",
40
     *     description="On success",
41
     *     headers={@OA\Header(header="X-Timestamp", @OA\Schema(type="integer"), description="Current server timestamp")}
42
     * )
43
     * @OA\Response(response="400", description="When provided object is not valid")
44
     *
45
     * @Route("", name="api_upsert_object", methods={"POST"}, defaults={"_format": "json"})
46
     */
47 4
    public function storeValue(Request $request)
48
    {
49 4
        $objects = json_decode($request->getContent(), true);
50
51 4
        if (!is_iterable($objects)) {
52 3
            throw new BadRequestHttpException();
53
        }
54
55 1
        foreach ($objects as $key => $object) {
56 1
            $entry = new ObjectEntry($key, $object);
57 1
            $this->objectStorage->store($entry, new DateTime());
58
        }
59
60 1
        return new JsonResponse(
61 1
            null,
62 1
            Response::HTTP_CREATED,
63 1
            ['X-Timestamp' => time()]
64
        );
65
    }
66
67
    /**
68
     * @OA\Parameter(name="key", in="path", description="Key to display value for", @OA\Schema(type="string"))
69
     * @OA\Parameter(name="timestamp", in="query", description="Timestamp of the value snapshot", @OA\Schema(type="integer"), required=false)
70
     * @OA\Response(
71
     *     response="200",
72
     *     description="Value for the key at given time (or now)",
73
     *     @OA\Schema(type="object", example="test-value"),
74
     *     headers={@OA\Header(header="X-Timestamp", schema=@OA\Schema(type="integer"), description="Current server timestamp")}
75
     * )
76
     * @OA\Response(response="400", description="When provided timestamp is invalid")
77
     * @OA\Response(response="404", description="When key is not found (for provided time)")
78
     *
79
     * @Route("/{key}", name="api_get_value", methods={"GET"}, defaults={"_format": "json"})
80
     */
81 4
    public function getValue(string $key, Request $request)
82
    {
83 4
        $date = DateTime::createFromFormat('U', (string) $request->get('timestamp', time()));
84
85 4
        if (!$date instanceof DateTime) {
86 1
            throw new BadRequestHttpException('Invalid time');
87
        }
88
89 3
        $value = $this->objectStorage->get($key, $date);
90
91 3
        if (!$value) {
92 1
            throw new NotFoundHttpException();
93
        }
94
95 2
        return new JsonResponse(
96 2
            $value->getValue(),
97 2
            Response::HTTP_OK,
98 2
            ['X-Timestamp' => time()]
99
        );
100
    }
101
}
102