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