ascio / ascio-framework
PHP Framework for the Ascio-API. Sync, AutoQueue, Update, REST-API
Installs: 9
Dependents: 0
Suggesters: 0
Security: 0
Stars: 2
Watchers: 2
Forks: 0
Open Issues: 1
Language:CSS
Requires
- php: >=5.3.0
- ext-pdo: *
- ext-soap: *
- doctrine/couchdb: @dev
- giggsey/libphonenumber-for-php: ^8.12
- illuminate/database: >=5.9@dev
- io-developer/php-whois: dev-master
- monolog/monolog: ^1.23
- predis/predis: ^1.1
Requires (Dev)
This package is auto-updated.
Last update: 2024-10-31 15:20:01 UTC
README
A php framework with docker to sync and connect to the ascio-api. Scalable, based on docker and kafka.
It makes make domain-management-processes easear like:
- Sync all data from ascio to the local databases in realtime.
- Auto-Queue blocking orders
- Scalable architecture
- Consume the poll-queue with multiple orders
- Provide one $domain->update functions. Change data, update, and all orders will be queued
- Auto unlock-relock
- REST-API: https://app.swaggerhub.com/apis/rendermani/Ascio-Framework/1.0.0-oas3
Requirements
The only requirement is docker. It can be downloaded here: https://www.docker.com/
Installation
- Clone repository:
git clone https://github.com/rendermani/ascio-framework.git ascio-framework
cd ascio-framework
chmod u+x bin/init.sh
- Run
bin/init.sh <<github token>>
. The github-token can be used optionally to extend quotas (Could not authenticate against github.com). It can be obtained here: https://github.com/settings/tokens - Set missing passwords in the .env
- Enter the ascio-credentials in config/accounts/default.json
- Run
bin/up.sh
Initial database sync: ascio > local
At the beginning the database is empty. As Ascio-messages are sent, when something changes, an initial sync must be done at the beginning. The sync-orders script syncs all orders and data that belongs to the orders, like Domains or SSL-Certificates.
- make sure the installation is complete, and default.json contains valid credentials and environment
- run
bin/sync-orders.sh
Testing the installation
At the beginning there will be a Kafka exception in the logs. This will be gone as soon as Kafka has fully loaded. There is no dependancy on Kafka, because the Kafka could run somewhere else.
- run
bin/logs.sh
. Look for 401 Authentification failed - run
bin/php sandbox/create-order.php
- observe the logs for poll complete.
- check the database: http://localhost:8001/
Locations
- phpmyadmin: http://localhost:8001/
- REST-API: http://localhost:8000/
Commands
- Init framework, create tables, build:
bin/init.sh
- Initials sync orders:
bin/sync-orders.sh
- Start:
bin/up.sh
- Stop:
bin/down.sh
- Restart framework:
bin/restart-framework.sh
- View logs:
bin/logs.sh
- Docker shell:
docker exec -it ascio-framework-php bash
- Execute php:
docker exec ascio-framework-php php sandbox/my-example.php
Example Code
Examples are in the sandbox directory. Here some examples:
Autoqueue the next order when blocked
First a register-order is created and a domain is registered. By setting $submitOptions->setQueue(false) the order is directly submitted. After that a expire-order is sent. But as the asynchronous register orders is still running, the expire order is queued in the database and started when the register is completed.
<?php namespace ascio\lib; use ascio\v2\TestLib; use ascio\lib\SubmitOptions; use SoapFault; require(__DIR__."/../vendor/autoload.php"); // an alternative can be set here Ascio::setConfig(); // get Test-Domain $domain = TestLib::getDomain("testme-".uniqid().".com"); try { $submitOptions = new SubmitOptions(); // direct submit if possible $submitOptions->setQueue(false); // register the domain $order = $domain->register($submitOptions); echo "Register: ". $domain->getDomainName()." Order: ".$order->getOrderId()." ".$order->db()->_id."\n"; // as register is running, the expire order will be auto-queued $order = $domain->expire($submitOptions); echo "Expire: ". $domain->getDomainName()." Order: ".$order->getOrderId()." ".$order->db()->_id."\n"; } catch (SoapFault $e) { echo "error!"; echo $e->getMessage(); // view SOAP-Request echo ascio::getClientV2()->__getLastRequest(); } catch (AscioException $e) { // view Ascio-Errors and the result echo $e->getMessage(); var_dump($e->getResult()->getCreateOrderResult()); }
The update() method
Normally it's required to know the order-type when changing data. With the update method of the domain, it's possible to change any data and the order-type will be automatically selected. If multiple order-types are required, orders are queued like in the example above.
Some order-types can change 2 different objects. Like the owner-change can change the registrant and the admin-contact in one request. In this case, the update method only uses necessary objects.
<?php namespace ascio\lib; use ascio\v2\TestLib; use SoapFault; require(__DIR__."/../vendor/autoload.php"); // an alternative can be set here Ascio::setConfig(); // get Test-Domain $domain = TestLib::getDomain("testme-".uniqid().".com"); try { // register the domain $order = $domain->register(); echo "Register: ". $domain->getDomainName()." Order: ".$order->getOrderId()." ".$order->db()->_id."\n"; // change domain data $domain->getAdminContact()->setFirstName("Manuel"); $domain->getRegistrant()->setAddress1("new adr. 123"); $domain->getNameServers()->createNameServer3()->setHostName("ns3.ascio.net"); // 3 orders are created: Registrant_Details_Update, Contact_Update and Nameserver_Update $domain->update(); } catch (SoapFault $e) { echo "error!"; echo $e->getMessage(); // view SOAP-Request echo ascio::getClientV2()->__getLastRequest(); } catch (AscioException $e) { // view Ascio-Errors and the result echo $e->getMessage(); var_dump($e->getResult()->getCreateOrderResult()); }
Store data into databases
All data is auto-stored in the database. If data should be stored manually, please use $object->produce()
to store data into all databases. This function should be use carefully, because data could get out of sync.
Read data from the database
Database can be read from any database. Objects like domains have a serialize and deserialize data. Please use $object->deserialize()
to import data. And $object->serialize($data)
or $object->toJson()
to serialize.
Here an example of retrieving data from the database:
// get Domain by databaseId $domain->db()->getById("myId"); // get Domain by ascio domain-handle $domain->db()->getByHandle("DomainHandle"); // get Domain by domain-name $domain->db()->getByName("myname.com"); // get Domain order by OrderId $order->db()->getByOrderId(); // get Order by databaseId $order->db()->getById("myId"); // get related tables: Domain, Registrant $order->getDomain()->getRegistrant(); // custom lavarel-query $domain->db()->where("Status","Active")->first(); // custom query $domain->db()->raw("select * from domains where Status = 'Active'");
Example database connector
Database connectors listen on the Kafka-service and write data into the database. It's possible to include own connectors. Right now Redis and Couch are included as examples. This is the Redit-connector.
The process of creating connectors is:
- create the connector in the
docker/docker-compose.yml
. Duplicate the redis-connector, and change the script-name to your file - create the connector file
bin/down.sh
bin/up.sh
This is an example Redis connector which is in the services directory.
<?php namespace ascio\lib; require(__DIR__."/../vendor/autoload.php"); use Illuminate\Support\Str; \Predis\Autoloader::register(); $client = new \Predis\Client([ 'scheme' => 'tcp', 'host' => 'redis', 'port' => 6379, ]); Consumer::object(function($payload) use($client) { Ascio::setConfig($payload->Config); $obj = $payload->object; $client->set($obj->db()->_id,$obj->toJson()); echo $obj->getStatusSerializer()->console(LogLevel::Info,Str::ucfirst($payload->action)); });
Read order from the API
Reads an Order from the API. When reading from the API, data is automatically synced to all databases.
<?php use ascio\v2\Order; require(__DIR__."/../vendor/autoload.php"); Ascio::setConfig(); $order = new Order(); $order->api()->getByOrderId("TEST561580");
Read domain by handle from the API
Reads an Domain from the API. When reading from the API, data is automatically synced to all databases.
<?php use ascio\v2\Domain; require(__DIR__."/../vendor/autoload.php"); Ascio::setConfig(); $domain = new Domain(); $domain->api()->getByHandle("TEST1234");
Read domain by domain-name from the API
Reads an Domain from the API. When reading from the API, data is automatically synced to all databases.
<?php use ascio\v2\Domain; require(__DIR__."/../vendor/autoload.php"); Ascio::setConfig(); $domain = new Domain(); $domain->api()->getByName("testmeee.com");
Update data from the API
$order = new Order(); $order->db()->getByOrderId("TEST561580"); $order->api()->get(); $domain = new Domain(); $domain->db()->getByName("test.de"); $domain->api()->get();
Workflow with AutoUnlock
Sometimes locks can prevent updates. This can be an issue when updating thousands of domains, and a few fail because they are locked. They would need to be unlocked and relocked again, after all operations are finished. The AutoUnlock makes this process easier
AutoUnlock before expiring (Delete_Lock)
<?php namespace ascio\lib; use ascio\v2\Domain; use ascio\v2\TestLib; require(__DIR__."/../vendor/autoload.php"); Ascio::setConfig(); $domain = new Domain(); $domain->getByHandle("TESTME5D66885"); $wf = new Workflow($domain); // if the orders of the workflow require and unlock it will be done before submitting the orders. // After the orders are finished the relock will be restored if possible. $wf->getSubmitOptions()->setAutoUnlock(true); // add the expire order-object $wf->addTask($domain->getOrderRequest()->expire()); // submit all orders $wf->submit();
AutoUnlock before update
This example is the same like the example above, only that the declarative way is used. Instead of adding a $domain->getOrderRequest()->expire()
task, a $domain->getUpdateOrders()
task is added. There could be more changes like $domain->getRegistrant()->setName("Manuel L")
and an OwnerChange would be created. And the UpdateLock released if necessary.
<?php namespace ascio\lib; use ascio\v2\TestLib; require(__DIR__."/../vendor/autoload.php"); Ascio::setConfig(); $domain = TestLib::getDomain("testme-".uniqid().".com"); // register domain $domain->register(); // set AutoRenew $domain->getAutoRenew()->set(false); $wf = new Workflow($domain); // if the orders of the workflow require and unlock it will be done before submitting the orders. // After the orders are finished the relock will be restored if possible. $wf->getSubmitOptions()->setAutoUnlock(true); $wf->addTasks($domain->getUpdateOrders()); // submit workflow $wf->submit();