2020-06-26 21:54:37 +12:00
< ? php
2024-04-23 08:45:55 +12:00
2024-04-23 07:38:48 +12:00
require_once __DIR__ . '/init2.php' ;
require_once __DIR__ . '/controllers/general.php' ;
2020-06-26 21:54:37 +12:00
2024-04-14 20:58:05 +12:00
use Appwrite\Utopia\Queue\Connections ;
2024-03-07 06:34:21 +13:00
use Appwrite\Utopia\Request ;
2020-10-30 02:07:56 +13:00
use Appwrite\Utopia\Response ;
2024-03-07 06:34:21 +13:00
use Utopia\Abuse\Adapters\TimeLimit ;
use Utopia\Audit\Audit ;
2024-04-15 17:29:32 +12:00
use Utopia\Cache\Cache ;
2020-06-27 00:27:58 +12:00
use Utopia\CLI\Console ;
2021-05-04 22:24:08 +12:00
use Utopia\Config\Config ;
2024-04-15 17:29:32 +12:00
use Utopia\Database\Adapter\MariaDB ;
use Utopia\Database\Adapter\MySQL ;
2024-03-07 06:34:21 +13:00
use Utopia\Database\Database ;
use Utopia\Database\Document ;
2022-12-15 04:42:25 +13:00
use Utopia\Database\Helpers\ID ;
2022-12-15 05:04:06 +13:00
use Utopia\Database\Helpers\Permission ;
use Utopia\Database\Helpers\Role ;
2021-07-26 02:51:04 +12:00
use Utopia\Database\Validator\Authorization ;
2024-07-06 03:44:58 +12:00
use Utopia\Http\Adapter\Swoole\Server ;
2024-03-09 01:57:20 +13:00
use Utopia\Http\Http ;
2024-04-14 20:58:05 +12:00
use Utopia\System\System ;
2022-09-30 23:32:58 +13:00
2024-06-04 06:09:58 +12:00
global $global , $container ;
2024-05-09 21:41:02 +12:00
$payloadSize = 12 * ( 1024 * 1024 ); // 12MB - adding slight buffer for headers and other data that might be sent with the payload - update later with valid testing
2024-07-13 10:11:43 +12:00
$workerNumber = swoole_cpu_num () * intval ( System :: getEnv ( '_APP_WORKER_PER_CORE' , 2 ));
2020-06-26 21:54:37 +12:00
2024-07-06 03:44:58 +12:00
$server = new Server ( '0.0.0.0' , '80' , [
'open_http2_protocol' => true ,
'http_compression' => true ,
'http_compression_level' => 6 ,
'package_max_length' => $payloadSize ,
'buffer_output_size' => $payloadSize ,
// Server
// 'log_level' => 0,
'dispatch_mode' => 1 ,
'worker_num' => $workerNumber ,
'reactor_num' => swoole_cpu_num () * 2 ,
'open_cpu_affinity' => true ,
// Coroutine
'enable_coroutine' => true ,
2024-07-13 10:11:43 +12:00
'send_yield' => true ,
'tcp_fastopen' => true ,
2024-07-06 03:44:58 +12:00
]);
2024-07-19 03:54:01 +12:00
$server -> on ( Constant :: EVENT_WORKER_START , function ( $server , $workerId ) {
2022-05-24 02:54:50 +12:00
Console :: success ( 'Worker ' . ++ $workerId . ' started successfully' );
2020-06-26 21:54:37 +12:00
});
2024-07-06 03:44:58 +12:00
2024-02-23 00:51:19 +13:00
$http -> on ( Constant :: EVENT_BEFORE_RELOAD , function ( $server , $workerId ) {
2020-06-26 21:54:37 +12:00
Console :: success ( 'Starting reload...' );
});
2024-02-23 00:51:19 +13:00
$http -> on ( Constant :: EVENT_AFTER_RELOAD , function ( $server , $workerId ) {
2020-06-26 21:54:37 +12:00
Console :: success ( 'Reload completed...' );
});
2021-05-07 09:35:05 +12:00
include __DIR__ . '/controllers/general.php' ;
2024-07-06 03:44:58 +12:00
global $global , $container ;
2024-04-14 20:58:05 +12:00
2024-07-06 03:44:58 +12:00
http :: onStart ()
-> inject ( 'authorization' )
-> inject ( 'cache' )
-> inject ( 'pools' )
-> inject ( 'connections' )
-> action ( function ( Authorization $authorization , Cache $cache , array $pools , Connections $connections ) {
try {
// wait for database to be ready
$attempts = 0 ;
$max = 15 ;
$sleep = 2 ;
do {
2024-04-15 17:29:32 +12:00
try {
2024-07-06 03:44:58 +12:00
$attempts ++ ;
$pool = $pools [ 'pools-console-main' ][ 'pool' ];
$dsn = $pools [ 'pools-console-main' ][ 'dsn' ];
$connection = $pool -> get ();
$connections -> add ( $connection , $pool );
$adapter = match ( $dsn -> getScheme ()) {
'mariadb' => new MariaDB ( $connection ),
'mysql' => new MySQL ( $connection ),
default => null
};
$adapter -> setDatabase ( $dsn -> getPath ());
$dbForConsole = new Database ( $adapter , $cache );
$dbForConsole -> setAuthorization ( $authorization );
$dbForConsole
-> setNamespace ( '_console' )
-> setMetadata ( 'host' , \gethostname ())
-> setMetadata ( 'project' , 'console' )
-> setTimeout ( APP_DATABASE_TIMEOUT_MILLISECONDS );
$dbForConsole -> ping ();
break ; // leave the do-while if successful
2024-04-15 17:29:32 +12:00
} catch ( \Throwable $e ) {
2024-07-06 03:44:58 +12:00
Console :: warning ( " Database not ready. Retrying connection ( { $attempts } )... " );
if ( $attempts >= $max ) {
throw new \Exception ( 'Failed to connect to database: ' . $e -> getMessage ());
}
sleep ( $sleep );
2024-04-15 17:29:32 +12:00
}
2024-07-06 03:44:58 +12:00
} while ( $attempts < $max );
2024-04-15 17:29:32 +12:00
2024-07-06 03:44:58 +12:00
Console :: success ( '[Setup] - Server database init started...' );
2024-04-14 20:58:05 +12:00
2024-07-06 03:44:58 +12:00
try {
Console :: success ( '[Setup] - Creating database: appwrite...' );
$dbForConsole -> create ();
} catch ( \Throwable $e ) {
Console :: success ( '[Setup] - Skip: metadata table already exists' );
return true ;
}
2021-07-05 03:14:39 +12:00
2024-07-06 03:44:58 +12:00
if ( $dbForConsole -> getCollection ( Audit :: COLLECTION ) -> isEmpty ()) {
$audit = new Audit ( $dbForConsole );
$audit -> setup ();
}
2022-09-13 02:09:28 +12:00
2024-07-06 03:44:58 +12:00
if ( $dbForConsole -> getCollection ( TimeLimit :: COLLECTION ) -> isEmpty ()) {
$abuse = new TimeLimit ( " " , 0 , 1 , $dbForConsole );
$abuse -> setup ();
}
2021-07-05 00:05:46 +12:00
2024-07-06 03:44:58 +12:00
/** @var array $collections */
$collections = Config :: getParam ( 'collections' , []);
$consoleCollections = $collections [ 'console' ];
foreach ( $consoleCollections as $key => $collection ) {
if (( $collection [ '$collection' ] ? ? '' ) !== Database :: METADATA ) {
continue ;
}
if ( ! $dbForConsole -> getCollection ( $key ) -> isEmpty ()) {
continue ;
}
2022-01-10 19:31:33 +13:00
2024-07-06 03:44:58 +12:00
Console :: success ( '[Setup] - Creating collection: ' . $collection [ '$id' ] . '...' );
$attributes = [];
$indexes = [];
foreach ( $collection [ 'attributes' ] as $attribute ) {
$attributes [] = new Document ([
'$id' => ID :: custom ( $attribute [ '$id' ]),
'type' => $attribute [ 'type' ],
'size' => $attribute [ 'size' ],
'required' => $attribute [ 'required' ],
'signed' => $attribute [ 'signed' ],
'array' => $attribute [ 'array' ],
'filters' => $attribute [ 'filters' ],
'default' => $attribute [ 'default' ] ? ? null ,
'format' => $attribute [ 'format' ] ? ? ''
]);
2024-04-15 17:29:32 +12:00
}
2020-12-30 07:42:03 +13:00
2024-07-06 03:44:58 +12:00
foreach ( $collection [ 'indexes' ] as $index ) {
$indexes [] = new Document ([
'$id' => ID :: custom ( $index [ '$id' ]),
'type' => $index [ 'type' ],
'attributes' => $index [ 'attributes' ],
'lengths' => $index [ 'lengths' ],
'orders' => $index [ 'orders' ],
]);
}
2022-05-24 02:54:50 +12:00
2024-07-06 03:44:58 +12:00
$dbForConsole -> createCollection ( $key , $attributes , $indexes );
}
2024-04-14 20:58:05 +12:00
2024-07-06 03:44:58 +12:00
if ( $dbForConsole -> getDocument ( 'buckets' , 'default' ) -> isEmpty () && ! $dbForConsole -> exists ( $dbForConsole -> getDatabase (), 'bucket_1' )) {
Console :: success ( '[Setup] - Creating default bucket...' );
$dbForConsole -> createDocument ( 'buckets' , new Document ([
'$id' => ID :: custom ( 'default' ),
'$collection' => ID :: custom ( 'buckets' ),
'name' => 'Default' ,
'maximumFileSize' => ( int ) System :: getEnv ( '_APP_STORAGE_LIMIT' , 0 ), // 10MB
'allowedFileExtensions' => [],
'enabled' => true ,
'compression' => 'gzip' ,
'encryption' => true ,
'antivirus' => true ,
'fileSecurity' => true ,
'$permissions' => [
Permission :: create ( Role :: any ()),
Permission :: read ( Role :: any ()),
Permission :: update ( Role :: any ()),
Permission :: delete ( Role :: any ()),
],
'search' => 'buckets Default' ,
]));
$bucket = $dbForConsole -> getDocument ( 'buckets' , 'default' );
Console :: success ( '[Setup] - Creating files collection for default bucket...' );
$files = $collections [ 'buckets' ][ 'files' ] ? ? [];
if ( empty ( $files )) {
throw new Exception ( 'Files collection is not configured.' );
}
2021-12-28 01:45:23 +13:00
2024-07-06 03:44:58 +12:00
$attributes = [];
$indexes = [];
foreach ( $files [ 'attributes' ] as $attribute ) {
$attributes [] = new Document ([
'$id' => ID :: custom ( $attribute [ '$id' ]),
'type' => $attribute [ 'type' ],
'size' => $attribute [ 'size' ],
'required' => $attribute [ 'required' ],
'signed' => $attribute [ 'signed' ],
'array' => $attribute [ 'array' ],
'filters' => $attribute [ 'filters' ],
'default' => $attribute [ 'default' ] ? ? null ,
'format' => $attribute [ 'format' ] ? ? ''
]);
2024-04-15 17:29:32 +12:00
}
2022-07-10 01:41:14 +12:00
2024-07-06 03:44:58 +12:00
foreach ( $files [ 'indexes' ] as $index ) {
$indexes [] = new Document ([
'$id' => ID :: custom ( $index [ '$id' ]),
'type' => $index [ 'type' ],
'attributes' => $index [ 'attributes' ],
'lengths' => $index [ 'lengths' ],
'orders' => $index [ 'orders' ],
]);
}
2024-04-14 20:58:05 +12:00
2024-07-06 03:44:58 +12:00
$dbForConsole -> createCollection ( 'bucket_' . $bucket -> getInternalId (), $attributes , $indexes );
2024-04-14 20:58:05 +12:00
}
2024-03-09 01:57:20 +13:00
2024-07-06 03:44:58 +12:00
$connections -> reclaim ();
2021-12-22 04:01:40 +13:00
2024-07-06 03:44:58 +12:00
Console :: success ( '[Setup] - Server database init completed...' );
Console :: success ( 'Server started successfully' );
} catch ( \Throwable $e ) {
Console :: warning ( 'Database not ready: ' . $e -> getMessage ());
exit ( 1 );
}
});
Http :: init ()
-> inject ( 'authorization' )
-> action ( function ( Authorization $authorization ) {
$authorization -> cleanRoles ();
$authorization -> addRole ( Role :: any () -> toString ());
});
$http -> start ();