2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.onap.aai.migration.v14;
22 import java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.nio.file.Files;
25 import java.nio.file.NoSuchFileException;
26 import java.nio.file.Paths;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
32 import java.util.Optional;
34 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
35 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
36 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
37 import org.apache.tinkerpop.gremlin.structure.Vertex;
38 import org.onap.aai.db.props.AAIProperties;
39 import org.onap.aai.edges.EdgeIngestor;
40 import org.onap.aai.introspection.LoaderFactory;
41 import org.onap.aai.migration.Enabled;
42 import org.onap.aai.migration.MigrationDangerRating;
43 import org.onap.aai.migration.MigrationPriority;
44 import org.onap.aai.migration.Migrator;
45 import org.onap.aai.migration.Status;
46 import org.onap.aai.serialization.db.EdgeSerializer;
47 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
48 import org.onap.aai.setup.SchemaVersions;
50 @MigrationPriority(100)
51 @MigrationDangerRating(1)
53 public class MigrateSdnaIvlanData extends Migrator {
55 private final String CONFIGURATION_NODE_TYPE = "configuration";
56 private final String EVC_NODE_TYPE = "evc";
57 private final String FORWARDER_NODE_TYPE = "forwarder";
58 private final String FORWRDER_EVC_NODE_TYPE = "forwarder-evc";
59 private final String FORWARDING_PATH_NODE_TYPE = "forwarding-path";
60 private final String PNF_NODE_TYPE = "pnf";
61 private final String P_INTERFACE_NODE_TYPE = "p-interface";
62 private final String LAG_INTERFACE_NODE_TYPE = "lag-interface";
63 private final String SAREA_GLOBAL_CUSTOMER_ID = "8a00890a-e6ae-446b-9dbe-b828dbeb38bd";
65 GraphTraversal<Vertex, Vertex> serviceSubscriptionGt;
67 private static GraphTraversalSource g = null;
68 private static boolean success = true;
69 private static boolean checkLog = false;
70 private int headerLength;
71 private int migrationSuccess = 0;
72 private int migrationFailure = 0;
73 private int invalidPInterfaceCount = 0;
74 private int invalidLagInterfaceCount = 0;
77 private static List<String> dmaapMsgList = new ArrayList<String>();
78 private static final String homeDir = System.getProperty("AJSC_HOME");
80 private static List<String> validPnfList = new ArrayList<String>();
81 private static List<String> invalidPnfList = new ArrayList<String>();
83 private static Map<String, List<String>> validInterfaceMap = new HashMap<String, List<String>>();
84 private static Map<String, List<String>> invalidInterfaceMap = new HashMap<String, List<String>>();
86 protected class SdnaIvlanFileData{
92 public String getEvcName() {
95 public void setEvcName(String evcName) {
96 this.evcName = evcName;
99 public String getPnfName() {
102 public void setPnfName(String pnfName) {
103 this.pnfName = pnfName;
105 public String getInterfaceAID() {
108 public void setInterfaceAID(String interfaceAID) {
109 this.interfaceAID = interfaceAID;
112 public int getIvlanValue() {
115 public void setIvlanValue(int ivlanValue) {
116 this.ivlanValue = ivlanValue;
121 private static ArrayList<SdnaIvlanFileData> ivlanList = new ArrayList<SdnaIvlanFileData>();
123 public MigrateSdnaIvlanData(TransactionalGraphEngine engine, LoaderFactory loaderFactory, EdgeIngestor edgeIngestor, EdgeSerializer edgeSerializer, SchemaVersions schemaVersions) {
124 super(engine, loaderFactory, edgeIngestor, edgeSerializer, schemaVersions);
126 this.g = this.engine.asAdmin().getTraversalSource();
127 this.serviceSubscriptionGt = g.V().has("global-customer-id", SAREA_GLOBAL_CUSTOMER_ID).in("org.onap.relationships.inventory.BelongsTo").has("service-type", "SAREA");
132 logger.info("---------- Start migration ----------");
133 String configDir = System.getProperty("BUNDLECONFIG_DIR");
134 if (homeDir == null) {
135 logger.info(this.MIGRATION_ERROR + "ERROR: Could not find sys prop AJSC_HOME");
139 if (configDir == null) {
144 String feedDir = homeDir + "/" + configDir + "/" + "migration-input-files/sarea-inventory/";
146 int fileLineCounter = 0;
148 String fileName = feedDir+ "ivlanData.csv";
149 logger.info(fileName);
150 logger.info("---------- Processing Entries from file ----------");
154 List<String> lines = Files.readAllLines(Paths.get(fileName));
155 Iterator<String> lineItr = lines.iterator();
156 while (lineItr.hasNext()){
157 String line = lineItr.next().trim();
158 if (!line.isEmpty()) {
159 if (fileLineCounter != 0) {
162 String[] colList = line.split(",", -1);
163 SdnaIvlanFileData lineData = new SdnaIvlanFileData();
164 lineData.setEvcName(colList[0].trim());
165 lineData.setPnfName(colList[1].trim());
166 lineData.setInterfaceAID(colList[2].trim());
167 lineData.setIvlanValue(Integer.valueOf(colList[3].trim()));
168 ivlanList.add(lineData);
170 } catch (Exception e){
171 logger.info(this.MIGRATION_ERROR + " ERROR: Record Format is invalid. Expecting Numeric value for Forwarder_Id and Ivlan_Value. Skipping Record: " + line);
172 this.migrationFailure++;
176 this.headerLength = line.split(",", -1).length;
177 if (this.headerLength < 4){
178 logger.info(this.MIGRATION_ERROR + "ERROR: Input file should have atleast 4 columns");
179 this.success = false;
189 int invalidInterfacesCount = getInvalidInterfaceCount();
191 logger.info ("\n \n ******* Final Summary for SDN-A IVLAN Migration ********* \n");
192 logger.info(this.MIGRATION_SUMMARY_COUNT + "SDN-A forward-evcs: IVLANs updated: "+ migrationSuccess);
193 logger.info(this.MIGRATION_SUMMARY_COUNT + "Total File Record Count: "+(fileLineCounter - 1));
194 logger.info(this.MIGRATION_SUMMARY_COUNT + "Unprocessed SDNA File Records : "+ migrationFailure);
195 logger.info(this.MIGRATION_SUMMARY_COUNT + "PNFs from Input File not found : "+ Integer.toString(invalidPnfList.size()) + "\n");
198 logger.info(this.MIGRATION_SUMMARY_COUNT + "Total PNF + P-INTERFACEs from Input File not found : " + Integer.toString(invalidPInterfaceCount));
199 logger.info(this.MIGRATION_SUMMARY_COUNT + "Total PNF + LAG-INTERFACEs from Input File not found : " + Integer.toString(invalidLagInterfaceCount));
200 logger.info(this.MIGRATION_SUMMARY_COUNT + "Total PNF/INTERFACEs from Input File not found : " + Integer.toString(invalidInterfacesCount));
202 } catch (FileNotFoundException e) {
203 logger.info(this.MIGRATION_ERROR + "ERROR: Could not find file " + fileName, e.getMessage());
206 } catch (NoSuchFileException e) {
207 logger.info(this.MIGRATION_ERROR + "ERROR: Could not find file " + fileName, e.getMessage());
210 } catch (IOException e) {
211 logger.info(this.MIGRATION_ERROR + "ERROR: Issue reading file " + fileName, e);
213 } catch (Exception e) {
214 logger.info(this.MIGRATION_ERROR + "encountered exception", e);
220 private void processSdnaIvlan() {
222 for(int i = 0; i < ivlanList.size(); i ++) {
223 String evc = ivlanList.get(i).getEvcName();
224 String pnf = ivlanList.get(i).getPnfName();
225 String interfaceId = ivlanList.get(i).getInterfaceAID();
226 String ivlanValue = Integer.toString(ivlanList.get(i).getIvlanValue());
228 Boolean pnfExists = pnfExists(pnf);
229 GraphTraversal<Vertex, Vertex> forwarderEvcGT;
230 Vertex forwarderEvcVtx = null;
231 String interfaceNodeType;
232 String forwarderEvcId = null;
238 if (interfaceId.contains(".")){
239 interfaceNodeType = P_INTERFACE_NODE_TYPE;
241 interfaceNodeType = LAG_INTERFACE_NODE_TYPE;
244 validateInterface(pnf, interfaceNodeType, interfaceId);
246 forwarderEvcGT = g.V()
247 .has("pnf-name", pnf).has(AAIProperties.NODE_TYPE, PNF_NODE_TYPE)
248 .in("tosca.relationships.network.BindsTo")
249 .has(AAIProperties.NODE_TYPE, interfaceNodeType).has("interface-name", interfaceId)
250 .in("org.onap.relationships.inventory.ForwardsTo")
251 .where(__.out("org.onap.relationships.inventory.BelongsTo").has("forwarding-path-id", evc))
252 .out("org.onap.relationships.inventory.Uses")
253 .in("org.onap.relationships.inventory.BelongsTo");
255 // fwd-evc not found for pnf + interface
256 if(!forwarderEvcGT.hasNext()){
257 forwarderEvcId = pnf + " " + evc;
258 migrationError(PNF_NODE_TYPE + "/" + EVC_NODE_TYPE, forwarderEvcId, "ivlan", ivlanValue);
262 while(forwarderEvcGT.hasNext()){
263 forwarderEvcVtx = forwarderEvcGT.next();
265 // fwd-evc vertex is null
266 if(forwarderEvcVtx == null){
267 forwarderEvcId = pnf + " " + evc;
268 migrationError(PNF_NODE_TYPE + "/" + EVC_NODE_TYPE, forwarderEvcId, "ivlan", ivlanValue);
270 // update fwd-evc with ivlan value
273 forwarderEvcId = forwarderEvcVtx.property("forwarder-evc-id").value().toString();
275 forwarderEvcVtx.property("ivlan", ivlanValue);
276 logger.info(String.format("Updating Node Type forwarder-evc Property ivlan value %s", ivlanValue.toString()));
277 this.touchVertexProperties(forwarderEvcVtx, false);
278 updateDmaapList(forwarderEvcVtx);
281 }catch (Exception e){
282 logger.info(e.toString());
283 migrationError(FORWRDER_EVC_NODE_TYPE, forwarderEvcId, "ivlan", ivlanValue);
293 * Description: Validate if pnf node exists in Graph
297 private boolean pnfExists(String pnf){
298 if (invalidPnfList.contains(pnf)){
299 logger.info(this.MIGRATION_ERROR + "ERROR: PNF value " + pnf + " does not exist.");
302 if (validPnfList.contains(pnf)){
306 GraphTraversal<Vertex, Vertex> pnfGT = g.V()
307 .has("pnf-name", pnf).has(AAIProperties.NODE_TYPE, PNF_NODE_TYPE);
310 validPnfList.add(pnf);
314 logger.info(this.MIGRATION_ERROR + "ERROR: PNF value " + pnf + " does not exist.");
315 invalidPnfList.add(pnf);
322 * Description: Validate if p-interface or lag-interface node exists in Graph
324 * @param interfaceNodeType
325 * @param interfaceName
327 private void validateInterface(String pnf, String interfaceNodeType, String interfaceName){
329 List <String> validInterfaceList;
330 List <String> invalidInterfaceList;
332 if(!validInterfaceMap.containsKey(pnf) ){
333 validInterfaceList = new ArrayList<String>();
335 validInterfaceList = validInterfaceMap.get(pnf);
338 if(!invalidInterfaceMap.containsKey(pnf)){
339 invalidInterfaceList = new ArrayList<String>();
341 invalidInterfaceList = invalidInterfaceMap.get(pnf);
344 if(invalidInterfaceList.contains(interfaceName)){
345 logger.info(this.MIGRATION_ERROR + "ERROR PNF " + pnf + " with a " + interfaceNodeType + " of " + interfaceName + " does not exist.");
348 if(validInterfaceList.contains(interfaceName)){
352 GraphTraversal<Vertex, Vertex> interfaceGT = g.V()
353 .has("pnf-name", pnf).has(AAIProperties.NODE_TYPE, PNF_NODE_TYPE)
354 .in("tosca.relationships.network.BindsTo")
355 .has("interface-name", interfaceName).has(AAIProperties.NODE_TYPE, interfaceNodeType);
357 if(interfaceGT.hasNext()){
358 validInterfaceList.add(interfaceName);
359 validInterfaceMap.put(pnf, validInterfaceList);
362 logger.info(this.MIGRATION_ERROR + "ERROR PNF " + pnf + " with a " + interfaceNodeType + " of " + interfaceName + " does not exist.");
363 invalidInterfaceList.add(interfaceName);
364 invalidInterfaceMap.put(pnf, invalidInterfaceList);
370 * Description: Error Routine if graph is not updated by input file record
374 * @param propertyValue
376 private void migrationError(String nodeType, String nodeId, String property, String propertyValue){
377 logger.info(this.MIGRATION_ERROR + "ERROR: Failure to update "
378 + nodeType + " ID " + nodeId + ", " + property + " to value " + propertyValue
379 + ". Node Not Found \n");
383 private int getInvalidInterfaceCount(){
384 int interfaceCount = 0;
386 for (Map.Entry<String, List<String>> entry: invalidInterfaceMap.entrySet()){
387 String key = entry.getKey();
388 List <String> invalidList = invalidInterfaceMap.get(key);
390 for (int i = 0; i < invalidList.size(); i++){
391 if(invalidList.get(i).contains(".")){
392 invalidPInterfaceCount++;
394 invalidLagInterfaceCount++;
398 interfaceCount = interfaceCount + invalidInterfaceMap.get(key).size();
400 return interfaceCount;
404 * Description: Dmaap Routine
407 private void updateDmaapList(Vertex v){
408 String dmaapMsg = System.nanoTime() + "_" + v.id().toString() + "_" + v.value("resource-version").toString();
409 dmaapMsgList.add(dmaapMsg);
410 logger.info("\tAdding Updated Vertex " + v.id().toString() + " to dmaapMsgList....");
414 public Status getStatus() {
416 return Status.CHECK_LOGS;
419 return Status.SUCCESS;
422 return Status.FAILURE;
427 public void commit() {
429 createDmaapFiles(dmaapMsgList);
433 public Optional<String[]> getAffectedNodeTypes() {
434 return Optional.of(new String[]{this.FORWRDER_EVC_NODE_TYPE});
439 public String getMigrationName() {
440 return "MigrateSdnaIvlanData";