Merge "Merge Casablanca"
[so.git] / adapters / mso-openstack-adapters / src / main / java / db / migration / R__CloudConfigMigration.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 - 2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package db.migration;
22
23 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
24 import com.fasterxml.jackson.annotation.JsonProperty;
25 import com.fasterxml.jackson.databind.ObjectMapper;
26 import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
27 import org.flywaydb.core.api.MigrationVersion;
28 import org.flywaydb.core.api.migration.MigrationChecksumProvider;
29 import org.flywaydb.core.api.migration.MigrationInfoProvider;
30 import org.flywaydb.core.api.migration.jdbc.JdbcMigration;
31 import org.onap.so.db.catalog.beans.CloudIdentity;
32 import org.onap.so.db.catalog.beans.CloudSite;
33 import org.onap.so.db.catalog.beans.CloudifyManager;
34 import org.onap.so.logger.MsoLogger;
35
36 import java.io.FileInputStream;
37 import java.io.IOException;
38 import java.io.InputStream;
39 import java.nio.file.Paths;
40 import java.sql.Connection;
41 import java.sql.PreparedStatement;
42 import java.sql.ResultSet;
43 import java.sql.SQLException;
44 import java.sql.Statement;
45 import java.util.Collection;
46
47 /**
48  * Performs migration using JDBC Connection from the cloud config provided in the environment (application-{profile}.yaml) and persist data (when not already present) to the catalod database.
49  */
50 @JsonIgnoreProperties(ignoreUnknown = true)
51 public class R__CloudConfigMigration implements JdbcMigration , MigrationInfoProvider, MigrationChecksumProvider {
52     public static final String FLYWAY = "FLYWAY";
53
54     private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA, R__CloudConfigMigration.class);
55     @JsonProperty("cloud_config")
56     private CloudConfig cloudConfig;
57     
58     @Override
59     public boolean isUndo(){
60         return false;
61     }
62
63     @Override
64     public void migrate(Connection connection) throws Exception {
65         LOGGER.debug("Starting migration for CloudConfig");
66         
67         CloudConfig cloudConfig = null;
68         
69         String tableQuery = "SELECT * FROM identity_services";
70         int totalRetries = 20;
71         boolean tableExists = false;
72         int count = 1;
73         while(!tableExists && count != totalRetries) {
74                 try(Statement stmt = connection.createStatement();) {
75                 stmt.executeQuery(tableQuery);
76                 tableExists = true;
77             } catch (SQLException e) {
78                 count++;
79                 // Wait 5 mintues
80                 Thread.sleep(300000);
81             }
82         }
83         
84         // Try the override file
85         String configLocation = System.getProperty("spring.config.additional-location");
86         if (configLocation != null) {
87             try (InputStream stream = new FileInputStream(Paths.get(configLocation).normalize().toString())) {
88                 cloudConfig = loadCloudConfig(stream);
89             }catch(Exception e){
90                 LOGGER.warnSimple("Error Loading override.yaml",e);
91             } 
92         }
93         
94         if (cloudConfig == null) {
95                 LOGGER.debug("No CloudConfig defined in " + configLocation);
96
97                 // Try the application.yaml file
98             try (InputStream stream = R__CloudConfigMigration.class.getResourceAsStream(getApplicationYamlName())) {
99                 cloudConfig = loadCloudConfig(stream);
100             }
101
102             if (cloudConfig == null) {
103                 LOGGER.debug("No CloudConfig defined in " + getApplicationYamlName());
104             }
105         }
106  
107         if(cloudConfig != null){
108             migrateCloudIdentity(cloudConfig.getIdentityServices().values(), connection);
109             migrateCloudSite(cloudConfig.getCloudSites().values(), connection);
110             migrateCloudifyManagers(cloudConfig.getCloudifyManagers().values(), connection);
111         }
112     }
113
114     public CloudConfig getCloudConfig() {
115         return cloudConfig;
116     }
117
118     public void setCloudConfig(CloudConfig cloudConfig) {
119         this.cloudConfig = cloudConfig;
120     }
121
122     private CloudConfig loadCloudConfig(InputStream stream) throws IOException  {
123         ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
124         R__CloudConfigMigration cloudConfigMigration =
125                         mapper.readValue(stream, R__CloudConfigMigration.class);
126         CloudConfig cloudConfig = cloudConfigMigration.getCloudConfig();
127
128         if(cloudConfig != null){
129                 cloudConfig.populateId();
130         }
131
132         return cloudConfig;
133     }
134
135     private String getApplicationYamlName() {
136         String profile = System.getProperty("spring.profiles.active") == null ? "" : "-" + System.getProperty("spring.profiles.active");
137         return "/application" + profile + ".yaml";
138     }
139
140     private void migrateCloudIdentity(Collection<CloudIdentity> entities, Connection connection) throws SQLException  {
141         LOGGER.debug("Starting migration for CloudConfig-->IdentityService");
142         String insert = "INSERT INTO `identity_services` (`ID`, `IDENTITY_URL`, `MSO_ID`, `MSO_PASS`, `ADMIN_TENANT`, `MEMBER_ROLE`, `TENANT_METADATA`, `IDENTITY_SERVER_TYPE`, `IDENTITY_AUTHENTICATION_TYPE`, `LAST_UPDATED_BY`) " +
143                 "VALUES (?,?,?,?,?,?,?,?,?,?);";
144
145         try (Statement stmt = connection.createStatement();PreparedStatement ps = connection.prepareStatement(insert)) {
146             for (CloudIdentity cloudIdentity : entities) {
147                 try (ResultSet rows = stmt.executeQuery("Select count(1) from identity_services where id='" + cloudIdentity.getId() + "'")) {
148                     int count = 0;
149                     while (rows.next()) {
150                         count = rows.getInt(1);
151                     }
152                     if (count == 0) {
153                         ps.setString(1, cloudIdentity.getId());
154                         ps.setString(2, cloudIdentity.getIdentityUrl());
155                         ps.setString(3, cloudIdentity.getMsoId());
156                         ps.setString(4, cloudIdentity.getMsoPass());
157                         ps.setString(5, cloudIdentity.getAdminTenant());
158                         ps.setString(6, cloudIdentity.getMemberRole());
159                         ps.setBoolean(7, cloudIdentity.getTenantMetadata());
160                         ps.setString(8, cloudIdentity.getIdentityServerType() != null ? cloudIdentity.getIdentityServerType().name() : null);
161                         ps.setString(9, cloudIdentity.getIdentityAuthenticationType() != null ? cloudIdentity.getIdentityAuthenticationType().name() : null);
162                         ps.setString(10, FLYWAY);
163                         ps.executeUpdate();
164                     }
165                 }
166             }
167         }
168     }
169
170     private void migrateCloudSite(Collection<CloudSite> entities, Connection connection) throws SQLException  {
171         LOGGER.debug("Starting migration for CloudConfig-->CloudSite");
172         String insert = "INSERT INTO `cloud_sites` (`ID`, `REGION_ID`, `IDENTITY_SERVICE_ID`, `CLOUD_VERSION`, `CLLI`, `CLOUDIFY_ID`, `PLATFORM`, `ORCHESTRATOR`, `LAST_UPDATED_BY`) " +
173                 "VALUES (?,?,?,?,?,?,?,?,?);";
174
175         try (Statement stmt = connection.createStatement();PreparedStatement ps = connection.prepareStatement(insert)) {
176             for (CloudSite cloudSite : entities) {
177                 try (ResultSet rows = stmt.executeQuery("Select count(1) from cloud_sites where id='" + cloudSite.getId() + "'")) {
178                     int count = 0;
179                     while (rows.next()) {
180                         count = rows.getInt(1);
181                     }
182                     if (count == 0) {
183                         ps.setString(1, cloudSite.getId());
184                         ps.setString(2, cloudSite.getRegionId());
185                         ps.setString(3, cloudSite.getIdentityServiceId());
186                         ps.setString(4, cloudSite.getCloudVersion());
187                         ps.setString(5, cloudSite.getClli());
188                         ps.setString(6, cloudSite.getCloudifyId());
189                         ps.setString(7, cloudSite.getPlatform());
190                         ps.setString(8, cloudSite.getOrchestrator());
191                         ps.setString(9, FLYWAY);
192                         ps.executeUpdate();
193                     }
194                 }
195             }
196         }
197     }
198
199     private void migrateCloudifyManagers(Collection<CloudifyManager> entities, Connection connection) throws SQLException  {
200         String insert = "INSERT INTO `cloudify_managers` (`ID`, `CLOUDIFY_URL`, `USERNAME`, `PASSWORD`, `VERSION`, `LAST_UPDATED_BY`)" +
201                 " VALUES (?,?,?,?,?,?);";
202
203         try (Statement stmt = connection.createStatement();PreparedStatement ps = connection.prepareStatement(insert)) {
204             for (CloudifyManager cloudifyManager : entities) {
205                 try (ResultSet rows = stmt.executeQuery("Select count(1) from cloudify_managers where id='" + cloudifyManager.getId() + "'")) {
206                     int count = 0;
207                     while (rows.next()) {
208                         count = rows.getInt(1);
209                     }
210                     if (count == 0) {
211                         ps.setString(1, cloudifyManager.getId());
212                         ps.setString(2, cloudifyManager.getCloudifyUrl());
213                         ps.setString(3, cloudifyManager.getUsername());
214                         ps.setString(4, cloudifyManager.getPassword());
215                         ps.setString(5, cloudifyManager.getVersion());
216                         ps.setString(6, FLYWAY);
217                         ps.executeUpdate();
218                     }
219                 }
220             }
221         }
222     }
223
224     public MigrationVersion getVersion() {
225         return null;
226     }
227
228     public String getDescription() {
229         return "R_CloudConfigMigration";
230     }
231
232     public Integer getChecksum() {
233         return Math.toIntExact(System.currentTimeMillis() / 1000);
234     }
235 }
236