content: // 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.api.query.dao;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import javax.inject.Inject;
  
  import org.apache.cloudstack.annotation.AnnotationService;
  import org.apache.cloudstack.annotation.dao.AnnotationDao;
  import org.apache.cloudstack.context.CallContext;
  import org.apache.commons.lang3.StringUtils;
  import org.springframework.stereotype.Component;
  
  import org.apache.cloudstack.api.response.DomainRouterResponse;
  import org.apache.cloudstack.api.response.NicResponse;
  import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
  import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
  import org.apache.cloudstack.utils.CloudStackVersion;
  
  import com.cloud.api.ApiDBUtils;
  import com.cloud.api.ApiResponseHelper;
  import com.cloud.api.query.vo.DomainRouterJoinVO;
  import com.cloud.dc.HostPodVO;
  import com.cloud.host.ControlState;
  import com.cloud.network.Networks.TrafficType;
  import com.cloud.network.router.VirtualRouter;
  import com.cloud.network.router.VirtualRouter.Role;
  import com.cloud.storage.VMTemplateVO;
  import com.cloud.user.Account;
  import com.cloud.user.AccountManager;
  import com.cloud.utils.db.GenericDaoBase;
  import com.cloud.utils.db.SearchBuilder;
  import com.cloud.utils.db.SearchCriteria;
  
  @Component
  public class DomainRouterJoinDaoImpl extends GenericDaoBase<DomainRouterJoinVO, Long> implements DomainRouterJoinDao {
  
      @Inject
      private ConfigurationDao _configDao;
      @Inject
      public AccountManager _accountMgr;
      @Inject
      private AnnotationDao annotationDao;
  
      private final SearchBuilder<DomainRouterJoinVO> vrSearch;
  
      private final SearchBuilder<DomainRouterJoinVO> vrIdSearch;
      private final SearchBuilder<DomainRouterJoinVO> vrIdTrafficSearch;
  
      protected DomainRouterJoinDaoImpl() {
  
          vrSearch = createSearchBuilder();
          vrSearch.and("idIN", vrSearch.entity().getId(), SearchCriteria.Op.IN);
          vrSearch.done();
  
          vrIdSearch = createSearchBuilder();
          vrIdSearch.and("id", vrIdSearch.entity().getId(), SearchCriteria.Op.EQ);
          vrIdSearch.done();
  
          vrIdTrafficSearch = createSearchBuilder();
          vrIdTrafficSearch.and("id", vrIdTrafficSearch.entity().getId(), SearchCriteria.Op.EQ);
          vrIdTrafficSearch.and("trafficType", vrIdTrafficSearch.entity().getTrafficType(), SearchCriteria.Op.IN);
          vrIdTrafficSearch.done();
  
          _count = "select count(distinct id) from domain_router_view WHERE ";
      }
  
      @Override
      public DomainRouterResponse newDomainRouterResponse(DomainRouterJoinVO router, Account caller) {
          DomainRouterResponse routerResponse = new DomainRouterResponse();
          routerResponse.setId(router.getUuid());
          routerResponse.setZoneId(router.getDataCenterUuid());
          routerResponse.setName(router.getName());
          routerResponse.setTemplateId(router.getTemplateUuid());
          routerResponse.setArch(router.getArch().getType());
          VMTemplateVO template = ApiDBUtils.findTemplateById(router.getTemplateId());
          if (template != null) {
              routerResponse.setTemplateName(template.getName());
          }
          routerResponse.setCreated(router.getCreated());
          routerResponse.setState(router.getState());
          routerResponse.setIsRedundantRouter(router.isRedundantRouter());
          routerResponse.setScriptsVersion(router.getScriptsVersion());
          routerResponse.setSoftwareVersion(router.getSoftwareVersion());
          if (router.getRedundantState() != null) {
              routerResponse.setRedundantState(router.getRedundantState().toString());
          }
          if (router.getTemplateVersion() != null) {
              String routerVersion = CloudStackVersion.trimRouterVersion(router.getTemplateVersion());
              routerResponse.setVersion(routerVersion);
              boolean isTempVersionLower = (CloudStackVersion.compare(routerVersion, NetworkOrchestrationService.MinVRVersion.valueIn(router.getDataCenterId())) < 0);
              if (!isTempVersionLower) {
                  routerResponse.setRequiresUpgrade(false);
              } else {
                  boolean requiresUpgrade = true;
                  String currentCodeVersion = this.getClass().getPackage().getImplementationVersion();
                  if (StringUtils.isNotEmpty(currentCodeVersion)) {
                      currentCodeVersion = CloudStackVersion.parse(currentCodeVersion).toString();
                      String routerSoftwareVersion = router.getSoftwareVersion();
                      if (StringUtils.isNotEmpty(routerSoftwareVersion)) {
                          requiresUpgrade = !(currentCodeVersion.equals(routerSoftwareVersion));
                      }
                  }
                  routerResponse.setRequiresUpgrade(requiresUpgrade);
              }
          } else {
              routerResponse.setVersion("UNKNOWN");
              routerResponse.setRequiresUpgrade(true);
          }
  
          if (router.getHypervisorType() != null) {
              routerResponse.setHypervisor(router.getHypervisorType().getHypervisorDisplayName());
          }
          routerResponse.setHasAnnotation(annotationDao.hasAnnotations(router.getUuid(), AnnotationService.EntityType.VR.name(),
                  _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
  
          if (caller.getType() == Account.Type.RESOURCE_DOMAIN_ADMIN
                  || _accountMgr.isRootAdmin(caller.getId())) {
              if (router.getHostId() != null) {
                  routerResponse.setHostId(router.getHostUuid());
                  routerResponse.setHostName(router.getHostName());
                  routerResponse.setHostControlState(ControlState.getControlState(router.getHostStatus(), router.getHostResourceState()).toString());
              }
              routerResponse.setPodId(router.getPodUuid());
              HostPodVO pod = ApiDBUtils.findPodById(router.getPodId());
              if (pod != null) {
                  routerResponse.setPodName(pod.getName());
              }
              long nic_id = router.getNicId();
              if (nic_id > 0) {
                  TrafficType ty = router.getTrafficType();
                  if (ty != null) {
                      // legacy code, public/control/guest nic info is kept in
                      // nics response object
                      if (ty == TrafficType.Public) {
                          routerResponse.setPublicIp(router.getIpAddress());
                          routerResponse.setPublicMacAddress(router.getMacAddress());
                          routerResponse.setPublicNetmask(router.getNetmask());
                          routerResponse.setGateway(router.getGateway());
                          routerResponse.setPublicNetworkId(router.getNetworkUuid());
                      } else if (ty == TrafficType.Control) {
                          routerResponse.setLinkLocalIp(router.getIpAddress());
                          routerResponse.setLinkLocalMacAddress(router.getMacAddress());
                          routerResponse.setLinkLocalNetmask(router.getNetmask());
                          routerResponse.setLinkLocalNetworkId(router.getNetworkUuid());
                      } else if (ty == TrafficType.Guest) {
                          routerResponse.setGuestIpAddress(router.getIpAddress());
                          routerResponse.setGuestMacAddress(router.getMacAddress());
                          routerResponse.setGuestNetmask(router.getNetmask());
                          routerResponse.setGuestNetworkId(router.getNetworkUuid());
                          routerResponse.setGuestNetworkName(router.getNetworkName());
                          routerResponse.setNetworkDomain(router.getNetworkDomain());
                      }
                  }
  
                  NicResponse nicResponse = new NicResponse();
                  nicResponse.setId(router.getNicUuid());
                  nicResponse.setIpaddress(router.getIpAddress());
                  nicResponse.setGateway(router.getGateway());
                  nicResponse.setNetmask(router.getNetmask());
                  nicResponse.setNetworkid(router.getNetworkUuid());
                  nicResponse.setNetworkName(router.getNetworkName());
                  nicResponse.setMacAddress(router.getMacAddress());
                  nicResponse.setIp6Address(router.getIp6Address());
                  nicResponse.setIp6Gateway(router.getIp6Gateway());
                  nicResponse.setIp6Cidr(router.getIp6Cidr());
                  if (router.getBroadcastUri() != null) {
                      nicResponse.setBroadcastUri(router.getBroadcastUri().toString());
                  }
                  if (router.getIsolationUri() != null) {
                      nicResponse.setIsolationUri(router.getIsolationUri().toString());
                  }
                  if (router.getTrafficType() != null) {
                      nicResponse.setTrafficType(router.getTrafficType().toString());
                  }
                  if (router.getGuestType() != null) {
                      nicResponse.setType(router.getGuestType().toString());
                  }
                  if (router.getMtu() != null){
                      nicResponse.setMtu(router.getMtu());
                  }
                  nicResponse.setIsDefault(router.isDefaultNic());
                  nicResponse.setObjectName("nic");
                  routerResponse.addNic(nicResponse);
              }
          }
  
          routerResponse.setServiceOfferingId(router.getServiceOfferingUuid());
          routerResponse.setServiceOfferingName(router.getServiceOfferingName());
  
          // populate owner.
          ApiResponseHelper.populateOwner(routerResponse, router);
  
          routerResponse.setZoneName(router.getDataCenterName());
          routerResponse.setDns1(router.getDns1());
          routerResponse.setDns2(router.getDns2());
  
          routerResponse.setIp6Dns1(router.getIp6Dns1());
          routerResponse.setIp6Dns2(router.getIp6Dns2());
  
          routerResponse.setVpcId(router.getVpcUuid());
          routerResponse.setVpcName(router.getVpcName());
  
          routerResponse.setRole(router.getRole().toString());
  
          // set async job
          if (router.getJobId() != null) {
              routerResponse.setJobId(router.getJobUuid());
              routerResponse.setJobStatus(router.getJobStatus());
          }
  
          if (router.getRole() == Role.INTERNAL_LB_VM) {
              routerResponse.setObjectName("internalloadbalancervm");
          } else {
              routerResponse.setObjectName("router");
          }
  
          return routerResponse;
      }
  
      @Override
      public DomainRouterResponse setDomainRouterResponse(DomainRouterResponse vrData, DomainRouterJoinVO vr) {
          long nic_id = vr.getNicId();
          if (nic_id > 0) {
              TrafficType ty = vr.getTrafficType();
              if (ty != null) {
                  // legacy code, public/control/guest nic info is kept in
                  // nics response object
                  if (ty == TrafficType.Public) {
                      vrData.setPublicIp(vr.getIpAddress());
                      vrData.setPublicMacAddress(vr.getMacAddress());
                      vrData.setPublicNetmask(vr.getNetmask());
                      vrData.setGateway(vr.getGateway());
                      vrData.setPublicNetworkId(vr.getNetworkUuid());
                  } else if (ty == TrafficType.Control) {
                      vrData.setLinkLocalIp(vr.getIpAddress());
                      vrData.setLinkLocalMacAddress(vr.getMacAddress());
                      vrData.setLinkLocalNetmask(vr.getNetmask());
                      vrData.setLinkLocalNetworkId(vr.getNetworkUuid());
                  } else if (ty == TrafficType.Guest) {
                      vrData.setGuestIpAddress(vr.getIpAddress());
                      vrData.setGuestMacAddress(vr.getMacAddress());
                      vrData.setGuestNetmask(vr.getNetmask());
                      vrData.setGuestNetworkId(vr.getNetworkUuid());
                      vrData.setGuestNetworkName(vr.getNetworkName());
                      vrData.setNetworkDomain(vr.getNetworkDomain());
                  }
              }
              NicResponse nicResponse = new NicResponse();
              nicResponse.setId(vr.getNicUuid());
              nicResponse.setIpaddress(vr.getIpAddress());
              nicResponse.setGateway(vr.getGateway());
              nicResponse.setNetmask(vr.getNetmask());
              nicResponse.setNetworkid(vr.getNetworkUuid());
              nicResponse.setNetworkName(vr.getNetworkName());
              nicResponse.setMacAddress(vr.getMacAddress());
              nicResponse.setIp6Address(vr.getIp6Address());
              nicResponse.setIp6Gateway(vr.getIp6Gateway());
              nicResponse.setIp6Cidr(vr.getIp6Cidr());
              if (vr.getBroadcastUri() != null) {
                  nicResponse.setBroadcastUri(vr.getBroadcastUri().toString());
              }
              if (vr.getIsolationUri() != null) {
                  nicResponse.setIsolationUri(vr.getIsolationUri().toString());
              }
              if (vr.getTrafficType() != null) {
                  nicResponse.setTrafficType(vr.getTrafficType().toString());
              }
              if (vr.getGuestType() != null) {
                  nicResponse.setType(vr.getGuestType().toString());
              }
              if (vr.getMtu() != null) {
                  nicResponse.setMtu(vr.getMtu());
              }
              nicResponse.setIsDefault(vr.isDefaultNic());
              nicResponse.setObjectName("nic");
              vrData.addNic(nicResponse);
          }
          return vrData;
      }
  
      @Override
      public List<DomainRouterJoinVO> searchByIds(Long... vrIds) {
          // set detail batch query size
          int DETAILS_BATCH_SIZE = 2000;
          String batchCfg = _configDao.getValue("detail.batch.query.size");
          if (batchCfg != null) {
              DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg);
          }
          // query details by batches
          List<DomainRouterJoinVO> uvList = new ArrayList<DomainRouterJoinVO>();
          // query details by batches
          int curr_index = 0;
          if (vrIds.length > DETAILS_BATCH_SIZE) {
              while ((curr_index + DETAILS_BATCH_SIZE) <= vrIds.length) {
                  Long[] ids = new Long[DETAILS_BATCH_SIZE];
                  for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) {
                      ids[k] = vrIds[j];
                  }
                  SearchCriteria<DomainRouterJoinVO> sc = vrSearch.create();
                  sc.setParameters("idIN", ids);
                  List<DomainRouterJoinVO> vms = searchIncludingRemoved(sc, null, null, false);
                  if (vms != null) {
                      uvList.addAll(vms);
                  }
                  curr_index += DETAILS_BATCH_SIZE;
              }
          }
          if (curr_index < vrIds.length) {
              int batch_size = (vrIds.length - curr_index);
              // set the ids value
              Long[] ids = new Long[batch_size];
              for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) {
                  ids[k] = vrIds[j];
              }
              SearchCriteria<DomainRouterJoinVO> sc = vrSearch.create();
              sc.setParameters("idIN", ids);
              List<DomainRouterJoinVO> vms = searchIncludingRemoved(sc, null, null, false);
              if (vms != null) {
                  uvList.addAll(vms);
              }
          }
          return uvList;
      }
  
      @Override
      public List<DomainRouterJoinVO> getRouterByIdAndTrafficType(Long id, TrafficType... trafficType) {
          SearchCriteria<DomainRouterJoinVO> sc = vrIdTrafficSearch.create();
          sc.setParameters("id", id);
          sc.setParameters("trafficType", (Object[])trafficType);
          return searchIncludingRemoved(sc, null, null, false);
      }
  
      @Override
      public List<DomainRouterJoinVO> newDomainRouterView(VirtualRouter vr) {
  
          SearchCriteria<DomainRouterJoinVO> sc = vrIdSearch.create();
          sc.setParameters("id", vr.getId());
          return searchIncludingRemoved(sc, null, null, false);
      }
  
  }
  