2222import java .io .StringReader ;
2323import java .io .StringWriter ;
2424import java .util .ArrayList ;
25+ import java .util .Arrays ;
2526import java .util .Collections ;
2627import java .util .HashMap ;
2728import java .util .LinkedList ;
@@ -229,93 +230,127 @@ protected List<OVFEulaSectionTO> getOVFEulaSectionFromXmlString(final String ovf
229230 return getEulaSectionsFromDocument (doc );
230231 }
231232
232- public List <DatadiskTO > getOVFVolumeInfoFromFile (final String ovfFilePath ) throws InternalErrorException {
233+ public List <DatadiskTO > getOVFVolumeInfoFromFile (final String ovfFilePath , final String configurationId ) throws InternalErrorException {
233234 if (StringUtils .isBlank (ovfFilePath )) {
234235 return new ArrayList <>();
235236 }
236237 Document doc = getDocumentFromFile (ovfFilePath );
237238
238- return getOVFVolumeInfoFromFile (ovfFilePath , doc );
239+ return getOVFVolumeInfoFromFile (ovfFilePath , doc , configurationId );
239240 }
240241
241- public List <DatadiskTO > getOVFVolumeInfoFromFile (String ovfFilePath , Document doc ) throws InternalErrorException {
242+ public List <DatadiskTO > getOVFVolumeInfoFromFile (String ovfFilePath , Document doc , String configurationId ) throws InternalErrorException {
242243 if (org .apache .commons .lang .StringUtils .isBlank (ovfFilePath )) {
243244 return null ;
244245 }
245246
246247 File ovfFile = new File (ovfFilePath );
247- NodeList disks = doc .getElementsByTagName ("Disk" );
248- NodeList files = doc .getElementsByTagName ("File" );
249- NodeList items = doc .getElementsByTagName ("Item" );
250- List <OVFFile > vf = extractFilesFromOvfDocumentTree (ovfFile , files );
251-
252- List <OVFDisk > vd = extractDisksFromOvfDocumentTree (disks , items );
253-
254- List <DatadiskTO > diskTOs = matchDisksToFilesAndGenerateDiskTOs (ovfFile , vf , vd );
255-
256- moveFirstIsoToEndOfDiskList (diskTOs );
257-
248+ List <OVFVirtualHardwareItemTO > hardwareItems = getVirtualHardwareItemsFromDocumentTree (doc );
249+ List <OVFFile > files = extractFilesFromOvfDocumentTree (ovfFile , doc );
250+ List <OVFDisk > disks = extractDisksFromOvfDocumentTree (doc );
251+
252+ List <OVFVirtualHardwareItemTO > diskHardwareItems = hardwareItems .stream ()
253+ .filter (x -> x .getResourceType () == OVFVirtualHardwareItemTO .HardwareResourceType .DiskDrive &&
254+ hardwareItemContainsConfiguration (x , configurationId ))
255+ .collect (Collectors .toList ());
256+ List <DatadiskTO > diskTOs = matchHardwareItemsToDiskAndFilesInformation (diskHardwareItems , files , disks , ovfFile .getParent ());
258257 return diskTOs ;
259258 }
260259
261- /**
262- * check if first disk is an iso move it to the end. the semantics of this are not complete as more than one ISO may be there and theoretically an OVA may only contain ISOs
263- *
264- */
265- private void moveFirstIsoToEndOfDiskList (List <DatadiskTO > diskTOs ) {
266- if (CollectionUtils .isNotEmpty (diskTOs )) {
267- DatadiskTO fd = diskTOs .get (0 );
268- if (fd .isIso ()) {
269- if (s_logger .isDebugEnabled ()) {
270- s_logger .debug ("moving first disk to the end as it is an ISO" );
271- }
272- diskTOs .remove (0 );
273- diskTOs .add (fd );
260+ private String extractDiskIdFromDiskHostResource (String hostResource ) {
261+ if (hostResource .startsWith ("ovf:/disk/" )) {
262+ return hostResource .replace ("ovf:/disk/" , "" );
263+ }
264+ String [] resourceParts = hostResource .split ("/" );
265+ return resourceParts [resourceParts .length - 1 ];
266+ }
267+
268+ private OVFDisk getDiskDefinitionFromDiskId (String diskId , List <OVFDisk > disks ) {
269+ for (OVFDisk disk : disks ) {
270+ if (disk ._diskId .equalsIgnoreCase (diskId )) {
271+ return disk ;
274272 }
275273 }
274+ return null ;
276275 }
277276
278- private List <DatadiskTO > matchDisksToFilesAndGenerateDiskTOs (File ovfFile , List <OVFFile > vf , List <OVFDisk > vd ) throws InternalErrorException {
279- List <DatadiskTO > diskTOs = new ArrayList <>();
277+ private List <DatadiskTO > matchHardwareItemsToDiskAndFilesInformation (List <OVFVirtualHardwareItemTO > diskHardwareItems ,
278+ List <OVFFile > files , List <OVFDisk > disks ,
279+ String ovfParentPath ) throws InternalErrorException {
280+ List <DatadiskTO > diskTOs = new LinkedList <>();
280281 int diskNumber = 0 ;
281- for (OVFFile of : vf ) {
282- if (StringUtils .isBlank (of ._id )){
283- s_logger .error ("The ovf file info is incomplete file info" );
284- throw new InternalErrorException ("The ovf file info has incomplete file info" );
285- }
286- OVFDisk cdisk = getDisk (of ._id , vd );
287- if (cdisk == null && !of .isIso ){
288- s_logger .error ("The ovf file info has incomplete disk info" );
289- throw new InternalErrorException ("The ovf file info has incomplete disk info" );
282+ for (OVFVirtualHardwareItemTO diskItem : diskHardwareItems ) {
283+ if (StringUtils .isBlank (diskItem .getHostResource ())) {
284+ s_logger .error ("Missing disk information for hardware item " + diskItem .getElementName () + " " + diskItem .getInstanceId ());
285+ continue ;
290286 }
291- Long capacity = cdisk == null ? of ._size : cdisk ._capacity ;
292- String controller = "" ;
293- String controllerSubType = "" ;
294- if (cdisk != null ) {
295- OVFDiskController cDiskController = cdisk ._controller ;
296- controller = cDiskController == null ? "" : cdisk ._controller ._name ;
297- controllerSubType = cDiskController == null ? "" : cdisk ._controller ._subType ;
287+ String diskId = extractDiskIdFromDiskHostResource (diskItem .getHostResource ());
288+ OVFDisk diskDefinition = getDiskDefinitionFromDiskId (diskId , disks );
289+ if (diskDefinition == null ) {
290+ s_logger .error ("Missing disk definition for disk ID " + diskId );
298291 }
292+ OVFFile fileDefinition = getFileDefinitionFromDiskDefinition (diskDefinition ._fileRef , files );
293+ DatadiskTO datadiskTO = generateDiskTO (fileDefinition , diskDefinition , ovfParentPath , diskNumber , diskItem );
294+ diskTOs .add (datadiskTO );
295+ diskNumber ++;
296+ }
297+ List <OVFFile > isoFiles = files .stream ().filter (x -> x .isIso ).collect (Collectors .toList ());
298+ for (OVFFile isoFile : isoFiles ) {
299+ DatadiskTO isoTO = generateDiskTO (isoFile , null , ovfParentPath , diskNumber , null );
300+ diskTOs .add (isoTO );
301+ diskNumber ++;
302+ }
303+ return diskTOs ;
304+ }
299305
300- String dataDiskPath = ovfFile .getParent () + File .separator + of ._href ;
301- File f = new File (dataDiskPath );
306+ private DatadiskTO generateDiskTO (OVFFile file , OVFDisk disk , String ovfParentPath , int diskNumber ,
307+ OVFVirtualHardwareItemTO diskItem ) throws InternalErrorException {
308+ String path = file != null ? ovfParentPath + File .separator + file ._href : null ;
309+ if (StringUtils .isNotBlank (path )) {
310+ File f = new File (path );
302311 if (!f .exists () || f .isDirectory ()) {
303- s_logger .error ("One of the attached disk or iso does not exists " + dataDiskPath );
304- throw new InternalErrorException ("One of the attached disk or iso as stated on OVF does not exists " + dataDiskPath );
312+ s_logger .error ("One of the attached disk or iso does not exists " + path );
313+ throw new InternalErrorException ("One of the attached disk or iso as stated on OVF does not exists " + path );
305314 }
306- diskTOs .add (new DatadiskTO (dataDiskPath , capacity , of ._size , of ._id , of .isIso , of ._bootable , controller , controllerSubType , diskNumber ));
307- diskNumber ++;
308315 }
309- if (s_logger .isTraceEnabled ()) {
310- s_logger .trace (String .format ("found %d file definitions in %s" ,diskTOs .size (), ovfFile .getPath ()));
316+ Long capacity = disk != null ? disk ._capacity : file ._size ;
317+ Long fileSize = file != null ? file ._size : 0L ;
318+
319+ String controller = "" ;
320+ String controllerSubType = "" ;
321+ if (disk != null ) {
322+ OVFDiskController cDiskController = disk ._controller ;
323+ controller = cDiskController == null ? "" : disk ._controller ._name ;
324+ controllerSubType = cDiskController == null ? "" : disk ._controller ._subType ;
311325 }
312- return diskTOs ;
326+
327+ boolean isIso = file != null && file .isIso ;
328+ boolean bootable = file != null && file ._bootable ;
329+ String diskId = disk == null ? file ._id : disk ._diskId ;
330+ String configuration = diskItem != null ? diskItem .getConfigurationIds () : null ;
331+ return new DatadiskTO (path , capacity , fileSize , diskId ,
332+ isIso , bootable , controller , controllerSubType , diskNumber , configuration );
313333 }
314334
315- private List <OVFDisk > extractDisksFromOvfDocumentTree (NodeList disks , NodeList items ) {
335+ protected List <OVFDisk > extractDisksFromOvfDocumentTree (Document doc ) {
336+ NodeList disks = doc .getElementsByTagName ("Disk" );
337+ NodeList ovfDisks = doc .getElementsByTagName ("ovf:Disk" );
338+ NodeList items = doc .getElementsByTagName ("Item" );
339+
340+ int totalDisksLength = disks .getLength () + ovfDisks .getLength ();
316341 ArrayList <OVFDisk > vd = new ArrayList <>();
317- for (int i = 0 ; i < disks .getLength (); i ++) {
318- Element disk = (Element )disks .item (i );
342+ for (int i = 0 ; i < totalDisksLength ; i ++) {
343+ Element disk ;
344+ if (i >= disks .getLength ()) {
345+ int pos = i - disks .getLength ();
346+ disk = (Element ) ovfDisks .item (pos );
347+ } else {
348+ disk = (Element ) disks .item (i );
349+ }
350+
351+ if (disk == null ) {
352+ continue ;
353+ }
319354 OVFDisk od = new OVFDisk ();
320355 String virtualSize = getNodeAttribute (disk , "ovf" , "capacity" );
321356 od ._capacity = NumberUtils .toLong (virtualSize , 0L );
@@ -344,7 +379,8 @@ private List<OVFDisk> extractDisksFromOvfDocumentTree(NodeList disks, NodeList i
344379 return vd ;
345380 }
346381
347- private List <OVFFile > extractFilesFromOvfDocumentTree ( File ovfFile , NodeList files ) {
382+ protected List <OVFFile > extractFilesFromOvfDocumentTree (File ovfFile , Document doc ) {
383+ NodeList files = doc .getElementsByTagName ("File" );
348384 ArrayList <OVFFile > vf = new ArrayList <>();
349385 boolean toggle = true ;
350386 for (int j = 0 ; j < files .getLength (); j ++) {
@@ -528,10 +564,10 @@ private void writeDocumentToFile(String newOvfFilePath, Document doc) {
528564 }
529565 }
530566
531- OVFDisk getDisk (String fileRef , List <OVFDisk > disks ) {
532- for (OVFDisk disk : disks ) {
533- if (disk . _fileRef .equals (fileRef )) {
534- return disk ;
567+ OVFFile getFileDefinitionFromDiskDefinition (String fileRef , List <OVFFile > files ) {
568+ for (OVFFile file : files ) {
569+ if (file . _id .equals (fileRef )) {
570+ return file ;
535571 }
536572 }
537573 return null ;
@@ -653,6 +689,19 @@ private Map<String, NetworkPrerequisiteTO> getNetworksFromDocumentTree(Document
653689 return nets ;
654690 }
655691
692+ private boolean hardwareItemContainsConfiguration (OVFVirtualHardwareItemTO item , String configurationId ) {
693+ if (StringUtils .isBlank (configurationId ) || StringUtils .isBlank (item .getConfigurationIds ())) {
694+ return true ;
695+ }
696+ String configurationIds = item .getConfigurationIds ();
697+ if (StringUtils .isNotBlank (configurationIds )) {
698+ String [] configurations = configurationIds .split (" " );
699+ List <String > confList = Arrays .asList (configurations );
700+ return confList .contains (configurationId );
701+ }
702+ return false ;
703+ }
704+
656705 /**
657706 * Retrieve the virtual hardware section and its deployment options as configurations
658707 */
@@ -663,7 +712,7 @@ public OVFVirtualHardwareSectionTO getVirtualHardwareSectionFromDocument(Documen
663712 for (OVFConfigurationTO configuration : configurations ) {
664713 List <OVFVirtualHardwareItemTO > confItems = items .stream ().
665714 filter (x -> StringUtils .isNotBlank (x .getConfigurationIds ())
666- && x . getConfigurationIds (). toLowerCase (). contains ( configuration .getId ()))
715+ && hardwareItemContainsConfiguration ( x , configuration .getId ()))
667716 .collect (Collectors .toList ());
668717 configuration .setHardwareItems (confItems );
669718 }
@@ -726,6 +775,9 @@ private List<OVFVirtualHardwareItemTO> getVirtualHardwareItemsFromDocumentTree(D
726775 String reservation = getChildNodeValue (configuration , "Reservation" );
727776 String resourceType = getChildNodeValue (configuration , "ResourceType" );
728777 String virtualQuantity = getChildNodeValue (configuration , "VirtualQuantity" );
778+ String hostResource = getChildNodeValue (configuration , "HostResource" );
779+ String addressOnParent = getChildNodeValue (configuration , "AddressOnParent" );
780+ String parent = getChildNodeValue (configuration , "Parent" );
729781 OVFVirtualHardwareItemTO item = new OVFVirtualHardwareItemTO ();
730782 item .setConfigurationIds (configurationIds );
731783 item .setAllocationUnits (allocationUnits );
@@ -739,6 +791,9 @@ private List<OVFVirtualHardwareItemTO> getVirtualHardwareItemsFromDocumentTree(D
739791 item .setResourceType (OVFVirtualHardwareItemTO .getResourceTypeFromId (resType ));
740792 }
741793 item .setVirtualQuantity (getLongValueFromString (virtualQuantity ));
794+ item .setHostResource (hostResource );
795+ item .setAddressOnParent (addressOnParent );
796+ item .setParent (parent );
742797 items .add (item );
743798 }
744799 }
@@ -822,7 +877,6 @@ class OVFDisk {
822877 //<Disk ovf:capacity="50" ovf:capacityAllocationUnits="byte * 2^20" ovf:diskId="vmdisk2" ovf:fileRef="file2"
823878 //ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" ovf:populatedSize="43319296" />
824879 public Long _capacity ;
825- public String _capacityUnit ;
826880 public String _diskId ;
827881 public String _fileRef ;
828882 public Long _populatedSize ;
0 commit comments