Skip to content

Commit

Permalink
Get ready for general use
Browse files Browse the repository at this point in the history
  • Loading branch information
shrikeh committed May 30, 2022
1 parent c3bd044 commit 9c7fd48
Show file tree
Hide file tree
Showing 115 changed files with 750 additions and 55 deletions.
11 changes: 3 additions & 8 deletions .env
Expand Up @@ -26,18 +26,13 @@ APP_SECRET=e4fab8533e85795651f9963db77469ea
# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
###< symfony/messenger ###
APP_ENV=test
APP_CODE_DIR='/cushon/app'
APP_BUILD_DIR=build
APP_CACHE_DIR=build/cache/symfony
APP_LOG_DIR=build/logs
HOST_NGINX_PORT=9010
NULL_DEPENDENCY_NAME='A fake dependency'

###> doctrine/doctrine-bundle ###
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
#
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
# DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7&charset=utf8mb4"
DATABASE_URL="postgresql://symfony:ChangeMe@127.0.0.1:5432/app?serverVersion=13&charset=utf8"
###< doctrine/doctrine-bundle ###
DB_READ_PASSWORD=cushon_health_reader
DB_WRITE_PASSWORD=cushon_health_writer
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -115,6 +115,7 @@ craft: .craft test quality

console: .composer-console

health: APP_ENV = prod
health: .composer-health

brew:
Expand Down
16 changes: 10 additions & 6 deletions app/config/packages/doctrine.prod.yaml
@@ -1,22 +1,22 @@
---
parameters:
env(DB_READ_HOST): '127.0.0.1'
env(DB_READ_NAME): 'health_example'
env(DB_READ_NAME): 'cushon_health_test'
env(DB_READ_USER): 'cushon_read'
env(DB_READ_VERSION): 'mariadb-10.7.3'
env(DB_READ_PORT): 3306
env(DB_READ_PORT): 33010

env(DB_WRITE_HOST): '127.0.0.1'
env(DB_WRITE_NAME): 'health_example'
env(DB_WRITE_NAME): 'cushon_health_test'
env(DB_WRITE_USER): 'cushon_write'
env(DB_WRITE_VERSION): 'mariadb-10.7.3'
env(DB_WRITE_PORT): 3306
env(DB_WRITE_PORT): 33010

doctrine:
dbal:
default_connection: default
default_connection: 'read'
connections:
default:
read:
# Connection used for read operations
host: '%env(string:DB_READ_HOST)%'
dbname: '%env(string:DB_READ_NAME)%'
Expand All @@ -25,6 +25,8 @@ doctrine:
server_version: '%env(string:DB_READ_VERSION)%'
port: '%env(int:DB_READ_PORT)%'
driver: 'pdo_mysql'
options:
LoginTimeout: 2
write:
# Connection used for write operations
host: '%env(string:DB_WRITE_HOST)%'
Expand All @@ -34,4 +36,6 @@ doctrine:
server_version: '%env(string:DB_WRITE_VERSION)%'
port: '%env(int:DB_WRITE_PORT)%'
driver: 'pdo_mysql'
options:
LoginTimeout: 2

2 changes: 1 addition & 1 deletion app/config/packages/doctrine_migrations.prod.yaml
Expand Up @@ -4,5 +4,5 @@ doctrine_migrations:
migrations_paths:
# namespace is arbitrary but should be different from App\Migrations
# as migrations classes should NOT be autoloaded
'Example\DoctrineMigrations': '%kernel.project_dir%/migrations'
'App\DoctrineMigrations': '%kernel.project_dir%/migrations'
enable_profiler: '%kernel.debug%'
13 changes: 13 additions & 0 deletions app/config/packages/translation.yaml
@@ -0,0 +1,13 @@
framework:
default_locale: en
translator:
default_path: '%kernel.project_dir%/translations'
fallbacks:
- en
# providers:
# crowdin:
# dsn: '%env(CROWDIN_DSN)%'
# loco:
# dsn: '%env(LOCO_DSN)%'
# lokalise:
# dsn: '%env(LOKALISE_DSN)%'
10 changes: 9 additions & 1 deletion app/config/services.yaml
Expand Up @@ -14,14 +14,22 @@ services:
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '%kernel.project_dir%/src/'
exclude:
- '%kernel.project_dir%/src/{DependencyInjection/,Kernel.php}'

_instanceof:
App\ApplicationHealth\DependencyCheck\DatabaseCheck\DatabaseUserCheck:
tags:
- 'app.health.check.db'

App\ApplicationHealth\DependencyCheck\DatabaseCheck:
arguments:
- !tagged_iterator app.health.check.db

# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
App\ApplicationHealth\DependencyCheck\NullDependencyCheck:
Expand Down
38 changes: 38 additions & 0 deletions app/data/health.sql
@@ -0,0 +1,38 @@
-- MariaDB dump 10.19 Distrib 10.7.3-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: localhost Database: uuid_example
-- ------------------------------------------------------
-- Server version 10.7.3-MariaDB-1:10.7.3+maria~focal

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

CREATE SCHEMA IF NOT EXISTS cushon_health_test;

CREATE USER 'cushon_read'@'%';
CREATE USER 'cushon_write'@'%';

GRANT ALL PRIVILEGES ON `cushon_health_test`.* TO 'cushon_write'@'%' IDENTIFIED BY 'cushon_health_writer';
GRANT SELECT ON `cushon_health_test`.* TO 'cushon_read'@'%' IDENTIFIED BY 'cushon_health_reader';

FLUSH PRIVILEGES;

/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2022-03-23 15:47:25
Empty file added app/migrations/.gitignore
Empty file.
36 changes: 36 additions & 0 deletions app/migrations/Version20220530155854.php
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace App\DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Types\Types;
use Doctrine\Migrations\AbstractMigration;
use Ramsey\Uuid\Doctrine\UuidBinaryType;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20220530155854 extends AbstractMigration
{
public function getDescription(): string
{
return 'Create a simple table for health checks';
}

public function up(Schema $schema): void
{
$health = $schema->createTable('health');
$health->addColumn(
'last_checked',
Types::DATETIME_IMMUTABLE
);

}

public function down(Schema $schema): void
{
$schema->dropTable('health');
}
}
31 changes: 25 additions & 6 deletions app/src/ApplicationHealth/DependencyCheck/DatabaseCheck.php
@@ -1,34 +1,53 @@
<?php

declare(strict_types=1);

namespace App\ApplicationHealth\DependencyCheck;

use App\ApplicationHealth\DependencyCheck\DatabaseCheck\HealthDependencyRepository;
use App\ApplicationHealth\DependencyCheck\DatabaseCheck\DatabaseUserCheck;
use App\ApplicationHealth\DependencyCheck\DatabaseCheck\Exception\NoDatabaseChecksProvided;
use Cushon\HealthBundle\ApplicationHealth\DependencyCheck;
use Cushon\HealthBundle\ApplicationHealth\HealthReport\DependencyStatus;
use Ds\Set;
use Generator;

final class DatabaseCheck implements DependencyCheck
{
/**
* @var Set<DatabaseUserCheck>
*/
private Set $dependencyRepositories;

/**
* @param HealthDependencyRepository ...$dependencyRepositories
* @param iterable<DatabaseUserCheck> $dependencyRepositories
*/
public function __construct(HealthDependencyRepository ...$dependencyRepositories)
public function __construct(iterable $dependencyRepositories)
{
$this->dependencyRepositories = new Set($dependencyRepositories);
$this->dependencyRepositories = new Set();
foreach ($dependencyRepositories as $dependencyRepository) {
$this->addDatabaseUserCheck($dependencyRepository);
}

if (!$this->dependencyRepositories->count()) {
throw NoDatabaseChecksProvided::create();
}
}

/**
* @inheritDoc
*/
public function check(): Generator
{
/** @var HealthDependencyRepository $dependencyRepository */
foreach ($this->dependencyRepositories as $dependencyRepository) {
yield $dependencyRepository->checkUser();
}
}

/**
* @param DatabaseUserCheck $databaseUserChecks
* @return void
*/
private function addDatabaseUserCheck(DatabaseUserCheck $databaseUserChecks): void
{
$this->dependencyRepositories->add($databaseUserChecks);
}
}
@@ -1,11 +1,12 @@
<?php

declare(strict_types=1);

namespace App\ApplicationHealth\DependencyCheck\DatabaseCheck;

use Cushon\HealthBundle\ApplicationHealth\HealthReport\DependencyStatus;

interface HealthDependencyRepository
interface DatabaseUserCheck
{
/**
* @return DependencyStatus
Expand Down
@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);

namespace App\ApplicationHealth\DependencyCheck\DatabaseCheck\Exception;

use InvalidArgumentException;

final class NoDatabaseChecksProvided extends InvalidArgumentException
{
/**
* @return static
*/
public static function create(): self
{
return new self('No database checks were provided');
}
}
47 changes: 47 additions & 0 deletions app/src/Repository/DatabaseCheck/ReadUserCheck.php
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace App\Repository\DatabaseCheck;

use App\ApplicationHealth\DependencyCheck\DatabaseCheck\DatabaseUserCheck;
use Cushon\HealthBundle\ApplicationHealth\HealthReport\DependencyStatus;
use Cushon\HealthBundle\ApplicationHealth\HealthReport\DependencyStatus\SimpleStatus;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception;

final class ReadUserCheck implements DatabaseUserCheck
{
/**
* @var Connection
*/
private Connection $connection;

/**
* @param Connection $readConnection
*/
public function __construct(Connection $readConnection)
{
$this->connection = $readConnection;
}

/**
* @inheritDoc
*/
public function checkUser(): DependencyStatus
{
$healthy = false;
try {
$this->connection->createQueryBuilder()
->select('last_checked')
->from('health')
->executeQuery();
$healthy = true;
$info = null;
} catch (Exception $e) {
$info = $e->getMessage();
}

return new SimpleStatus('DB read user', $healthy, $info);
}
}
50 changes: 50 additions & 0 deletions app/src/Repository/DatabaseCheck/WriteUserCheck.php
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace App\Repository\DatabaseCheck;

use App\ApplicationHealth\DependencyCheck\DatabaseCheck\DatabaseUserCheck;
use Cushon\HealthBundle\ApplicationHealth\HealthReport\DependencyStatus;
use Cushon\HealthBundle\ApplicationHealth\HealthReport\DependencyStatus\SimpleStatus;
use DateTimeImmutable;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Types\Types;

final class WriteUserCheck implements DatabaseUserCheck
{
/**
* @var Connection
*/
private Connection $connection;

/**
* @param Connection $writeConnection
*/
public function __construct(Connection $writeConnection)
{
$this->connection = $writeConnection;
}

/**
* @inheritDoc
*/
public function checkUser(): DependencyStatus
{
$health = false;
try {
$this->connection->createQueryBuilder()
->insert('health')
->setValue('last_checked', ':now')
->setParameter('now', new DateTimeImmutable(), Types::DATETIME_IMMUTABLE)
->executeStatement();
$health = true;
$info = null;
} catch (Exception $e) {
$info = $e->getMessage();
}

return new SimpleStatus('DB write user', $health, $info);
}
}
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace App\Repository;
namespace App\Repository\RandomOrgCheck;

use App\ApplicationHealth\DependencyCheck\RandomOrgApiCheck\HealthDependencyRepository;
use App\Repository\Exception\ResponseNotOk;
Expand Down
Empty file added app/translations/.gitignore
Empty file.

0 comments on commit 9c7fd48

Please sign in to comment.