@Override public void preRecoverDataVolume(VolumeInventory vol) { if (vol.getPrimaryStorageUuid() == null) { return; } SimpleQuery<PrimaryStorageVO> q = dbf.createQuery(PrimaryStorageVO.class); q.select(PrimaryStorageVO_.type); q.add(PrimaryStorageVO_.uuid, Op.EQ, vol.getPrimaryStorageUuid()); String type = q.findValue(); if (!LocalStorageConstants.LOCAL_STORAGE_TYPE.equals(type)) { return; } SimpleQuery<LocalStorageResourceRefVO> rq = dbf.createQuery(LocalStorageResourceRefVO.class); rq.add(LocalStorageResourceRefVO_.resourceUuid, Op.EQ, vol.getUuid()); rq.add(LocalStorageResourceRefVO_.resourceType, Op.EQ, VolumeVO.class.getSimpleName()); if (!rq.isExists()) { throw new OperationFailureException( errf.stringToOperationError( String.format( "the data volume[name:%s, uuid:%s] is on the local storage[uuid:%s]; however," + "the host on which the data volume is has been deleted. Unable to recover this volume", vol.getName(), vol.getUuid(), vol.getPrimaryStorageUuid()))); } }
@Override public NetworkServiceProviderType getTypeOfNetworkServiceProviderForService( String l3NetworkUuid, NetworkServiceType serviceType) { L3NetworkVO l3vo = dbf.findByUuid(l3NetworkUuid, L3NetworkVO.class); L3NetworkInventory l3inv = L3NetworkInventory.valueOf(l3vo); NetworkServiceL3NetworkRefInventory targetRef = null; for (NetworkServiceL3NetworkRefInventory ref : l3inv.getNetworkServices()) { if (ref.getNetworkServiceType().equals(serviceType.toString())) { targetRef = ref; break; } } if (targetRef == null) { throw new OperationFailureException( errf.stringToOperationError( String.format( "L3Network[uuid:%s] doesn't have network service[type:%s] enabled or no provider provides this network service", l3NetworkUuid, serviceType))); } SimpleQuery<NetworkServiceProviderVO> q = dbf.createQuery(NetworkServiceProviderVO.class); q.select(NetworkServiceProviderVO_.type); q.add(NetworkServiceProviderVO_.uuid, Op.EQ, targetRef.getNetworkServiceProviderUuid()); String providerType = q.findValue(); return NetworkServiceProviderType.valueOf(providerType); }
public List<String> getTags(String resourceUuid, Class resourceClass) { SimpleQuery<SystemTagVO> q = dbf.createQuery(SystemTagVO.class); q.select(SystemTagVO_.tag); q.add(SystemTagVO_.resourceType, Op.EQ, resourceClass.getSimpleName()); q.add(SystemTagVO_.resourceUuid, Op.EQ, resourceUuid); q.add(SystemTagVO_.tag, useOp(), useTagFormat()); return q.listValue(); }
private void handle(APIDetachNetworkServiceProviderFromL2NetworkMsg msg) { NetworkServiceProviderVO vo = dbf.findByUuid(msg.getNetworkServiceProviderUuid(), NetworkServiceProviderVO.class); NetworkServiceProviderFactory factory = getProviderFactory(vo.getType()); NetworkServiceProvider provider = factory.getNetworkServiceProvider(vo); L2NetworkVO l2vo = dbf.findByUuid(msg.getL2NetworkUuid(), L2NetworkVO.class); APIDetachNetworkServiceProviderFromL2NetworkEvent evt = new APIDetachNetworkServiceProviderFromL2NetworkEvent(msg.getId()); try { provider.detachFromL2Network(L2NetworkInventory.valueOf(l2vo), msg); } catch (NetworkException e) { String err = String.format( "unable to detach network service provider[uuid:%s, name:%s, type:%s] to l2network[uuid:%s, name:%s, type:%s], %s", vo.getUuid(), vo.getName(), vo.getType(), l2vo.getUuid(), l2vo.getName(), l2vo.getType(), e.getMessage()); logger.warn(err, e); evt.setErrorCode( errf.instantiateErrorCode( NetworkServiceErrors.DETACH_NETWORK_SERVICE_PROVIDER_ERROR, err)); bus.publish(evt); return; } SimpleQuery<NetworkServiceProviderL2NetworkRefVO> query = dbf.createQuery(NetworkServiceProviderL2NetworkRefVO.class); query.select(NetworkServiceProviderL2NetworkRefVO_.id); query.add(NetworkServiceProviderL2NetworkRefVO_.l2NetworkUuid, Op.EQ, l2vo.getUuid()); query.add( NetworkServiceProviderL2NetworkRefVO_.networkServiceProviderUuid, Op.EQ, vo.getUuid()); Long id = query.findValue(); if (id != null) { dbf.removeByPrimaryKey(id, NetworkServiceProviderL2NetworkRefVO.class); } vo = dbf.findByUuid(vo.getUuid(), NetworkServiceProviderVO.class); evt.setInventory(NetworkServiceProviderInventory.valueOf(vo)); String info = String.format( "successfully detach network service provider[uuid:%s, name:%s, type:%s] to l2network[uuid:%s, name:%s, type:%s]", vo.getUuid(), vo.getName(), vo.getType(), l2vo.getUuid(), l2vo.getName(), l2vo.getType()); logger.debug(info); bus.publish(evt); }
@Override public void preAttachVolume(VmInstanceInventory vm, final VolumeInventory volume) { SimpleQuery<LocalStorageResourceRefVO> q = dbf.createQuery(LocalStorageResourceRefVO.class); q.add( LocalStorageResourceRefVO_.resourceUuid, Op.IN, list(vm.getRootVolumeUuid(), volume.getUuid())); q.groupBy(LocalStorageResourceRefVO_.hostUuid); long count = q.count(); if (count < 2) { return; } q = dbf.createQuery(LocalStorageResourceRefVO.class); q.select(LocalStorageResourceRefVO_.hostUuid); q.add(LocalStorageResourceRefVO_.resourceUuid, Op.EQ, vm.getRootVolumeUuid()); String rootHost = q.findValue(); q = dbf.createQuery(LocalStorageResourceRefVO.class); q.select(LocalStorageResourceRefVO_.hostUuid); q.add(LocalStorageResourceRefVO_.resourceUuid, Op.EQ, volume.getUuid()); String dataHost = q.findValue(); if (!rootHost.equals(dataHost)) { throw new OperationFailureException( errf.stringToOperationError( String.format( "cannot attach the data volume[uuid:%s] to the vm[uuid:%s]. Both vm's root volume and the data volume are" + " on local primary storage, but they are on different hosts. The root volume[uuid:%s] is on the host[uuid:%s] but the data volume[uuid: %s]" + " is on the host[uuid: %s]", volume.getUuid(), vm.getUuid(), vm.getRootVolumeUuid(), rootHost, volume.getUuid(), dataHost))); } }
@Override public void run(final FlowTrigger trigger, final Map data) { final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); VolumeInventory volume = spec.getDestDataVolumes().get(0); SimpleQuery<LocalStorageResourceRefVO> q = dbf.createQuery(LocalStorageResourceRefVO.class); q.select(LocalStorageResourceRefVO_.hostUuid, LocalStorageResourceRefVO_.primaryStorageUuid); q.add( LocalStorageResourceRefVO_.resourceUuid, Op.EQ, spec.getVmInventory().getRootVolumeUuid()); Tuple t = q.findTuple(); final String hostUuid = t.get(0, String.class); String priUuid = t.get(1, String.class); AllocatePrimaryStorageMsg msg = new AllocatePrimaryStorageMsg(); if (isThereOtherStorageForTheHost(hostUuid, priUuid)) { // use network-shared primary storage msg.addExcludeAllocatorStrategy(LocalStorageConstants.LOCAL_STORAGE_ALLOCATOR_STRATEGY); msg.addExcludePrimaryStoratgeUuid(priUuid); } else { msg.setAllocationStrategy(LocalStorageConstants.LOCAL_STORAGE_ALLOCATOR_STRATEGY); msg.setRequiredPrimaryStorageUuid( spec.getVmInventory().getRootVolume().getPrimaryStorageUuid()); } msg.setRequiredHostUuid(hostUuid); msg.setVmInstanceUuid(spec.getVmInventory().getUuid()); msg.setSize(volume.getSize()); msg.setPurpose(PrimaryStorageAllocationPurpose.CreateVolume.toString()); bus.makeLocalServiceId(msg, PrimaryStorageConstant.SERVICE_ID); bus.send( msg, new CloudBusCallBack(trigger) { @Override public void run(MessageReply reply) { if (!reply.isSuccess()) { trigger.fail(reply.getError()); return; } spec.setDestHost(HostInventory.valueOf(dbf.findByUuid(hostUuid, HostVO.class))); AllocatePrimaryStorageReply ar = (AllocatePrimaryStorageReply) reply; data.put( VmInstanceConstant.Params.DestPrimaryStorageInventoryForAttachingVolume.toString(), ar.getPrimaryStorageInventory()); data.put(LocalStorageAllocateCapacityForAttachingVolumeFlow.class, ar.getSize()); trigger.next(); } }); }
private String steppingAllocate(long s, long e, int total, String rangeUuid) { int step = 254; int failureCount = 0; int failureCheckPoint = 5; while (s < e) { // if failing failureCheckPoint times, the range is probably full, // we check the range. // why don't we check before steppingAllocate()? because in that case we // have to count the used IP every time allocating a IP, and count operation // is a full scan in DB, which is very costly if (failureCheckPoint == failureCount++) { SimpleQuery<UsedIpVO> q = dbf.createQuery(UsedIpVO.class); q.add(UsedIpVO_.ipRangeUuid, Op.EQ, rangeUuid); long count = q.count(); if (count == total) { logger.debug( String.format("ip range[uuid:%s] has no ip available, try next one", rangeUuid)); return null; } else { failureCount = 0; } } long te = s + step; te = te > e ? e : te; SimpleQuery<UsedIpVO> q = dbf.createQuery(UsedIpVO.class); q.select(UsedIpVO_.ipInLong); q.add(UsedIpVO_.ipInLong, Op.GTE, s); q.add(UsedIpVO_.ipInLong, Op.LTE, te); q.add(UsedIpVO_.ipRangeUuid, Op.EQ, rangeUuid); List<Long> used = q.listValue(); if (te - s + 1 == used.size()) { s += step; continue; } Collections.sort(used); return NetworkUtils.randomAllocateIpv4Address(s, te, used); } return null; }
public Map<String, List<String>> getTags(List<String> resourceUuids, Class resourceClass) { SimpleQuery<SystemTagVO> q = dbf.createQuery(SystemTagVO.class); q.select(SystemTagVO_.tag, SystemTagVO_.resourceUuid); q.add(SystemTagVO_.resourceType, Op.EQ, resourceClass.getSimpleName()); q.add(SystemTagVO_.resourceUuid, Op.IN, resourceUuids); q.add(SystemTagVO_.tag, useOp(), useTagFormat()); List<Tuple> ts = q.listTuple(); Map<String, List<String>> ret = new HashMap<String, List<String>>(); for (Tuple t : ts) { String uuid = t.get(1, String.class); List<String> tags = ret.get(uuid); if (tags == null) { tags = new ArrayList<String>(); ret.put(uuid, tags); } tags.add(t.get(0, String.class)); } return ret; }
@Override public void run(final FlowTrigger chain, final Map data) { final VirtualRouterVmInventory vr = (VirtualRouterVmInventory) data.get(VirtualRouterConstant.Param.VR.toString()); List<String> nwServed = vr.getGuestL3Networks(); List<String> l3Uuids = vrMgr.selectL3NetworksNeedingSpecificNetworkService(nwServed, NetworkServiceType.DNS); if (l3Uuids.isEmpty()) { chain.next(); return; } if (VirtualRouterSystemTags.DEDICATED_ROLE_VR.hasTag(vr.getUuid()) && !VirtualRouterSystemTags.VR_DNS_ROLE.hasTag(vr.getUuid())) { chain.next(); return; } new VirtualRouterRoleManager().makeDnsRole(vr.getUuid()); SimpleQuery<L3NetworkDnsVO> query = dbf.createQuery(L3NetworkDnsVO.class); query.select(L3NetworkDnsVO_.dns); query.add(L3NetworkDnsVO_.l3NetworkUuid, Op.IN, l3Uuids); List<String> lst = query.listValue(); if (lst.isEmpty()) { chain.next(); return; } Set<String> dnsAddresses = new HashSet<String>(lst.size()); dnsAddresses.addAll(lst); final List<DnsInfo> dns = new ArrayList<DnsInfo>(dnsAddresses.size()); for (String d : dnsAddresses) { DnsInfo dinfo = new DnsInfo(); dinfo.setDnsAddress(d); dns.add(dinfo); } SetDnsCmd cmd = new SetDnsCmd(); cmd.setDns(dns); VirtualRouterAsyncHttpCallMsg msg = new VirtualRouterAsyncHttpCallMsg(); msg.setVmInstanceUuid(vr.getUuid()); msg.setPath(VirtualRouterConstant.VR_SET_DNS_PATH); msg.setCommand(cmd); msg.setCommandTimeout(apiTimeoutManager.getTimeout(cmd.getClass(), "5m")); bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vr.getUuid()); bus.send( msg, new CloudBusCallBack(chain) { @Override public void run(MessageReply reply) { if (!reply.isSuccess()) { chain.fail(reply.getError()); return; } VirtualRouterAsyncHttpCallReply re = reply.castReply(); SetDnsRsp ret = re.toResponse(SetDnsRsp.class); if (ret.isSuccess()) { chain.next(); } else { String err = String.format( "virtual router[name: %s, uuid: %s] failed to configure dns%s, %s ", vr.getName(), vr.getUuid(), JSONObjectUtil.toJsonString(dns), ret.getError()); logger.warn(err); chain.fail(errf.stringToOperationError(err)); } } }); }
@Override public void beforeDeleteHost(final HostInventory inventory) { SimpleQuery<LocalStorageHostRefVO> q = dbf.createQuery(LocalStorageHostRefVO.class); q.select(LocalStorageHostRefVO_.primaryStorageUuid); q.add(LocalStorageHostRefVO_.hostUuid, Op.EQ, inventory.getUuid()); final String psUuid = q.findValue(); if (psUuid == null) { return; } logger.debug( String.format( "the host[uuid:%s] belongs to the local storage[uuid:%s], starts to delete vms and" + " volumes on the host", inventory.getUuid(), psUuid)); final List<String> vmUuids = new Callable<List<String>>() { @Override @Transactional(readOnly = true) public List<String> call() { String sql = "select vm.uuid from VolumeVO vol, LocalStorageResourceRefVO ref, VmInstanceVO vm where ref.primaryStorageUuid = :psUuid" + " and vol.type = :vtype and ref.resourceUuid = vol.uuid and ref.resourceType = :rtype and ref.hostUuid = :huuid" + " and vm.uuid = vol.vmInstanceUuid"; TypedQuery<String> q = dbf.getEntityManager().createQuery(sql, String.class); q.setParameter("vtype", VolumeType.Root); q.setParameter("rtype", VolumeVO.class.getSimpleName()); q.setParameter("huuid", inventory.getUuid()); q.setParameter("psUuid", psUuid); return q.getResultList(); } }.call(); // destroy vms if (!vmUuids.isEmpty()) { List<DestroyVmInstanceMsg> msgs = CollectionUtils.transformToList( vmUuids, new Function<DestroyVmInstanceMsg, String>() { @Override public DestroyVmInstanceMsg call(String uuid) { DestroyVmInstanceMsg msg = new DestroyVmInstanceMsg(); msg.setVmInstanceUuid(uuid); bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, uuid); return msg; } }); final FutureCompletion completion = new FutureCompletion(); bus.send( msgs, new CloudBusListCallBack(completion) { @Override public void run(List<MessageReply> replies) { for (MessageReply r : replies) { if (!r.isSuccess()) { String vmUuid = vmUuids.get(replies.indexOf(r)); // TODO logger.warn( String.format("failed to destroy the vm[uuid:%s], %s", vmUuid, r.getError())); } } completion.success(); } }); completion.await(TimeUnit.MINUTES.toMillis(15)); } final List<String> volUuids = new Callable<List<String>>() { @Override @Transactional(readOnly = true) public List<String> call() { String sql = "select vol.uuid from VolumeVO vol, LocalStorageResourceRefVO ref where ref.primaryStorageUuid = :psUuid" + " and vol.type = :vtype and ref.resourceUuid = vol.uuid and ref.resourceType = :rtype and ref.hostUuid = :huuid"; TypedQuery<String> q = dbf.getEntityManager().createQuery(sql, String.class); q.setParameter("psUuid", psUuid); q.setParameter("vtype", VolumeType.Data); q.setParameter("rtype", VolumeVO.class.getSimpleName()); q.setParameter("huuid", inventory.getUuid()); return q.getResultList(); } }.call(); // delete data volumes if (!volUuids.isEmpty()) { List<DeleteVolumeMsg> msgs = CollectionUtils.transformToList( volUuids, new Function<DeleteVolumeMsg, String>() { @Override public DeleteVolumeMsg call(String uuid) { DeleteVolumeMsg msg = new DeleteVolumeMsg(); msg.setUuid(uuid); msg.setDetachBeforeDeleting(true); bus.makeTargetServiceIdByResourceUuid(msg, VolumeConstant.SERVICE_ID, uuid); return msg; } }); final FutureCompletion completion = new FutureCompletion(); bus.send( msgs, new CloudBusListCallBack(completion) { @Override public void run(List<MessageReply> replies) { for (MessageReply r : replies) { if (!r.isSuccess()) { String uuid = volUuids.get(replies.indexOf(r)); // TODO logger.warn( String.format( "failed to delete the data volume[uuid:%s], %s", uuid, r.getError())); } } completion.success(); } }); completion.await(TimeUnit.MINUTES.toMillis(15)); } }