2 * ============LICENSE_START=======================================================
3 * ONAP : ccsdk features
4 * ================================================================================
5 * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.ccsdk.features.sdnr.wt.dataprovider.setup.database;
25 import java.sql.SQLException;
26 import java.text.ParseException;
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.stream.Collectors;
30 import org.onap.ccsdk.features.sdnr.wt.common.database.data.DatabaseVersion;
31 import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBClient;
32 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.SdnrDbType;
33 import org.onap.ccsdk.features.sdnr.wt.dataprovider.setup.DataMigrationProviderService;
34 import org.onap.ccsdk.features.sdnr.wt.dataprovider.setup.ReleaseInformation;
35 import org.onap.ccsdk.features.sdnr.wt.dataprovider.setup.data.ComponentName;
36 import org.onap.ccsdk.features.sdnr.wt.dataprovider.setup.data.DataMigrationReport;
37 import org.onap.ccsdk.features.sdnr.wt.dataprovider.setup.data.Release;
38 import org.onap.ccsdk.features.sdnr.wt.dataprovider.setup.data.ReleaseGroup;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
42 public class MariaDbDataMigrationProvider implements DataMigrationProviderService {
45 private static final Logger LOG = LoggerFactory.getLogger(MariaDbDataMigrationProvider.class);
46 private static final SdnrDbType DBTYPE = SdnrDbType.MARIADB;
47 private static final String LOG_DELETING_INDEX = "deleting index {}";
48 private final SqlDBClient dbClient;
50 public MariaDbDataMigrationProvider(String url, String username, String password, boolean trustAll,
51 long timeoutms) throws Exception {
52 dbClient = new SqlDBClient(url, username, password);
56 public DataMigrationReport importData(String filename, boolean dryrun) throws Exception {
57 return this.importData(filename, dryrun, Release.CURRENT_RELEASE);
61 public DataMigrationReport importData(String filename, boolean dryrun, Release forRelease) throws Exception {
62 throw new RuntimeException("not supported anymore");
67 * export data if file exists .1 (.n) will be created
70 public DataMigrationReport exportData(String filename) {
71 throw new RuntimeException("not supported anymore");
74 private String checkFilenameForWrite(String filename) {
75 File f = new File(filename);
79 return this.checkFilenameForWrite(filename, 0);
82 private String checkFilenameForWrite(String filename, int apdx) {
83 File f = new File(String.format("$s.$d", filename, apdx));
87 return this.checkFilenameForWrite(filename, apdx + 1);
91 public Release getCurrentVersion() {
92 return Release.CURRENT_RELEASE;
97 public Release autoDetectRelease() {
98 DatabaseVersion dbVersion;
100 dbVersion = this.dbClient.readActualVersion();
101 } catch (SQLException | ParseException e) {
102 LOG.error("unable to detect db version", e);
105 var views = this.dbClient.readViews();
106 var tables = this.dbClient.readTables();
107 if (tables == null) {
110 List<Release> foundReleases = new ArrayList<>();
111 //if there are active aliases reduce indices to the active ones
112 if (views != null && !views.isEmpty()) {
113 tables = tables.stream()
114 .filter(e -> views.stream().anyMatch(v -> v.getTableReference().equals(e.getName())))
115 .collect(Collectors.toUnmodifiableList());
117 for (Release r : Release.values()) {
118 if (r.isDbInRange(dbVersion)) {
119 ReleaseInformation ri = ReleaseInformation.getInstance(r);
120 if (ri != null && ri.containsIndices(tables)) {
121 foundReleases.add(r);
125 if (foundReleases.size() == 1) {
126 return foundReleases.get(0);
128 LOG.error("detect {} releases: {}. unable to detect for which one to do sth.", foundReleases.size(),
134 public boolean initDatabase(Release release, int numShards, int numReplicas, String dbPrefix, boolean forceRecreate,
137 this.dbClient.waitForYellowStatus(timeoutms);
139 DatabaseVersion dbVersion;
141 dbVersion = this.dbClient.readActualVersion();
142 } catch (SQLException | ParseException e1) {
143 LOG.error("unable to detect db version", e1);
146 if (dbVersion == null) {
149 LOG.info("detected database version {}", dbVersion);
150 if (release == null) {
151 release = ReleaseGroup.CURRENT_RELEASE.getLatestCompatibleRelease(dbVersion);
152 if (release == null) {
153 LOG.warn("unable to autodetect release for this database version for release {}",
154 ReleaseGroup.CURRENT_RELEASE.name());
157 LOG.info("autodetect release {}", release);
159 if (!release.isDbInRange(dbVersion)) {
160 LOG.warn("db version {} maybe not compatible with release {}", dbVersion, release);
164 this.clearDatabase(release, dbPrefix, 0);
166 ReleaseInformation ri = ReleaseInformation.getInstance(release);
167 var views = this.dbClient.readViews();
168 var tables = this.dbClient.readTables();
169 if (views == null || tables == null) {
172 boolean response = false;
173 if (!ri.runPreInitCommands(this.dbClient)) {
176 for (ComponentName component : ri.getComponents()) {
178 if (ri.hasOwnDbIndex(component)) {
179 //check if index already exists
180 String tableName = ri.getIndex(component, dbPrefix);
181 String viewName = ri.getAlias(component, dbPrefix);
182 if (!tables.stream().anyMatch(e->e.getName().equals(tableName))) {
183 LOG.info("creating index for {}", component);
184 response = this.dbClient.createTable(ri.getIndex(component, dbPrefix),
185 ri.getDatabaseMapping(component, DBTYPE));
186 LOG.info(response ? "succeeded" : "failed");
188 LOG.info("index {} for {} already exists", tableName, component);
190 //check if alias already exists
191 if (!views.stream().anyMatch(e->e.getName().equals(viewName))) {
192 LOG.info("creating alias for {}", component);
193 response = this.dbClient.createView(tableName, viewName);
194 LOG.info(response ? "succeeded" : "failed");
196 LOG.info("view {} for table {} for {} already exists", viewName, tableName, component);
199 } catch (SQLException e) {
200 LOG.error(e.getMessage());
204 if (!ri.runPostInitCommands(this.dbClient)) {
211 public boolean clearDatabase(Release release, String dbPrefix, long timeoutms) {
214 this.dbClient.waitForYellowStatus(timeoutms);
217 var entries = this.dbClient.readViews();
218 var entries2 = this.dbClient.readTables();
219 if (entries == null) {
222 if (release == null) {
223 DatabaseVersion dbVersion;
225 dbVersion = this.dbClient.readActualVersion();
226 } catch (SQLException | ParseException e) {
227 LOG.error("unable to detect db version", e);
230 LOG.info("detected database version {}", dbVersion);
231 release = ReleaseGroup.CURRENT_RELEASE.getLatestCompatibleRelease(dbVersion);
232 if (release == null) {
233 LOG.warn("unable to autodetect release for this database version for release {}",
234 ReleaseGroup.CURRENT_RELEASE.name());
237 LOG.info("autodetect release {}", release);
239 ReleaseInformation ri = ReleaseInformation.getInstance(release);
241 if (entries.isEmpty()) {
242 LOG.info("no aliases to clear");
244 //check for every component of release if alias exists
245 for (ComponentName component : ri.getComponents()) {
246 String aliasToDelete = ri.getAlias(component, dbPrefix);
247 var entryToDelete = entries.stream().filter(e->e.getName().equals(aliasToDelete)).findFirst().orElse(null);
248 if (entryToDelete != null) {
250 LOG.info("deleting alias {} for index {}", entryToDelete.getName(), entryToDelete.getTableReference());
251 response = this.dbClient.deleteView(entryToDelete.getName());
252 LOG.info(response ? "succeeded" : "failed");
253 } catch (SQLException e) {
254 LOG.error(e.getMessage());
258 //try to find malformed typed index with alias name
259 var entry2ToDelete = entries2.stream().filter(e->e.getName().equals(aliasToDelete)).findFirst().orElse(null);
260 if (entry2ToDelete != null) {
262 LOG.info(LOG_DELETING_INDEX, entry2ToDelete.getName());
263 response = this.dbClient.deleteTable(entry2ToDelete.getName());
264 LOG.info(response ? "succeeded" : "failed");
265 } catch (SQLException e) {
266 LOG.error(e.getMessage());
273 if (entries2 == null) {
276 if (entries2.isEmpty()) {
277 LOG.info("no indices to clear");
279 //check for every component of release if index exists
280 for (ComponentName component : ri.getComponents()) {
281 String indexToDelete = ri.getIndex(component, dbPrefix);
282 var entryToDelete = entries2.stream().filter(e->e.getName().equals(indexToDelete)).findFirst().orElse(null);
283 if (entryToDelete != null) {
285 LOG.info(LOG_DELETING_INDEX, entryToDelete.getName());
286 response = this.dbClient.deleteTable(entryToDelete.getName());
287 LOG.info(response ? "succeeded" : "failed");
288 } catch (SQLException e) {
289 LOG.error(e.getMessage());
303 public boolean clearCompleteDatabase(long timeoutms) {
305 this.dbClient.waitForYellowStatus(timeoutms);
307 //check aliases and indices
308 var aliases = this.dbClient.readViews();
309 var indices = this.dbClient.readTables();
310 if (aliases == null || indices == null) {
313 for (var alias : aliases) {
315 LOG.info("deleting alias {} for index {}", alias.getName(), alias.getTableReference());
316 this.dbClient.deleteView(alias.getName());
317 } catch (SQLException e) {
318 LOG.error("problem deleting alias {}: {}", alias.getName(), e);
322 for (var index : indices) {
324 LOG.info(LOG_DELETING_INDEX, index.getName());
325 this.dbClient.deleteTable(index.getName());
326 } catch (SQLException e) {
327 LOG.error("problem deleting index {}: {}", index.getName(), e);