private void applyEip( final VirtualRouterVmInventory vr, final EipStruct struct, final Completion completion) { FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); chain.setName(String.format("apply-eip-%s-vr-%s", struct.getEip().getUuid(), vr.getUuid())); chain .then( new Flow() { @Override public void run(final FlowTrigger trigger, Map data) { asf.openFirewall( vr.getUuid(), struct.getVip().getL3NetworkUuid(), getFirewallRules(struct), new Completion(trigger) { @Override public void success() { trigger.next(); } @Override public void fail(ErrorCode errorCode) { trigger.fail(errorCode); } }); } @Override public void rollback(final FlowRollback trigger, Map data) { asf.removeFirewall( vr.getUuid(), struct.getVip().getL3NetworkUuid(), getFirewallRules(struct), new Completion(trigger) { @Override public void success() { trigger.rollback(); } @Override public void fail(ErrorCode errorCode) { logger.warn( String.format( "failed to remove firewall rules on virtual router[uuid:%s, l3Network uuid:%s], %s", vr.getUuid(), struct.getVip().getL3NetworkUuid(), errorCode)); trigger.rollback(); } }); } }) .then( new NoRollbackFlow() { @Override public void run(final FlowTrigger trigger, Map data) { EipTO to = new EipTO(); String priMac = CollectionUtils.find( vr.getVmNics(), new Function<String, VmNicInventory>() { @Override public String call(VmNicInventory arg) { if (arg.getL3NetworkUuid().equals(struct.getNic().getL3NetworkUuid())) { return arg.getMac(); } return null; } }); to.setPrivateMac(priMac); to.setVipIp(struct.getVip().getIp()); to.setGuestIp(struct.getNic().getIp()); to.setSnatInboundTraffic(struct.isSnatInboundTraffic()); VirtualRouterCommands.CreateEipCmd cmd = new VirtualRouterCommands.CreateEipCmd(); cmd.setEip(to); VirtualRouterAsyncHttpCallMsg msg = new VirtualRouterAsyncHttpCallMsg(); msg.setCheckStatus(true); msg.setPath(VirtualRouterConstant.VR_CREATE_EIP); msg.setCommand(cmd); msg.setVmInstanceUuid(vr.getUuid()); bus.makeTargetServiceIdByResourceUuid( msg, VmInstanceConstant.SERVICE_ID, vr.getUuid()); bus.send( msg, new CloudBusCallBack(completion) { @Override public void run(MessageReply reply) { if (!reply.isSuccess()) { trigger.fail(reply.getError()); return; } VirtualRouterAsyncHttpCallReply re = reply.castReply(); CreateEipRsp ret = re.toResponse(CreateEipRsp.class); if (ret.isSuccess()) { trigger.next(); } else { trigger.fail( errf.stringToOperationError( String.format( "failed to create eip[uuid:%s, name:%s, ip:%s] for vm nic[uuid:%s] on virtual router[uuid:%s], %s", struct.getEip().getUuid(), struct.getEip().getName(), struct.getVip().getIp(), struct.getNic().getUuid(), vr.getUuid(), ret.getError()))); } } }); } }) .done( new FlowDoneHandler(completion) { @Override public void handle(Map data) { String info = String.format( "successfully created eip[uuid:%s, name:%s, ip:%s] for vm nic[uuid:%s] on virtual router[uuid:%s]", struct.getEip().getUuid(), struct.getEip().getName(), struct.getVip().getIp(), struct.getNic().getUuid(), vr.getUuid()); new VirtualRouterRoleManager().makeEipRole(vr.getUuid()); logger.debug(info); completion.success(); } }) .error( new FlowErrorHandler(completion) { @Override public void handle(ErrorCode errCode, Map data) { completion.fail(errCode); } }) .start(); }
@Override public void revokeEip(final EipStruct struct, final Completion completion) { SimpleQuery<VirtualRouterEipRefVO> q = dbf.createQuery(VirtualRouterEipRefVO.class); q.add(VirtualRouterEipRefVO_.eipUuid, SimpleQuery.Op.EQ, struct.getEip().getUuid()); final VirtualRouterEipRefVO ref = q.find(); if (ref == null) { // vr may have been deleted completion.success(); return; } VirtualRouterVmVO vrvo = dbf.findByUuid(ref.getVirtualRouterVmUuid(), VirtualRouterVmVO.class); if (vrvo.getState() != VmInstanceState.Running) { // rule will be synced when vr state changes to Running completion.success(); return; } final VirtualRouterVmInventory vr = VirtualRouterVmInventory.valueOf(vrvo); // TODO: how to cleanup on failure final FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); chain.setName(String.format("revoke-eip-%s-vr-%s", struct.getEip().getUuid(), vr.getUuid())); chain .then( new NoRollbackFlow() { @Override public void run(final FlowTrigger trigger, Map data) { VirtualRouterCommands.RemoveEipCmd cmd = new VirtualRouterCommands.RemoveEipCmd(); EipTO to = new EipTO(); String priMac = CollectionUtils.find( vr.getVmNics(), new Function<String, VmNicInventory>() { @Override public String call(VmNicInventory arg) { if (arg.getL3NetworkUuid().equals(struct.getNic().getL3NetworkUuid())) { return arg.getMac(); } return null; } }); to.setPrivateMac(priMac); to.setSnatInboundTraffic(struct.isSnatInboundTraffic()); to.setVipIp(struct.getVip().getIp()); to.setGuestIp(struct.getNic().getIp()); cmd.setEip(to); VirtualRouterAsyncHttpCallMsg msg = new VirtualRouterAsyncHttpCallMsg(); msg.setVmInstanceUuid(vr.getUuid()); msg.setCommand(cmd); msg.setCheckStatus(true); msg.setPath(VirtualRouterConstant.VR_REMOVE_EIP); bus.makeTargetServiceIdByResourceUuid( msg, VmInstanceConstant.SERVICE_ID, vr.getUuid()); bus.send( msg, new CloudBusCallBack(trigger) { @Override public void run(MessageReply reply) { if (!reply.isSuccess()) { trigger.setError(reply.getError()); } else { VirtualRouterAsyncHttpCallReply re = reply.castReply(); RemoveEipRsp ret = re.toResponse(RemoveEipRsp.class); if (!ret.isSuccess()) { String err = String.format( "failed to remove eip[uuid:%s, name:%s, ip:%s] for vm nic[uuid:%s] on virtual router[uuid:%s], %s", struct.getEip().getUuid(), struct.getEip().getName(), struct.getVip().getIp(), struct.getNic().getUuid(), vr.getUuid(), ret.getError()); trigger.setError(errf.stringToOperationError(err)); } } trigger.next(); } }); } }) .then( new NoRollbackFlow() { @Override public void run(final FlowTrigger trigger, Map data) { asf.removeFirewall( vr.getUuid(), struct.getVip().getL3NetworkUuid(), getFirewallRules(struct), new Completion() { @Override public void success() { trigger.next(); } @Override public void fail(ErrorCode errorCode) { logger.warn( String.format( "failed to remove firewall rules on virtual router[uuid:%s, l3Network uuid:%s], %s", vr.getUuid(), struct.getVip().getL3NetworkUuid(), errorCode)); trigger.next(); } }); } }) .done( new FlowDoneHandler(completion) { @Override public void handle(Map data) { String info = String.format( "successfully removed eip[uuid:%s, name:%s, ip:%s] for vm nic[uuid:%s] on virtual router[uuid:%s]", struct.getEip().getUuid(), struct.getEip().getName(), struct.getVip().getIp(), struct.getNic().getUuid(), vr.getUuid()); logger.debug(info); dbf.remove(ref); completion.success(); } }) .error( new FlowErrorHandler(completion) { @Override public void handle(ErrorCode errCode, Map data) { completion.fail(errCode); } }) .start(); }