Could you translate this php symfony code to a kotlin + spring boot project, using springdoc annotations, don't take into account the command bus: 


class UpdateGenericTrackingMethodAction
{
    public function __construct(
        private readonly SerializerInterface $serializer,
        private readonly CommandBus $commandBus,
        private readonly GetGenericTrackingMethodQueryHandler $queryHandler
    ) {
    }

    #[OA\Put(
        path: '/api/generic-tracking-methods/{id}',
        operationId: 'UpdateGenericTrackingMethod',
        description: 'Update a generic tracking method label. For `aftership`\'s methods, it will also sync its configuration with mandatory fields.
JWT Allowed:
BO Product Delivery: ROLE_BO_PRODUCT_DELIVERY_SUPER_ADMIN',
        summary: 'Update a generic tracking method.',
        security: [
            ['ManomanoBearer' => []],
        ],
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\JsonContent(
                properties: [new OA\Property(property: 'label', type: 'string', example: 'Colissimo (Colissimo fr)')],
                type: 'object'
            )
        ),
        tags: ['Generic Tracking Methods'],
    )]
    #[OA\Response(
        response: 200,
        description: 'The generic tracking method',
        content: new OA\JsonContent(
            properties: [
                new OA\Property(property: 'content', ref: '#/components/schemas/GenericTrackingMethodDTO', type: 'object'),
            ],
        )
    )]
    #[OA\Response(response: 400, description: 'Bad request, adjust before retrying')]
    #[OA\Response(ref: '#/components/responses/401', response: 401)]
    #[OA\Response(ref: '#/components/responses/403', response: 403)]
    #[OA\Response(
        response: 404,
        description: 'Resource not found',
        content: new OA\JsonContent(
            examples: [
                'TRACKING_METHOD_NOT_FOUND' => new OA\Examples(example: 'TRACKING_METHOD_NOT_FOUND', summary: 'The tracking method can not be found'),
            ]
        )
    )]
    #[OA\Response(response: 500, description: 'Internal server error')]
    #[IsGranted('ROLE_BO_PRODUCT_DELIVERY_SUPER_ADMIN')]
    /**
     * @throws RestException
     */
    public function __invoke(
        Request $request,
        #[OA\Parameter(name: 'id', description: 'generic tracking method id', in: 'path', required: true, schema: new OA\Schema(ref: '#/components/schemas/Integer32'))]
        int $id
    ): JsonResponse {
        try {
            /** @var UpdateGenericTrackingMethodCommand $command */
            $command = $this->serializer->deserialize(
                $request->getContent(),
                UpdateGenericTrackingMethodCommand::class,
                JsonEncoder::FORMAT,
                [
                    'default_constructor_arguments' => [
                        UpdateGenericTrackingMethodCommand::class => ['id' => $id],
                    ],
                    'allow_extra_attributes' => false,
                ]
            );
        } catch (InvalidArgumentException|UnexpectedValueException|SerializerException $exception) {
            throw RestException::fromThrowable($exception, Response::HTTP_BAD_REQUEST);
        }

        try {
            $this->commandBus->dispatch($command);
            $updatedTrackingMethod = $this->queryHandler->__invoke(
                new GetGenericTrackingMethodQuery($command->getId())
            );
        } catch (TrackingMethodNotFoundException $exception) {
            throw RestException::fromDomainException($exception, Response::HTTP_NOT_FOUND);
        } catch (DomainExceptionInterface $exception) {
            throw RestException::fromDomainException($exception, Response::HTTP_BAD_REQUEST);
        } catch (InfraExceptionInterface $exception) {
            throw RestException::fromInfraException($exception);
        }

        return JsonResponse::fromJsonString(
            $this->serializer->serialize(
                GenericTrackingMethodDTO::fromGenericTrackingMethod($updatedTrackingMethod),
                JsonEncoder::FORMAT
            ),
            Response::HTTP_OK
        );
    }
}

class UpdateGenericTrackingMethodCommand implements Command
{
    public function __construct(private readonly int $id, private readonly string $label)
    {
        Assert::positiveInteger($id);
    }

    public function getId(): int
    {
        return $this->id;
    }

    public function getLabel(): string
    {
        return $this->label;
    }
}

class UpdateGenericTrackingMethodCommandHandler
{
    public function __construct(
        private readonly GenericTrackingMethodRepository $repository,
        private readonly TrackingServiceResolver $trackingServiceResolver
    ) {
    }

    /**
     * @throws TrackingMethodNotFoundException
     * @throws InfraExceptionInterface
     */
    public function __invoke(UpdateGenericTrackingMethodCommand $command): void
    {
        $genericTrackingMethod = $this->repository->findById($command->getId());

        $trackingService = $this->trackingServiceResolver->resolveFromTrackingPlatform(
            $genericTrackingMethod->getTrackingPlatform()
        );

        $config = $trackingService->enrichConfig($genericTrackingMethod->getConfig());
        $genericTrackingMethod->setConfig($config);
        $genericTrackingMethod->setLabel($command->getLabel());

        $this->repository->add($genericTrackingMethod);
    }
}

class UpdateGenericTrackingMethodCommand implements Command
{
    public function __construct(private readonly int $id, private readonly string $label)
    {
        Assert::positiveInteger($id);
    }

    public function getId(): int
    {
        return $this->id;
    }

    public function getLabel(): string
    {
        return $this->label;
    }
}