AutonomousDatabaseActionTask.groovy
001 /*
002  * SPDX-License-Identifier: Apache-2.0
003  *
004  * Copyright 2019-2022 Andres Almiray.
005  *
006  * Licensed under the Apache License, Version 2.0 (the "License");
007  * you may not use this file except in compliance with the License.
008  * You may obtain a copy of the License at
009  *
010  *     http://www.apache.org/licenses/LICENSE-2.0
011  *
012  * Unless required by applicable law or agreed to in writing, software
013  * distributed under the License is distributed on an "AS IS" BASIS,
014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015  * See the License for the specific language governing permissions and
016  * limitations under the License.
017  */
018 package org.kordamp.gradle.plugin.oci.tasks.autonomous
019 
020 
021 import com.oracle.bmc.database.DatabaseClient
022 import com.oracle.bmc.database.model.AutonomousDatabase
023 import com.oracle.bmc.database.requests.GetAutonomousDatabaseRequest
024 import com.oracle.bmc.database.requests.ListAutonomousDatabasesRequest
025 import com.oracle.bmc.database.requests.RestartAutonomousDatabaseRequest
026 import com.oracle.bmc.database.requests.StartAutonomousDatabaseRequest
027 import com.oracle.bmc.database.requests.StopAutonomousDatabaseRequest
028 import groovy.transform.CompileStatic
029 import org.gradle.api.provider.Property
030 import org.gradle.api.provider.Provider
031 import org.gradle.api.tasks.Input
032 import org.gradle.api.tasks.Internal
033 import org.gradle.api.tasks.options.Option
034 import org.gradle.api.tasks.options.OptionValues
035 import org.kordamp.gradle.plugin.oci.tasks.AbstractOCITask
036 import org.kordamp.gradle.plugin.oci.tasks.interfaces.OCITask
037 import org.kordamp.gradle.plugin.oci.tasks.traits.CompartmentIdAwareTrait
038 import org.kordamp.gradle.plugin.oci.tasks.traits.OptionalDatabaseIdAwareTrait
039 import org.kordamp.gradle.plugin.oci.tasks.traits.OptionalDatabaseNameAwareTrait
040 import org.kordamp.gradle.plugin.oci.tasks.traits.WaitForCompletionAwareTrait
041 import org.kordamp.jipsy.annotations.TypeProviderFor
042 
043 import static org.kordamp.gradle.PropertyUtils.resolveValue
044 import static org.kordamp.gradle.util.StringUtils.isBlank
045 import static org.kordamp.gradle.util.StringUtils.isNotBlank
046 
047 /**
048  @author Andres Almiray
049  @since 0.5.0
050  */
051 @CompileStatic
052 @TypeProviderFor(OCITask)
053 class AutonomousDatabaseActionTask extends AbstractOCITask implements CompartmentIdAwareTrait,
054     OptionalDatabaseIdAwareTrait,
055     OptionalDatabaseNameAwareTrait,
056     WaitForCompletionAwareTrait {
057     static final String TASK_DESCRIPTION = 'Performs a given action on an Database.'
058 
059     private static enum DatabaseAction {
060         START(AutonomousDatabase.LifecycleState.Available),
061         STOP(AutonomousDatabase.LifecycleState.Stopped),
062         RESTART(AutonomousDatabase.LifecycleState.Available)
063 
064         private AutonomousDatabase.LifecycleState state
065 
066         DatabaseAction(AutonomousDatabase.LifecycleState state) {
067             this.state = state
068         }
069 
070         AutonomousDatabase.LifecycleState state() {
071             this.state
072         }
073     }
074 
075     @Internal
076     final Property<DatabaseAction> action = project.objects.property(DatabaseAction)
077 
078     @Option(option = 'action', description = 'The action to be executed (REQUIRED).')
079     void setAction(DatabaseAction action) {
080         getAction().set(action)
081     }
082 
083     @Input
084     Provider<DatabaseAction> getResolvedAction() {
085         project.providers.provider {
086             String value = resolveValue('OCI_DATABASE_ACTION', 'oci.database.action', this, project.name)
087             isNotBlank(value? DatabaseAction.valueOf(value: action.getOrElse(DatabaseAction.STOP)
088         }
089     }
090 
091     @OptionValues("action")
092     List<DatabaseAction> getAvailableActions() {
093         return new ArrayList<DatabaseAction>(Arrays.asList(DatabaseAction.values()))
094     }
095 
096     @Override
097     protected void doExecuteTask() {
098         validateDatabaseId()
099 
100         if (isBlank(getResolvedDatabaseId().orNull&& isBlank(getResolvedDatabaseName().orNull)) {
101             throw new IllegalStateException("Missing value for either 'databaseId' or 'databaseName' in $path")
102         }
103         if (!getResolvedAction()) {
104             throw new IllegalStateException("Missing value for 'action' in $path")
105         }
106 
107         DatabaseClient client = createDatabaseClient()
108 
109         if (isNotBlank(getResolvedDatabaseId().orNull)) {
110             databaseAction(client, getResolvedDatabaseId().get(), getResolvedAction().get())
111         else {
112             validateCompartmentId()
113 
114             client.listAutonomousDatabases(ListAutonomousDatabasesRequest.builder()
115                 .compartmentId(getResolvedCompartmentId().get())
116                 .displayName(getResolvedDatabaseName().get())
117                 .build())
118                 .items.each database ->
119                 setDatabaseId(database.id)
120                 databaseAction(client, database.id, getResolvedAction().get())
121             }
122         }
123     }
124 
125     private void databaseAction(DatabaseClient client, String databaseId, DatabaseAction action) {
126         println("Sending ${getResolvedAction().get().name()} to Database with id ${console.yellow(databaseId)}")
127 
128         switch (action) {
129             case DatabaseAction.START:
130                 client.startAutonomousDatabase(StartAutonomousDatabaseRequest.builder()
131                     .autonomousDatabaseId(databaseId)
132                     .build())
133                 break
134             case DatabaseAction.STOP:
135                 client.stopAutonomousDatabase(StopAutonomousDatabaseRequest.builder()
136                     .autonomousDatabaseId(databaseId)
137                     .build())
138                 break
139             case DatabaseAction.RESTART:
140                 client.restartAutonomousDatabase(RestartAutonomousDatabaseRequest.builder()
141                     .autonomousDatabaseId(databaseId)
142                     .build())
143                 break
144         }
145 
146         if (getResolvedWaitForCompletion().get()) {
147             println("Waiting for Database to be ${state(action.state().name())}")
148             client.waiters
149                 .forAutonomousDatabase(GetAutonomousDatabaseRequest.builder()
150                     .autonomousDatabaseId(databaseId).build(),
151                     action.state())
152                 .execute()
153         }
154     }
155 }