In this section, you will modify the vpses.php
script since it is responsible for all operations with servers
in the application.
In this document:
Following the outlined Design Review, we need to edit three methods:
provision()
- when provisioning a new server, it must send a notification with type activity
and status
ready
, if a VPS is required, or inProgress
, if a VM is required.provisionAsync()
- it processes an async request and modifies the notification linked with the VM.unprovision()
- when removing a server, it must remove the existing notification and send a new one
of type warning
.This section continues the demo project started in the previous step.
The provisioning logic scripts mentioned above are able to work with a certain notification linked with a VPS.
For this purpose, make the notification ID stored
as one of VPS properties. In the vps
class, declare the notificationId
property:
/**
* @type(string)
* @title("Notification ID")
*/
public $notificationId;
Update the provision
method as follows.
Prepare a connection with the notification manager and define interface elements.
Get an instance of the notification manager
$notificationManager = \APS\NotificationManager::getInstance();
Get ready the account APS ID needed for the notification message. For this purpose, use the VPS-to-context relationship and the context-to-account relationship in a chain.
$accountId = $this->context->account->aps->id;
Define the notification message corresponding
to the Message
structure in the notification manager.
In accordance with Design Review, use two modifications of it.
Create a notification message for the case, when a VPS (without OS kernel) is requested.
$notification = new \APS\Notification;
$notification->message = new \APS\NotificationMessage("VPS Creation");
$notification->details = new \APS\NotificationMessage(
"VPS __name__ is provisioned",
array("name" => $this->name)
);
$notification->accountId = $accountId;
$notification->status = \APS\Notification::ACTIVITY_READY;
$notification->packageId = $this->aps->package->id;
$notification->link = new \APS\NotificationLink(
"/v/aps/samples/async1pn/servers", // Main link
"/v/aps/samples/async1pn/server-edit/r/".$this->aps->id, // Link more
"View or edit VPS" // Link more text
);
Modify the notification message for the case, when a VM (with OS kernel) is requested. Use one more if($this->hardware->VM)
clause.
if($this->hardware->VM ) {
$this->state = "Creating"; // VM state is intermediate
// Edit the notification message
$notification->message->message = "VM Creation";
$notification->details->message = "Provisioning of VM __name__ is started";
$notification->status = \APS\Notification::ACTIVITY_IN_PROGRESS;
$notification->link->linkMore = "/v/aps/samples/async1pn/servers";
$notification->link->linkMoreText->message = "View Servers";
}
Send the new notification and save the notification ID.
// Send the notification
$notificationResponse = $notificationManager->sendNotification($notification);
// Store the notification ID as the VPS property to update or remove it in other operations
$this->notificationId = $notificationResponse->id;
Make sure the exception for starting the async process is thrown at the very end of the provision
method.
if ($this->hardware->VM ) {
//Require async operation:
throw new \Rest\Accepted($this, "Creating VM", 15); // Returns code "202 Accepted"
} else {
// Simulate the end of async provisioning to show correct status in UI
$this->retry = 5;
}
In accordance with Design Review, this method should only modify the existing notification bound to the VM that is under processing. For this reason, there is no need to define the whole notification message.
Prepare a connection with the notification manager and define interface elements the same way you did it
in the provision
method.
// Get an instance of the Notification Manager:
$notificationManager = \APS\NotificationManager::getInstance();
// Get ready account APS ID needed for the notification structure.
$accountId = $this->context->account->aps->id;
// Increment the retry counter
$this->retry +=1;
Get ready two modifications of the notification.
The async provisioning is not finished yet (retry < 5):
$notification = new \APS\Notification;
$notification->message = new \APS\NotificationMessage("VM Creation");
$notification->details = new \APS\NotificationMessage(
"Provisioning of VM __name__ is in progress",
array("name" => $this->name)
);
$notification->fullDetails = new \APS\NotificationMessage(
"__percent__ % of the Virtual Machine provisioning is completed",
array("percent" => $this->retry * 20)
);
$notification->link = new \APS\NotificationLink(
"",
"/v/aps/samples/async1pn/servers",
"View Servers"
);
The async provisioning is finished (retry >= 5):
if ($this->retry >= 5) {
$this->state = "Stopped"; // Finish the Async operation - return 200 OK to APSC
$notification->details->message = "Provisioning of VM __name__ is completed";
$notification->status = \APS\Notification::ACTIVITY_READY;
$notification->link->linkMore="/v/aps/samples/async1pn/server-edit/r/".$this->aps->id;
$notification->link->linkMoreText->message = "View or edit VM";
}
Send the notification update request through the PUT operation.
if (isset($this->notificationId)) {
$notificationResponce = $notificationManager->editNotification(
$this->notificationId,
$notification
);}
Make sure the exception for continuing the async process is thrown at the very end of the provisionAsync
method.
if ($this->retry < 5) {
// Require the next async retry
throw new \Rest\Accepted($this, "Creating VM", 15); // Return code "202 Accepted"
}
As follows from Design Review, in the unprovision()
method, you need to
remove the notification along with the server whose removal is requested and then send a warning
notification,
either with status upcoming or existing. The condition is based on the number of servers remained,
either non-zero or zero.
Prepare a connection with the notification manager and define interface elements the same way you did it
in the provision
method.
$accountId = $this->context->account->aps->id;
// Get an instance of the Notification Manager:
$notificationManager = \APS\NotificationManager::getInstance();
Get ready the notification message for the two cases.
At least one server remains after the removal:
$notification = new \APS\Notification;
$notification->message = new \APS\NotificationMessage("Server Removal");
$notification->details = new \APS\NotificationMessage(
"Server __name__ is removed",
array("name" => $this->name)
);
$notification->type = \APS\Notification::TYPE_WARNING;
$notification->accountId = $accountId;
$notification->status = \APS\Notification::WARNING_UPCOMING;
$notification->packageId = $this->aps->package->id;
$notification->link = new \APS\NotificationLink(
"/v/aps/samples/async1pn/servers",
"/v/aps/samples/async1pn/servers",
"View Servers"
);
Removal of the last server:
// Get a list of VPSEs to count the remained ones
$apsc = \APS\Request::getController();
$vpses = $apsc->getResources(
'implementing(http://aps-standard.org/samples/async1pn/vps/1.0)'
);
// Removing the last server of the customer?
if (count($vpses) <= 1) {
$notification->details->message = "The last server __name__ is removed";
$notification->status = \APS\Notification::WARNING_EXISTING;
}
Remove the existing notification and send the new one.
// If Notification Manager is available, remove the notification
if (isset($this->notificationId)) {
// Remove the stored Notification
$notificationManager->deleteNotification($this->notificationId);
unset($this->notificationId);
// Send the new notification
$notificationManager->sendNotification($notification);
}
This completes modification of the vpses.php
file, which is a part of the provisioning logic.
You can compare the added code with the contents in the respective file
inside the sample package
.