22
33namespace MoveElevator \DeployerTools \Database \Manager ;
44
5+ use Deployer \Exception \Exception ;
56use GuzzleHttp \Exception \GuzzleException ;
6- use Mittwald \ApiClient \Client \EmptyResponse ;
77use Mittwald \ApiClient \Error \UnexpectedResponseException ;
8- use Mittwald \ApiClient \Generated \V2 \Clients \Database \CreateMysqlDatabase \CreateMysqlDatabaseCreatedResponse ;
98use Mittwald \ApiClient \Generated \V2 \Clients \Database \DeleteMysqlDatabase \DeleteMysqlDatabaseRequest ;
10- use Mittwald \ApiClient \Generated \V2 \Clients \Database \GetMysqlDatabase \GetMysqlDatabaseOKResponse ;
11- use Mittwald \ApiClient \Generated \V2 \Clients \Database \GetMysqlUser \GetMysqlUserOKResponse ;
129use Mittwald \ApiClient \Generated \V2 \Clients \Database \GetMysqlUser \GetMysqlUserRequest ;
1310use Mittwald \ApiClient \Generated \V2 \Schemas \Database \CharacterSettings ;
11+ use Mittwald \ApiClient \Generated \V2 \Schemas \Database \DatabaseUserStatus ;
1412use Mittwald \ApiClient \Generated \V2 \Schemas \Database \MySqlUser ;
1513use Mittwald \ApiClient \MittwaldAPIV2Client ;
1614use Mittwald \ApiClient \Generated \V2 \Clients \Database \ListMysqlDatabases \ListMysqlDatabasesRequest ;
17- use Mittwald \ApiClient \Generated \V2 \Clients \Database \ListMysqlDatabases \ListMysqlDatabasesOKResponse ;
1815use Mittwald \ApiClient \Generated \V2 \Schemas \Database \CreateMySqlDatabase ;
1916use Mittwald \ApiClient \Generated \V2 \Schemas \Database \CreateMySqlUserWithDatabase ;
2017use Mittwald \ApiClient \Generated \V2 \Schemas \Database \CreateMySqlUserWithDatabaseAccessLevel ;
@@ -42,6 +39,11 @@ class MittwaldApi extends AbstractManager implements ManagerInterface
4239{
4340 private MittwaldAPIV2Client $ client ;
4441
42+ /**
43+ * @throws GuzzleException
44+ * @throws UnexpectedResponseException
45+ * @throws \Exception
46+ */
4547 public function create (): void
4648 {
4749 debug ('Creating database ' );
@@ -69,8 +71,14 @@ public function create(): void
6971 )
7072 );
7173
72-
7374 $ responseBody = $ response ->getBody ();
75+
76+ // The database creation is not immediately available, we need to wait for it.
77+ $ ready = $ this ->checkForDatabaseReadyStatus ($ responseBody ->getUserId ());
78+ if (!$ ready ) {
79+ throw new \RuntimeException ('Database is not ready for feature ' . $ this ->getFeatureName () . ' after waiting period. ' );
80+ }
81+
7482 $ database = $ this ->getDatabase ($ responseBody ->getId ());
7583 $ user = $ this ->getDatabaseUser ($ responseBody ->getUserId ());
7684
@@ -99,6 +107,10 @@ public function delete(string $feature): void
99107
100108 }
101109
110+ /**
111+ * @throws GuzzleException
112+ * @throws UnexpectedResponseException
113+ */
102114 public function exists (?string $ feature = null ): bool
103115 {
104116 debug ('Check database exists ' );
@@ -131,6 +143,10 @@ private function initClient(): MittwaldAPIV2Client
131143 return $ this ->client ;
132144 }
133145
146+ /**
147+ * @throws GuzzleException
148+ * @throws UnexpectedResponseException
149+ */
134150 private function getDatabaseByFeature (string $ feature ): ?MySqlDatabase
135151 {
136152 $ response = $ this ->initClient ()
@@ -150,6 +166,10 @@ private function getDatabaseByFeature(string $feature): ?MySqlDatabase
150166 return null ;
151167 }
152168
169+ /**
170+ * @throws GuzzleException
171+ * @throws UnexpectedResponseException
172+ */
153173 private function getDatabase (string $ id ): MySqlDatabase
154174 {
155175 $ response = $ this ->initClient ()
@@ -164,6 +184,10 @@ private function getDatabase(string $id): MySqlDatabase
164184 return $ response ->getBody ();
165185 }
166186
187+ /**
188+ * @throws GuzzleException
189+ * @throws UnexpectedResponseException
190+ */
167191 private function getDatabaseUser (string $ id ): MysqlUser
168192 {
169193 $ response = $ this ->initClient ()
@@ -184,4 +208,34 @@ private function initDatabaseConfiguration(MySqlDatabase $database, MySqlUser $u
184208 set ('database_host ' , $ database ->getHostName ());
185209 set ('database_password ' , VarUtility::getDatabasePassword ());
186210 }
211+
212+ private function checkForDatabaseReadyStatus (string $ mysqlUserId , int $ waitingTime = 60 , int $ maxRetries = 10 ): bool
213+ {
214+
215+ while ($ maxRetries > 0 ) {
216+ try {
217+ debug ("Checking status for MySQL user {$ mysqlUserId }, remaining attempts: {$ maxRetries }" );
218+ $ response = $ this ->initClient ()
219+ ->database ()
220+ ->getMysqlUser (
221+ new GetMysqlUserRequest ($ mysqlUserId )
222+ );
223+
224+ if (DatabaseUserStatus::ready === $ response ->getBody ()->getStatus ()) {
225+ debug ("MySQL user {$ mysqlUserId } is ready. " );
226+ return true ;
227+ }
228+ } catch (\Throwable $ e ) {
229+ debug ("Error while checking status: " . $ e ->getMessage ());
230+ // Optionally: break on certain errors
231+ }
232+
233+ if ($ maxRetries > 1 ) {
234+ sleep ($ waitingTime );
235+ }
236+ $ maxRetries --;
237+ }
238+ debug ("MySQL user {$ mysqlUserId } is not ready after all attempts. " );
239+ return false ;
240+ }
187241}
0 commit comments