add v16 to local config for graphadmin
[aai/graphadmin.git] / src / main / java / org / onap / aai / migration / v14 / MigrateSdnaIvlanData.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
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
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 package org.onap.aai.migration.v14;
21
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;
31 import java.util.Map;
32 import java.util.Optional;
33
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;
49
50 @MigrationPriority(100)
51 @MigrationDangerRating(1)
52 //@Enabled
53 public class MigrateSdnaIvlanData extends Migrator {
54         
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";
64         
65         GraphTraversal<Vertex, Vertex> serviceSubscriptionGt;
66         
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;
75     
76     
77     private static List<String> dmaapMsgList = new ArrayList<String>();
78     private static final String homeDir = System.getProperty("AJSC_HOME");
79     
80     private static List<String> validPnfList = new ArrayList<String>();
81     private static List<String> invalidPnfList = new ArrayList<String>();
82    
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>>();
85        
86     protected class SdnaIvlanFileData{
87         String evcName;
88         String pnfName;
89                 String interfaceAID;
90         int ivlanValue;
91         
92         public String getEvcName() {
93                         return evcName;
94                 }
95                 public void setEvcName(String evcName) {
96                         this.evcName = evcName;
97                 }
98                 
99                 public String getPnfName() {
100                         return pnfName;
101                 }
102                 public void setPnfName(String pnfName) {
103                         this.pnfName = pnfName;
104                 }
105                 public String getInterfaceAID() {
106                         return interfaceAID;
107                 }
108                 public void setInterfaceAID(String interfaceAID) {
109                         this.interfaceAID = interfaceAID;
110                 }
111                 
112                 public int getIvlanValue() {
113                         return ivlanValue;
114                 }
115                 public void setIvlanValue(int ivlanValue) {
116                         this.ivlanValue = ivlanValue;
117                 }
118                 
119     }
120     
121     private static ArrayList<SdnaIvlanFileData> ivlanList = new ArrayList<SdnaIvlanFileData>();
122    
123         public MigrateSdnaIvlanData(TransactionalGraphEngine engine, LoaderFactory loaderFactory, EdgeIngestor edgeIngestor, EdgeSerializer edgeSerializer, SchemaVersions schemaVersions) {
124                 super(engine, loaderFactory, edgeIngestor, edgeSerializer, schemaVersions);
125                 
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");
128         }
129
130         @Override
131         public void run() {
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");
136             success = false;
137             return;
138         }
139         if (configDir == null) {
140             success = false;
141             return;
142         }
143         
144         String feedDir = homeDir + "/" + configDir + "/" + "migration-input-files/sarea-inventory/";
145
146         int fileLineCounter = 0;
147
148         String fileName = feedDir+ "ivlanData.csv";
149         logger.info(fileName);
150         logger.info("---------- Processing Entries from file  ----------");
151         
152                                 
153         try  {
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) {
160                         
161                         try{
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);
169                                 
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++;
173                         }
174                 
175                     } else {
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;
180                             return;
181                         }
182                     }
183                 }
184                 fileLineCounter++;
185             }
186             
187             processSdnaIvlan();
188             
189             int invalidInterfacesCount = getInvalidInterfaceCount();
190             
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");
196             
197            
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));
201
202         } catch (FileNotFoundException e) {
203             logger.info(this.MIGRATION_ERROR + "ERROR: Could not find file " + fileName, e.getMessage());
204             success = false;
205             checkLog = true;     
206         }  catch (NoSuchFileException e) {
207             logger.info(this.MIGRATION_ERROR + "ERROR: Could not find file " + fileName, e.getMessage());
208             success = false;
209             checkLog = true; 
210         } catch (IOException e) {
211             logger.info(this.MIGRATION_ERROR + "ERROR: Issue reading file " + fileName, e);
212             success = false;
213         } catch (Exception e) {
214             logger.info(this.MIGRATION_ERROR + "encountered exception", e);
215             e.printStackTrace();
216             success = false;
217         }        
218
219         }
220         private void processSdnaIvlan() {
221
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());
227                         
228                         Boolean pnfExists = pnfExists(pnf);
229                         GraphTraversal<Vertex, Vertex> forwarderEvcGT;
230                         Vertex forwarderEvcVtx = null;
231                         String interfaceNodeType;
232                         String forwarderEvcId = null;
233                         
234                         if (!pnfExists){
235                                 migrationFailure++;
236                         }else{
237                                 
238                                 if (interfaceId.contains(".")){
239                                         interfaceNodeType = P_INTERFACE_NODE_TYPE;                                      
240                                 }else{
241                                         interfaceNodeType = LAG_INTERFACE_NODE_TYPE;                                    
242                                 }
243                                 
244                                 validateInterface(pnf, interfaceNodeType, interfaceId);
245
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"); 
254                                 
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);
259                                         
260                                 }
261                                 
262                                 while(forwarderEvcGT.hasNext()){
263                                         forwarderEvcVtx = forwarderEvcGT.next();
264                                         
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);
269                                         }
270                                         // update fwd-evc with ivlan value
271                                         else{
272                                                                                                 
273                                                 forwarderEvcId = forwarderEvcVtx.property("forwarder-evc-id").value().toString();
274                                                 try{
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);
279                                                         migrationSuccess++;     
280                                                         
281                                                 }catch (Exception e){
282                                                         logger.info(e.toString());
283                                                         migrationError(FORWRDER_EVC_NODE_TYPE, forwarderEvcId, "ivlan", ivlanValue);
284                                                 }                                                       
285                                         }
286                                 }       
287                         }
288                 
289                 }
290         }
291         
292         /** 
293          * Description: Validate if pnf node exists in Graph
294          * @param pnf 
295          * @return boolean
296          */
297         private boolean pnfExists(String pnf){
298                 if (invalidPnfList.contains(pnf)){
299                         logger.info(this.MIGRATION_ERROR + "ERROR: PNF value " + pnf + " does not exist.");
300                         return false;
301                 }
302                 if (validPnfList.contains(pnf)){
303                         return true;
304                 }
305                 
306                 GraphTraversal<Vertex, Vertex> pnfGT = g.V()
307                                 .has("pnf-name", pnf).has(AAIProperties.NODE_TYPE, PNF_NODE_TYPE);
308                 
309                 if(pnfGT.hasNext()){
310                         validPnfList.add(pnf);
311                         return true;
312                 }
313                 else{
314                         logger.info(this.MIGRATION_ERROR + "ERROR: PNF value " + pnf + " does not exist.");
315                         invalidPnfList.add(pnf);
316                         return false;
317                 }
318
319         }
320         
321         /**
322          * Description: Validate if p-interface or lag-interface node exists in Graph
323          * @param pnf
324          * @param interfaceNodeType
325          * @param interfaceName
326          */
327         private void validateInterface(String pnf, String interfaceNodeType, String interfaceName){
328                 
329                 List <String> validInterfaceList;
330                 List <String> invalidInterfaceList;
331                 
332                 if(!validInterfaceMap.containsKey(pnf) ){
333                         validInterfaceList = new ArrayList<String>();
334                 }else{
335                         validInterfaceList = validInterfaceMap.get(pnf);                        
336                 }
337                 
338                 if(!invalidInterfaceMap.containsKey(pnf)){
339                         invalidInterfaceList = new ArrayList<String>();
340                 }else{
341                         invalidInterfaceList = invalidInterfaceMap.get(pnf);                    
342                 }
343                 
344                 if(invalidInterfaceList.contains(interfaceName)){
345                         logger.info(this.MIGRATION_ERROR + "ERROR PNF " + pnf  + " with a " + interfaceNodeType + " of " + interfaceName + " does not exist.");
346                         return;
347                 }
348                 if(validInterfaceList.contains(interfaceName)){
349                         return;
350                 }
351                 
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);
356                 
357                 if(interfaceGT.hasNext()){
358                         validInterfaceList.add(interfaceName);  
359                         validInterfaceMap.put(pnf, validInterfaceList);
360                 }
361                 else{
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);
365                 }
366         }
367         
368         
369         /**
370          * Description: Error Routine if graph is not updated by input file record
371          * @param nodeType
372          * @param nodeId
373          * @param property
374          * @param propertyValue
375          */
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");
380                 migrationFailure++;
381         }
382         
383         private int getInvalidInterfaceCount(){
384                 int interfaceCount = 0;
385
386                 for (Map.Entry<String, List<String>> entry: invalidInterfaceMap.entrySet()){
387                 String key = entry.getKey();
388                 List <String> invalidList = invalidInterfaceMap.get(key);
389                                 
390                 for (int i = 0; i < invalidList.size(); i++){
391                         if(invalidList.get(i).contains(".")){
392                                 invalidPInterfaceCount++;
393                         }else{
394                                 invalidLagInterfaceCount++;
395                         }
396                         
397                 }                               
398                 interfaceCount = interfaceCount + invalidInterfaceMap.get(key).size();                          
399         } 
400                 return interfaceCount;
401         }
402         
403         /**
404          * Description: Dmaap Routine
405          * @param v
406          */
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....");
411     }
412                 
413         @Override
414           public Status getStatus() {
415         if (checkLog) {
416             return Status.CHECK_LOGS;
417         }
418         else if (success) {
419             return Status.SUCCESS;
420         }
421         else {
422             return Status.FAILURE;
423         }
424     }
425         
426         @Override
427         public void commit() {
428                 engine.commit();
429                 createDmaapFiles(dmaapMsgList);
430         }
431
432         @Override
433     public Optional<String[]> getAffectedNodeTypes() {
434         return Optional.of(new String[]{this.FORWRDER_EVC_NODE_TYPE});
435     }
436
437
438         @Override
439         public String getMigrationName() {
440                 return "MigrateSdnaIvlanData";
441         }
442
443 }