/*************************************************************************** * Copyright (c) 2012-2013 VMware, Inc. All Rights Reserved. * 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. ***************************************************************************/ package com.vmware.aurora.composition; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import com.vmware.aurora.vc.MoUtil; import com.vmware.aurora.vc.VcDatacenter; import com.vmware.aurora.vc.vcservice.VcContext; import com.vmware.aurora.vc.vcservice.VcSession; import com.vmware.vim.binding.vim.Folder; import com.vmware.vim.binding.vim.fault.DuplicateName; import com.vmware.vim.binding.vmodl.ManagedObjectReference; import com.vmware.vim.vmomi.core.types.VmodlTypeMap; /** * Stored procedure to create VM folder(s) in a VC data centre. * * This stored procedure can create VM folders, under the top VM folder of a datacenter, down to any level. * If some intermediate folders already exist, it will ignore exception when trying to create them, and continue. * If any other exception is met, it will abort and rethrow the exception, * folders created already won't get deleted. * * If executed successfully, all folders along the path will be recorded. * * @author Xin Li (xinli) * */ public class CreateVMFolderSP implements Callable<Void> { private VcDatacenter dc; private List<String> folderNames; private List<Folder> folders; private Folder startPoint; /** * Create VM folder(s) inside a datacenter. Intermediate folders will be created if needed. * @param dc * @param startPoint Optional, if null, the start point is the top VM folder of the datacenter. * @param folderNames List of folder names. */ public CreateVMFolderSP(VcDatacenter dc, Folder startPoint, List<String> folderNames) { this.dc = dc; this.startPoint = startPoint; this.folderNames = folderNames; } private Folder getChildFolder(Folder folder, String name) throws Exception { ManagedObjectReference[] children = folder.getChildEntity(); for (ManagedObjectReference ref : children) { if (VmodlTypeMap.Factory.getTypeMap().getVmodlType(Folder.class).getWsdlName().equals(ref.getType())) { Folder child = MoUtil.getManagedObject(ref); if (child.getName().equals(name)) { return child; } } } return null; } @Override public Void call() throws Exception { VcContext.inVcSessionDo(new VcSession<Void>() { @Override protected boolean isTaskSession() { return false; } @Override protected Void body() throws Exception { folders = new ArrayList<Folder>(folderNames.size()); Folder folder = startPoint == null ? dc.getVmFolder() : startPoint; for (String folderName : folderNames) { try { Folder child = getChildFolder(folder, folderName); if (child == null) { folder = MoUtil.getManagedObject(folder.createFolder(folderName)); } else { folder = child; } folders.add(folder); } catch (DuplicateName ex) { Folder child = getChildFolder(folder, folderName); if (child == null) { throw new Exception("Folder " + folderName + " should exist, but cannot be found"); } else { folder = child; folders.add(folder); } } } return null; } }); return null; } public List<Folder> getResult() { return folders; } }