Skip to content

Commit

Permalink
Merge pull request apache#2238 from nuagenetworks/feature/caching_and…
Browse files Browse the repository at this point in the history
…_statistics

[CLOUDSTACK-10053] Performance improvement: caching of NuageVsp ID
  • Loading branch information
fmaximus authored Nov 2, 2017
2 parents 587b66d + 0871ff9 commit 2139dbe
Show file tree
Hide file tree
Showing 24 changed files with 3,125 additions and 449 deletions.
2 changes: 2 additions & 0 deletions engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public interface NicSecondaryIpDao extends GenericDao<NicSecondaryIpVO, Long> {

NicSecondaryIpVO findByIp4AddressAndNicId(String ip4Address, long nicId);

NicSecondaryIpVO findByIp4AddressAndInstanceId(Long vmId, String vmIp);

NicSecondaryIpVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, Long vmId, String vmIp);

List<String> getSecondaryIpAddressesForNic(long nicId);
Expand Down
14 changes: 12 additions & 2 deletions engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,10 @@ public NicSecondaryIpVO findByInstanceIdAndNetworkId(long networkId, long instan

@Override
public NicSecondaryIpVO findByIp4AddressAndNetworkId(String ip4Address, long networkId) {
// TODO Auto-generated method stub
return null;
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
sc.setParameters("network", networkId);
sc.setParameters("address", ip4Address);
return findOneBy(sc);
}

@Override
Expand All @@ -131,6 +133,14 @@ public NicSecondaryIpVO findByIp4AddressAndNicId(String ip4Address, long nicId)
return findOneBy(sc);
}

@Override
public NicSecondaryIpVO findByIp4AddressAndInstanceId(Long vmId, String vmIp) {
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
sc.setParameters("instanceId", vmId);
sc.setParameters("address", vmIp);
return findOneBy(sc);
}

@Override
public NicSecondaryIpVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, Long vmId, String vmIp) {
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
Expand Down
2 changes: 1 addition & 1 deletion plugins/network-elements/nuage-vsp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
</repository>
</repositories>
<properties>
<nuage.vsp.client.version>1.0.1</nuage.vsp.client.version>
<nuage.vsp.client.version>1.0.5</nuage.vsp.client.version>
</properties>
<dependencies>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.cloud.agent.api.manager;

import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;

import com.cloud.agent.api.Answer;
import com.cloud.agent.api.guru.ImplementNetworkVspCommand;

/**
* Created by sgoeminn on 3/24/17.
*/
public class ImplementNetworkVspAnswer extends Answer {
private NetworkRelatedVsdIds networkRelatedVsdIds;

public ImplementNetworkVspAnswer(ImplementNetworkVspCommand command, NetworkRelatedVsdIds networkRelatedVsdIds) {
super(command);
this.networkRelatedVsdIds = networkRelatedVsdIds;
}

public ImplementNetworkVspAnswer(ImplementNetworkVspCommand command, Exception e) {
super(command, e);
}

public NetworkRelatedVsdIds getNetworkRelatedVsdIds() {
return networkRelatedVsdIds;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
import javax.inject.Inject;
import javax.naming.ConfigurationException;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import net.nuage.vsp.acs.client.api.model.VspAclRule;
import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
import net.nuage.vsp.acs.client.api.model.VspNetwork;
Expand All @@ -40,8 +38,11 @@
import org.apache.log4j.Logger;

import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;

import org.apache.cloudstack.api.InternalIdentity;
Expand Down Expand Up @@ -521,9 +522,18 @@ public boolean applyStaticNats(Network config, List<? extends StaticNat> rules)
VlanVO sourceNatVlan = _vlanDao.findById(sourceNatIp.getVlanId());
checkVlanUnderlayCompatibility(sourceNatVlan);

if (!staticNat.isForRevoke()) {
final List<FirewallRuleVO> firewallRules = _firewallRulesDao.listByIpAndNotRevoked(staticNat.getSourceIpAddressId());
for (FirewallRuleVO firewallRule : firewallRules) {
_nuageVspEntityBuilder.buildVspAclRule(firewallRule, config, sourceNatIp);
}
}

NicVO nicVO = _nicDao.findByIp4AddressAndNetworkId(staticNat.getDestIpAddress(), staticNat.getNetworkId());
VspStaticNat vspStaticNat = _nuageVspEntityBuilder.buildVspStaticNat(staticNat.isForRevoke(), sourceNatIp, sourceNatVlan, nicVO);
vspStaticNatDetails.add(vspStaticNat);


}

VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(config);
Expand Down Expand Up @@ -632,7 +642,7 @@ public boolean applyNetworkACLs(Network config, List<? extends NetworkACLItem> r
@Override
public boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
List<VpcOfferingServiceMapVO> vpcOfferingServices = _vpcOfferingSrvcDao.listByVpcOffId(vpc.getVpcOfferingId());
Map<Network.Service, Set<Network.Provider>> supportedVpcServices = NuageVspManagerImpl.NUAGE_VSP_VPC_SERVICE_MAP;
Multimap<Service, Provider> supportedVpcServices = NuageVspManagerImpl.NUAGE_VSP_VPC_SERVICE_MAP;
for (VpcOfferingServiceMapVO vpcOfferingService : vpcOfferingServices) {
Network.Service service = Network.Service.getService(vpcOfferingService.getService());
if (!supportedVpcServices.containsKey(service)) {
Expand All @@ -641,7 +651,7 @@ public boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext
}

Network.Provider provider = Network.Provider.getProvider(vpcOfferingService.getProvider());
if (!supportedVpcServices.get(service).contains(provider)) {
if (!supportedVpcServices.containsEntry(service, provider)) {
s_logger.warn(String.format("NuageVsp doesn't support provider %s for service %s for VPCs", provider.getName(), service.getName()));
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,25 @@

import javax.inject.Inject;

import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
import net.nuage.vsp.acs.client.api.model.VspDhcpVMOption;
import net.nuage.vsp.acs.client.api.model.VspDomain;
import net.nuage.vsp.acs.client.api.model.VspNetwork;
import net.nuage.vsp.acs.client.api.model.VspNic;
import net.nuage.vsp.acs.client.api.model.VspStaticNat;
import net.nuage.vsp.acs.client.api.model.VspVm;

import org.apache.log4j.Logger;

import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import org.apache.cloudstack.resourcedetail.VpcDetailVO;
import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
import org.apache.log4j.Logger;

import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
Expand All @@ -36,6 +52,7 @@
import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand;
import com.cloud.agent.api.guru.TrashNetworkVspCommand;
import com.cloud.agent.api.guru.UpdateDhcpOptionVspCommand;
import com.cloud.agent.api.manager.ImplementNetworkVspAnswer;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenter.NetworkType;
Expand Down Expand Up @@ -82,20 +99,6 @@
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.VMInstanceDao;
import com.google.common.base.Strings;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
import net.nuage.vsp.acs.client.api.model.VspDhcpVMOption;
import net.nuage.vsp.acs.client.api.model.VspDomain;
import net.nuage.vsp.acs.client.api.model.VspNetwork;
import net.nuage.vsp.acs.client.api.model.VspNic;
import net.nuage.vsp.acs.client.api.model.VspStaticNat;
import net.nuage.vsp.acs.client.api.model.VspVm;

public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
public static final Logger s_logger = Logger.getLogger(NuageVspGuestNetworkGuru.class);
Expand Down Expand Up @@ -154,6 +157,7 @@ public Network design(NetworkOffering offering, DeploymentPlan plan, Network use
return networkObject;
}

/** In case an externalId is specified, we get called here, and store the id the same way as cached data */
@Override
public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapacityException {
long networkId = network.getId();
Expand Down Expand Up @@ -206,7 +210,7 @@ public Network implement(Network network, NetworkOffering offering, DeployDestin
implemented.setBroadcastUri(Networks.BroadcastDomainType.Vsp.toUri(broadcastUriStr));
implemented.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp);

if (!implement(physicalNetworkId, vspNetwork, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering))) {
if (!implement(network.getVpcId(), physicalNetworkId, vspNetwork, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering))) {
return null;
}

Expand All @@ -227,20 +231,65 @@ public Network implement(Network network, NetworkOffering offering, DeployDestin
return implemented;
}

private boolean implement(long physicalNetworkId, VspNetwork vspNetwork, VspDhcpDomainOption vspDhcpDomainOption) {
private boolean implement(Long vpcId, long physicalNetworkId, VspNetwork vspNetwork, VspDhcpDomainOption vspDhcpDomainOption) {
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(physicalNetworkId);
ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, vspDhcpDomainOption);
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
ImplementNetworkVspAnswer answer = (ImplementNetworkVspAnswer) _agentMgr.easySend(nuageVspHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
s_logger.error("ImplementNetworkVspCommand for network " + vspNetwork.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
if ((null != answer) && (null != answer.getDetails())) {
s_logger.error(answer.getDetails());
}
return false;
}
saveNetworkAndVpcDetails(vspNetwork, answer.getNetworkRelatedVsdIds(), vpcId);
return true;
}

private void saveNetworkAndVpcDetails(VspNetwork vspNetwork, NetworkRelatedVsdIds networkRelatedVsdIds, Long vpcId) {


if (!vspNetwork.isShared() && !vspNetwork.getNetworkRelatedVsdIds().equals(networkRelatedVsdIds)) {
Map<String, String> networkDetails = constructNetworkDetails(networkRelatedVsdIds, vspNetwork.isVpc());

for (Map.Entry<String, String> networkDetail : networkDetails.entrySet()) {
NetworkDetailVO networkDetailVO = new NetworkDetailVO(vspNetwork.getId(), networkDetail.getKey(), networkDetail.getValue(), false);
_networkDetailsDao.persist(networkDetailVO);
}

if(vspNetwork.isVpc()) {
Map<String, String> vpcDetails = constructVpcDetails(networkRelatedVsdIds);

for (Map.Entry<String, String> vpcDetail : vpcDetails.entrySet()) {
VpcDetailVO vpcDetailVO = new VpcDetailVO(vpcId, vpcDetail.getKey(), vpcDetail.getValue(), false);
_vpcDetailsDao.persist(vpcDetailVO);
}
}
}
}

private static Map<String, String> constructNetworkDetails(NetworkRelatedVsdIds networkRelatedVsdIds, boolean isVpc) {
Map<String, String> networkDetails = Maps.newHashMap();

if(!isVpc) {
networkRelatedVsdIds.getVsdDomainId().ifPresent(v -> networkDetails.put(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID, v));
networkRelatedVsdIds.getVsdZoneId().ifPresent(v -> networkDetails.put(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID, v));
}
networkRelatedVsdIds.getVsdSubnetId().ifPresent(v -> networkDetails.put(NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID, v));

return networkDetails;
}

private static Map<String, String> constructVpcDetails(NetworkRelatedVsdIds networkRelatedVsdIds) {
Map<String, String> vpcDetails = Maps.newHashMap();

networkRelatedVsdIds.getVsdDomainId().ifPresent(v -> vpcDetails.put(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID, v));
networkRelatedVsdIds.getVsdZoneId().ifPresent(v -> vpcDetails.put(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID, v));

return vpcDetails;
}


@Override
public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
if (vm.getType() != VirtualMachine.Type.DomainRouter && _nuageVspEntityBuilder.usesVirtualRouter(network.getNetworkOfferingId())) {
Expand Down Expand Up @@ -303,7 +352,7 @@ public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, D

// Make sure the shared network is present
NetworkOffering offering = _ntwkOfferingDao.findById(network.getNetworkOfferingId());
if (!implement(network.getPhysicalNetworkId(), vspNetwork, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering))) {
if (!implement(network.getVpcId(), network.getPhysicalNetworkId(), vspNetwork, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering))) {
s_logger.error("Failed to implement shared network " + network.getUuid() + " under domain " + context.getDomain().getUuid());
throw new InsufficientVirtualNetworkCapacityException("Failed to implement shared network " + network.getUuid() + " under domain " +
context.getDomain().getUuid(), Network.class, network.getId());
Expand Down Expand Up @@ -404,15 +453,12 @@ private void updateDhcpOptionsForExistingVms(Network network, HostVO nuageVspHos
private void checkMultipleSubnetsCombinedWithUseData(Network network) {
if (_ntwkOfferingSrvcDao.listServicesForNetworkOffering(network.getNetworkOfferingId()).contains(Network.Service.UserData.getName())) {
List<VlanVO> vlanVOs = _vlanDao.listVlansByNetworkId(network.getId());
if (vlanVOs.size() > 1) {
VlanVO vlanVoItem = vlanVOs.get(0);
for (VlanVO VlanVoItem2 : FluentIterable.from(vlanVOs).skip(1)) {
if (!vlanVoItem.equals(VlanVoItem2)
&& !VlanVoItem2.getVlanGateway().equals(vlanVoItem.getVlanGateway())) {
if (vlanVOs.stream()
.map(VlanVO::getVlanGateway)
.distinct()
.count() > 1) {
s_logger.error("NuageVsp provider does not support multiple subnets in combination with user data. Network: " + network + ", vlans: " + vlanVOs);
throw new UnsupportedServiceException("NuageVsp provider does not support multiple subnets in combination with user data.");
}
}
}
}
}
Expand All @@ -422,7 +468,7 @@ protected boolean canHandle(NetworkOffering offering, final NetworkType networkT
if (networkType == NetworkType.Advanced
&& isMyTrafficType(offering.getTrafficType())
&& isMyIsolationMethod(physicalNetwork)
&& (offering.getGuestType() == Network.GuestType.Isolated || offering.getGuestType() == Network.GuestType.Shared)
&& (offering.getGuestType() == GuestType.Isolated || offering.getGuestType() == GuestType.Shared)
&& hasRequiredServices(offering)) {
if (_configMgr.isOfferingForVpc(offering) && !offering.getIsPersistent()) {
if (s_logger.isDebugEnabled()) {
Expand Down Expand Up @@ -578,11 +624,7 @@ private boolean getDefaultHasDns(Map<Long, Boolean> cache, Nic nic) {
? Long.valueOf(nic.getNetworkId())
: getDefaultNetwork(nic.getInstanceId());

Boolean hasDns = cache.get(networkId);
if (hasDns == null) {
hasDns = networkHasDns(_networkDao.findById(networkId));
cache.put(networkId, hasDns);
}
Boolean hasDns = cache.computeIfAbsent(networkId, k -> networkHasDns(_networkDao.findById(networkId)));
return hasDns;
}

Expand Down
Loading

0 comments on commit 2139dbe

Please sign in to comment.