From 75a5dadbe6b4eb6e6838341dffdd2c272b65b35c Mon Sep 17 00:00:00 2001 From: ankitbhatt Date: Tue, 5 Mar 2019 16:34:18 +0530 Subject: Added SDNC MDSAL Data Migrator Functionality. Change-Id: I63ec1a4674d3a3cc6b39708ddee18ae7f9040b1c Issue-ID: SDNC-223 Signed-off-by: ankitbhatt Former-commit-id: c4c27b78ff6b4a8f22553ef3d19aec67edd17482 --- .../onap/sdnc/oam/datamigrator/DataMigration.java | 39 ++++++ .../oam/datamigrator/DataMigrationInternal.java | 148 +++++++++++++++++++++ .../sdnc/oam/datamigrator/common/Description.java | 31 +++++ .../datamigrator/common/MigratorConfiguration.java | 118 ++++++++++++++++ .../sdnc/oam/datamigrator/common/Operation.java | 24 ++++ .../oam/datamigrator/common/RestconfClient.java | 144 ++++++++++++++++++++ .../datamigrator/exceptions/RestconfException.java | 46 +++++++ .../sdnc/oam/datamigrator/migrators/Migrator.java | 136 +++++++++++++++++++ .../migrators/PreloadInformationMigrator.java | 61 +++++++++ .../migrators/RenameDeleteLeafMigrator.java | 62 +++++++++ .../src/main/resources/data-migrator.properties | 27 ++++ data-migrator/src/main/resources/log4j.properties | 37 ++++++ data-migrator/src/main/scripts/runMigration.sh | 48 +++++++ 13 files changed, 921 insertions(+) create mode 100644 data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/DataMigration.java create mode 100644 data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/DataMigrationInternal.java create mode 100644 data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/Description.java create mode 100644 data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/MigratorConfiguration.java create mode 100644 data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/Operation.java create mode 100644 data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/RestconfClient.java create mode 100644 data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/exceptions/RestconfException.java create mode 100644 data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/migrators/Migrator.java create mode 100644 data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/migrators/PreloadInformationMigrator.java create mode 100644 data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/migrators/RenameDeleteLeafMigrator.java create mode 100644 data-migrator/src/main/resources/data-migrator.properties create mode 100644 data-migrator/src/main/resources/log4j.properties create mode 100644 data-migrator/src/main/scripts/runMigration.sh (limited to 'data-migrator/src/main') diff --git a/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/DataMigration.java b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/DataMigration.java new file mode 100644 index 00000000..ac53f448 --- /dev/null +++ b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/DataMigration.java @@ -0,0 +1,39 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : SDNC + * ================================================================================ + * Copyright 2019 AMDOCS + *================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdnc.oam.datamigrator; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DataMigration { + + private static final Logger LOG = LoggerFactory.getLogger(DataMigration.class); + + public static void main(String[] args) { + try { + DataMigrationInternal dataMigrationInternal = new DataMigrationInternal(LOG); + dataMigrationInternal.run(args); + }catch (Exception e){ + e.printStackTrace(); + LOG.error("Error in DataMigration" + e.getMessage()); + } + return; + } +} diff --git a/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/DataMigrationInternal.java b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/DataMigrationInternal.java new file mode 100644 index 00000000..ae497235 --- /dev/null +++ b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/DataMigrationInternal.java @@ -0,0 +1,148 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : SDNC + * ================================================================================ + * Copyright 2019 AMDOCS + *================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdnc.oam.datamigrator; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Strings; +import org.onap.sdnc.oam.datamigrator.common.Description; +import org.onap.sdnc.oam.datamigrator.common.MigratorConfiguration; +import org.onap.sdnc.oam.datamigrator.common.Operation; +import org.onap.sdnc.oam.datamigrator.migrators.Migrator; +import org.reflections.Reflections; +import org.slf4j.Logger; + +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class DataMigrationInternal { + + private final Logger log; + + public DataMigrationInternal(Logger log) { + this.log = log; + } + + private void logAndPrint(String msg) { + System.out.println(msg); + log.info(msg); + } + + public void run(String[] args){ + CommandLineArgs cArgs = new CommandLineArgs(); + JCommander jCommander = new JCommander(cArgs, args); + jCommander.setProgramName(DataMigration.class.getSimpleName()); + + if (cArgs.help) { + jCommander.usage(); + return; + } + + Set> migratorList = getMigratorList(); + if(cArgs.scripts.size() > 0){ + migratorList = migratorList.stream().filter(aClass -> cArgs.scripts.contains(aClass.getSimpleName())).collect(Collectors.toSet()); + } + if(cArgs.excludeClasses.size() > 0){ + migratorList = migratorList.stream().filter(aClass -> !cArgs.excludeClasses.contains(aClass.getSimpleName())).collect(Collectors.toSet()); + } + + if(migratorList.size()>0) { + logAndPrint("Total number of available migrations: " + migratorList.size()); + if(cArgs.list) { + logAndPrint("List of available migrations:"); + for (Class migrator : migratorList) { + if(migrator.getAnnotation(Description.class) != null && !migrator.getAnnotation(Description.class).value().isEmpty()) { + logAndPrint(migrator.getSimpleName()+ ": " + migrator.getAnnotation(Description.class).value() ); + }else { + logAndPrint(migrator.getSimpleName()); + } + } + }else { + Operation operation; + try { + operation = Operation.valueOf(cArgs.operation.toUpperCase()); + logAndPrint("Starting operation: " + operation.name()); + }catch (IllegalArgumentException e) { + logAndPrint("Invalid operation: " + cArgs.operation +". Supported operations are: Migrate, Backup, Restore."); + return; + } + boolean success = true; + MigratorConfiguration config; + if(!Strings.isStringEmpty(cArgs.config)){ + config = new MigratorConfiguration(cArgs.config); + }else { + logAndPrint("No external configuration provided. Initializing Default configuration."); + config = new MigratorConfiguration(); + } + for (Class migratorClass : migratorList) { + logAndPrint("Started executing migrator: "+ migratorClass.getSimpleName()); + try { + Migrator migrator = migratorClass.newInstance(); + migrator.init(config); + migrator.run(operation); + success = success && migrator.isSuccess(); + } catch (InstantiationException | IllegalAccessException e) { + logAndPrint("Error instantiating migrator: " + migratorClass); + success=false; + } + logAndPrint("Completed execution for migrator "+ migratorClass.getSimpleName() +" with status: " + success); + } + if(success){ + logAndPrint(operation.name()+ " operation completed Successfully."); + }else{ + logAndPrint("Error during "+ operation.name() +" operation. Check logs for details."); + } + } + }else{ + logAndPrint("No migrations available."); + } + } + + private Set> getMigratorList() { + Reflections reflections = new Reflections("org.onap.sdnc.oam.datamigrator.migrators"); + return reflections.getSubTypesOf(Migrator.class).stream().filter(aClass -> !Modifier.isAbstract(aClass.getModifiers())).collect(Collectors.toSet()); + } + + class CommandLineArgs { + + @Parameter(names = "--h", help = true) + public boolean help; + + @Parameter(names = "-o", description = "Operation to be performed. Default is Migrate. Supported operations: Migrate , Backup , Restore.") + public String operation = "Migrate"; + + @Parameter(names = "-c", description = "Configuration File path / directory") + public String config; + + @Parameter(names = "-m", description = "Names of migration scripts to run") + public List scripts = new ArrayList<>(); + + @Parameter(names = "-l", description = "List the available of migrations") + public boolean list = false; + + @Parameter(names = "-e", description = "Exclude list of migrator classes") + public List excludeClasses = new ArrayList<>(); + } + + +} diff --git a/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/Description.java b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/Description.java new file mode 100644 index 00000000..3eaf562d --- /dev/null +++ b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/Description.java @@ -0,0 +1,31 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : SDNC + * ================================================================================ + * Copyright 2019 AMDOCS + *================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdnc.oam.datamigrator.common; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Description { + String value() default ""; +} diff --git a/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/MigratorConfiguration.java b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/MigratorConfiguration.java new file mode 100644 index 00000000..40a1b920 --- /dev/null +++ b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/MigratorConfiguration.java @@ -0,0 +1,118 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : SDNC + * ================================================================================ + * Copyright 2019 AMDOCS + *================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdnc.oam.datamigrator.common; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +public class MigratorConfiguration { + + private String sourceHost ; + private String sourceUser ; + private String sourcePassword ; + private String targetHost ; + private String targetUser ; + private String targetPassword ; + private String dataPath; + + private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR"; + private static final Logger LOG = LoggerFactory + .getLogger(MigratorConfiguration.class); + + public MigratorConfiguration (){ + String propDir = System.getenv(SDNC_CONFIG_DIR); + if (propDir == null) { + propDir = "/opt/sdnc/data/properties"; + } + try { + init(propDir); + } catch (Exception e) { + LOG.error("Cannot initialize MigratorConfiguration", e); + } + } + + public MigratorConfiguration (String propDir){ + try { + init(propDir); + } catch (Exception e) { + LOG.error("Cannot initialize MigratorConfiguration", e); + } + } + + public void init(String propDir) throws IOException { + String propPath = propDir + "/data-migrator.properties"; + URL propPathUrl= getClass().getClassLoader().getResource(propPath); + File propFile = (propPathUrl != null) ? new File(propPathUrl.getFile()) : new File(propPath); + if (!propFile.exists()) { + throw new FileNotFoundException( + "Missing configuration properties file : " + + propFile); + } + + Properties props = new Properties(); + props.load(new FileInputStream(propFile)); + this.sourceHost = props.getProperty("org.onap.sdnc.datamigrator.source.host"); + this.sourceUser = props.getProperty("org.onap.sdnc.datamigrator.source.user"); + this.sourcePassword = props.getProperty("org.onap.sdnc.datamigrator.source.password"); + this.targetHost = props.getProperty("org.onap.sdnc.datamigrator.target.host"); + this.targetUser = props.getProperty("org.onap.sdnc.datamigrator.target.user"); + this.targetPassword = props.getProperty("org.onap.sdnc.datamigrator.target.password"); + this.dataPath = props.getProperty("org.onap.sdnc.datamigrator.data.path"); + } + + public String getSourceHost() { + return sourceHost; + } + + public String getSourceUser() { + return sourceUser; + } + + public String getSourcePassword() { + return sourcePassword; + } + + public String getTargetHost() { + return targetHost; + } + + public String getTargetUser() { + return targetUser; + } + + public String getTargetPassword() { + return targetPassword; + } + + public String getDataPath() { + return dataPath; + } + + public void setDataPath(String dataPath) { + this.dataPath = dataPath; + } +} diff --git a/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/Operation.java b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/Operation.java new file mode 100644 index 00000000..df6cd00a --- /dev/null +++ b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/Operation.java @@ -0,0 +1,24 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : SDNC + * ================================================================================ + * Copyright 2019 AMDOCS + *================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdnc.oam.datamigrator.common; + +public enum Operation { + RESTORE,MIGRATE,BACKUP +} diff --git a/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/RestconfClient.java b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/RestconfClient.java new file mode 100644 index 00000000..b7722b6d --- /dev/null +++ b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/common/RestconfClient.java @@ -0,0 +1,144 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : SDNC + * ================================================================================ + * Copyright 2019 AMDOCS + *================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdnc.oam.datamigrator.common; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.onap.sdnc.oam.datamigrator.exceptions.RestconfException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.Authenticator; +import java.net.HttpURLConnection; +import java.net.PasswordAuthentication; +import java.net.URL; +import java.util.Base64; + +public class RestconfClient { + + private HttpURLConnection httpConn = null; + private final String host ; + private final String user ; + private final String password ; + private static final String CONFIG_PATH = "/restconf/config/"; + private static final String CONTENT_TYPE_JSON = "application/json"; + private final Logger log = LoggerFactory.getLogger(RestconfClient.class); + + public RestconfClient (String host , String user , String password){ + this.host = host; + this.user = user; + this.password = password; + } + + private class SdncAuthenticator extends Authenticator { + + private final String user; + private final String passwd; + + SdncAuthenticator(String user, String passwd) { + this.user = user; + this.passwd = passwd; + } + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(user, passwd.toCharArray()); + } + } + + public JsonObject get(String path) throws RestconfException { + String getResponse = send(path,"GET",CONTENT_TYPE_JSON,""); + JsonParser parser = new JsonParser(); + return parser.parse(getResponse).getAsJsonObject(); + } + + public void put(String path, String data) throws RestconfException { + send(path,"PUT",CONTENT_TYPE_JSON, data ); + } + + private String send(String path,String method, String contentType, String msg) throws RestconfException { + Authenticator.setDefault(new SdncAuthenticator(user, password)); + String url = host + CONFIG_PATH + path; + try { + URL sdncUrl = new URL(url); + log.info("SDNC url: " + url); + log.info("Method: " + method); + this.httpConn = (HttpURLConnection) sdncUrl.openConnection(); + String authStr = user + ":" + password; + String encodedAuthStr = new String(Base64.getEncoder().encode(authStr.getBytes())); + httpConn.addRequestProperty("Authentication", "Basic " + encodedAuthStr); + + httpConn.setRequestMethod(method); + httpConn.setRequestProperty("Content-Type", contentType); + httpConn.setRequestProperty("Accept", contentType); + + httpConn.setDoInput(true); + httpConn.setDoOutput(true); + httpConn.setUseCaches(false); + + if (httpConn instanceof HttpsURLConnection) { + HostnameVerifier hostnameVerifier = (hostname, session) -> true; + ((HttpsURLConnection) httpConn).setHostnameVerifier(hostnameVerifier); + } + if (!method.equals("GET")) { + log.info("Request payload: " + msg); + httpConn.setRequestProperty("Content-Length", "" + msg.length()); + DataOutputStream outStr = new DataOutputStream(httpConn.getOutputStream()); + outStr.write(msg.getBytes()); + outStr.close(); + } + + BufferedReader respRdr; + log.info("Response: " + httpConn.getResponseCode() + " " + httpConn.getResponseMessage()); + + if (httpConn.getResponseCode() < 300) { + respRdr = new BufferedReader(new InputStreamReader(httpConn.getInputStream())); + } else { + respRdr = new BufferedReader(new InputStreamReader(httpConn.getErrorStream())); + log.error("Error during restconf operation: "+ method + ". URL:" + sdncUrl.toString()+". Response:"+respRdr); + throw new RestconfException(httpConn.getResponseCode(),"Error during restconf operation: "+ method +". Response:"+respRdr); + } + + StringBuilder respBuff = new StringBuilder(); + String respLn; + while ((respLn = respRdr.readLine()) != null) { + respBuff.append(respLn).append("\n"); + } + respRdr.close(); + String respString = respBuff.toString(); + + log.info("Response body :\n" + respString); + return respString; + }catch (IOException e){ + throw new RestconfException(500,e.getMessage(),e); + }finally { + if (httpConn != null) { + httpConn.disconnect(); + } + } + } + + +} diff --git a/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/exceptions/RestconfException.java b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/exceptions/RestconfException.java new file mode 100644 index 00000000..6b714c29 --- /dev/null +++ b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/exceptions/RestconfException.java @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : SDNC + * ================================================================================ + * Copyright 2019 AMDOCS + *================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdnc.oam.datamigrator.exceptions; + +public class RestconfException extends Exception{ + + private final int errorCode; + private final String errorMessage; + + public RestconfException(int errorCode, String errorMessage) { + super(errorMessage); + this.errorCode = errorCode; + this.errorMessage = errorMessage; + } + + public RestconfException(int errorCode, String errorMessage, Throwable e) { + super(errorMessage,e); + this.errorCode = errorCode; + this.errorMessage = errorMessage; + } + + public int getErrorCode() { + return errorCode; + } + + public String getErrorMessage() { + return errorMessage; + } +} diff --git a/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/migrators/Migrator.java b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/migrators/Migrator.java new file mode 100644 index 00000000..e44a2c73 --- /dev/null +++ b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/migrators/Migrator.java @@ -0,0 +1,136 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : SDNC + * ================================================================================ + * Copyright 2019 AMDOCS + *================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdnc.oam.datamigrator.migrators; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import org.onap.sdnc.oam.datamigrator.common.MigratorConfiguration; +import org.onap.sdnc.oam.datamigrator.common.Operation; +import org.onap.sdnc.oam.datamigrator.common.RestconfClient; +import org.onap.sdnc.oam.datamigrator.exceptions.RestconfException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +public abstract class Migrator { + + protected RestconfClient sourceClient; + protected RestconfClient targetClient; + protected boolean success = true; + private MigratorConfiguration config; + private final Logger log = LoggerFactory.getLogger(PreloadInformationMigrator.class); + + + public void run(Operation operation){ + { + JsonObject sourceData; + if(operation != Operation.RESTORE) { + + try { + sourceData = sourceClient.get(getYangModuleName()+":"+ getSourcePath()); + if(operation == Operation.BACKUP){ + String fileName = getFileName(); + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(fileName)); + writer.write(sourceData.toString()); + writer.close(); + } catch (IOException e) { + log.error("Error writing data to file : " + fileName, e); + success = false; + return; + } + return; + } + } catch (RestconfException e) { + if(e.getErrorCode() == 404){ + log.error("No data available for migration. Returning silent success.", e); + success = true; + }else { + log.error("Error retrieving data from MD-SAL store. Error code: " + e.getErrorCode() + ". Error message:" + e.getErrorMessage(), e); + success = false; + } + return; + } + }else { + String fileName = getFileName(); + try { + Gson gson = new Gson(); + sourceData = gson.fromJson(new BufferedReader(new FileReader(fileName)),JsonObject.class); + } catch (IOException e) { + log.error("Error Reading data from file : " + fileName, e); + success = false; + return; + } + } + try { + String targetData = convertData(sourceData); + targetClient.put(getYangModuleName()+":"+ getTargetPath(),targetData); + } catch (RestconfException e) { + log.error("Error loading data to MD-SAL store. Error code: "+e.getErrorCode()+". Error message:"+e.getErrorMessage(),e); + success=false; + } + } + } + + private String getFileName() { + return config.getDataPath()+ "/" + getYangModuleName()+ "_"+ getSourcePath()+"_"+ getTargetPath() + ".json"; + } + + protected abstract String convertData(JsonObject sourceData); + + public abstract String getYangModuleName(); + public abstract String getSourcePath(); + public abstract String getTargetPath(); + + public void init(MigratorConfiguration config){ + this.config = config; + sourceClient = new RestconfClient(config.getSourceHost(),config.getSourceUser(),config.getSourcePassword()); + targetClient = new RestconfClient(config.getTargetHost(),config.getTargetUser(),config.getTargetPassword()); + } + + public RestconfClient getSourceClient() { + return sourceClient; + } + + public void setSourceClient(RestconfClient sourceClient) { + this.sourceClient = sourceClient; + } + + public RestconfClient getTargetClient() { + return targetClient; + } + + public void setTargetClient(RestconfClient targetClient) { + this.targetClient = targetClient; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } +} + diff --git a/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/migrators/PreloadInformationMigrator.java b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/migrators/PreloadInformationMigrator.java new file mode 100644 index 00000000..d259c216 --- /dev/null +++ b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/migrators/PreloadInformationMigrator.java @@ -0,0 +1,61 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : SDNC + * ================================================================================ + * Copyright 2019 AMDOCS + *================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdnc.oam.datamigrator.migrators; + +import org.onap.sdnc.oam.datamigrator.common.Description; + +import java.util.HashMap; +import java.util.HashSet; + +@Description("Migrator for container 'preload-vnf' in GENERIC-RESOURCE-API.yang") +public class PreloadInformationMigrator extends RenameDeleteLeafMigrator { + + private static final String YANG_MODULE = "GENERIC-RESOURCE-API"; + + static{ + deletedFields = new HashSet<>(); + deletedFields.add("preload-vnfs.vnf-preload-list.preload-data.vnf-topology-information"); + deletedFields.add("preload-vnfs.vnf-preload-list.preload-data.network-topology-information.network-topology-identifier.service-type"); + deletedFields.add("preload-vnfs.vnf-preload-list.preload-data.oper-status.last-action"); + renamedFields = new HashMap<>(); + renamedFields.put("preload-vnfs","preload-information"); + renamedFields.put("preload-vnfs.vnf-preload-list","preload-list"); + renamedFields.put("preload-vnfs.vnf-preload-list.vnf-type","preload-type"); + renamedFields.put("preload-vnfs.vnf-preload-list.vnf-name","preload-id"); + renamedFields.put("preload-vnfs.vnf-preload-list.preload-data.oper-status","preload-oper-status"); + renamedFields.put("preload-vnfs.vnf-preload-list.preload-data.network-topology-information","preload-network-topology-information"); + renamedFields.put("preload-vnfs.vnf-preload-list.preload-data.network-topology-information.network-topology-identifier","network-topology-identifier-structure"); + } + + @Override + public String getYangModuleName() { + return YANG_MODULE; + } + + @Override + public String getSourcePath() { + return "preload-vnfs"; + } + + @Override + public String getTargetPath() { + return "preload-information"; + } +} diff --git a/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/migrators/RenameDeleteLeafMigrator.java b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/migrators/RenameDeleteLeafMigrator.java new file mode 100644 index 00000000..8c0adc0c --- /dev/null +++ b/data-migrator/src/main/java/org/onap/sdnc/oam/datamigrator/migrators/RenameDeleteLeafMigrator.java @@ -0,0 +1,62 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : SDNC + * ================================================================================ + * Copyright 2019 AMDOCS + *================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdnc.oam.datamigrator.migrators; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import org.apache.commons.lang3.StringUtils; +import java.util.Map; +import java.util.Set; + +public abstract class RenameDeleteLeafMigrator extends Migrator { + + protected static Map renamedFields ; + protected static Set deletedFields ; + + @Override + protected String convertData(JsonObject sourceData) { + JsonObject target = convert(sourceData,""); + return target.toString(); + } + + protected JsonObject convert(JsonObject source,String parent) { + JsonObject target = new JsonObject(); + for (String key : source.keySet()){ + String prefixKey = StringUtils.isNotEmpty(parent) ? parent + "."+key : key; + if(!deletedFields.contains(prefixKey)) { + JsonElement value = source.get(key); + if (value.isJsonPrimitive()) { + target.add(renamedFields.getOrDefault(prefixKey,key), value); + } else if(value.isJsonArray()){ + JsonArray targetList = new JsonArray(); + JsonArray sourceArray = value.getAsJsonArray(); + for(JsonElement e : sourceArray){ + targetList.add(convert(e.getAsJsonObject(),prefixKey)); + } + target.add(renamedFields.getOrDefault(prefixKey,key), targetList); + } else{ + target.add(renamedFields.getOrDefault(prefixKey,key), convert(value.getAsJsonObject(),prefixKey)); + } + } + } + return target; + } +} diff --git a/data-migrator/src/main/resources/data-migrator.properties b/data-migrator/src/main/resources/data-migrator.properties new file mode 100644 index 00000000..f5f55a5e --- /dev/null +++ b/data-migrator/src/main/resources/data-migrator.properties @@ -0,0 +1,27 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# Copyright (C) 2019 AMDOCS +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +### + +org.onap.sdnc.datamigrator.source.host=http://localhost:8081 +org.onap.sdnc.datamigrator.source.user=admin +org.onap.sdnc.datamigrator.source.password=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U +org.onap.sdnc.datamigrator.target.host=http://localhost:8082 +org.onap.sdnc.datamigrator.target.user=admin +org.onap.sdnc.datamigrator.target.password=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U +org.onap.sdnc.datamigrator.data.path=C:/DATA \ No newline at end of file diff --git a/data-migrator/src/main/resources/log4j.properties b/data-migrator/src/main/resources/log4j.properties new file mode 100644 index 00000000..d53dc5a8 --- /dev/null +++ b/data-migrator/src/main/resources/log4j.properties @@ -0,0 +1,37 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# Copyright (C) 2019 AMDOCS +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +### + +log4j.rootLogger=DEBUG,CONSOLE,LOGFILE + +# CONSOLE is set to be a ConsoleAppender using a PatternLayout. +log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender +log4j.appender.CONSOLE.Threshold=DEBUG +log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout +log4j.appender.CONSOLE.layout.ConversionPattern=%p %d{yyyy-MM-dd HH:mm:ss.SSS Z} %c{1} - %m%n + + +# LOGFILE is set to be a File appender using a PatternLayout. +log4j.appender.LOGFILE=org.apache.log4j.RollingFileAppender +log4j.appender.LOGFILE.File=/opt/app/data-migrator/data-migrator.log +log4j.appender.LOGFILE.Append=true +log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout +log4j.appender.LOGFILE.layout.ConversionPattern=%p %d{yyyy-MM-dd HH:mm:ss.SSS Z} %c{1} - %m%n +log4j.appender.LOGFILE.MaxFileSize=10MB +log4j.appender.LOGFILE.MaxBackupIndex=10 diff --git a/data-migrator/src/main/scripts/runMigration.sh b/data-migrator/src/main/scripts/runMigration.sh new file mode 100644 index 00000000..e763acbe --- /dev/null +++ b/data-migrator/src/main/scripts/runMigration.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# Copyright (C) 2019 AMDOCS +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +### + +PROPERTY_DIR=${PROPERTY_DIR:-/opt/onap/sdnc/data/properties} +MIGRATION=data-migrator +MIGRATION_ROOT=${MIGRATION_ROOT:-/opt/onap/sdnc/data-migrator} +JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-8-oracle} +JAVA_OPTS=${JAVA_OPTS:--Dhttps.protocols=TLSv1.1,TLSv1.2} +JAVA=${JAVA:-${JAVA_HOME}/bin/java} + +# Redirect output from script to MIGRATION.out +exec >> ${MIGRATION_ROOT}/logs/$MIGRATION.out +exec 2>&1 + +if [ ! -d ${MIGRATION_ROOT}/logs ] +then + mkdir ${MIGRATION_ROOT}/logs +fi + +for file in ${MIGRATION_ROOT}/lib/*.jar +do + CLASSPATH=$CLASSPATH:$file +done + +${JAVA} ${JAVA_OPTS} -Dlog4j.configuration=file:${MIGRATION_ROOT}/properties/log4j.properties -cp ${CLASSPATH} org.onap.sdnc.oam.datamigrator.DataMigration $@ + +echo $! + +exit 0 -- cgit 1.2.3-korg