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);
  }
  private void handle(APIAttachNetworkServiceProviderToL2NetworkMsg 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);

    APIAttachNetworkServiceProviderToL2NetworkEvent evt =
        new APIAttachNetworkServiceProviderToL2NetworkEvent(msg.getId());
    try {
      provider.attachToL2Network(L2NetworkInventory.valueOf(l2vo), msg);
    } catch (NetworkException e) {
      String err =
          String.format(
              "unable to attach 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.ATTACH_NETWORK_SERVICE_PROVIDER_ERROR, err));
      bus.publish(evt);
      return;
    }

    NetworkServiceProviderL2NetworkRefVO ref = new NetworkServiceProviderL2NetworkRefVO();
    ref.setL2NetworkUuid(l2vo.getUuid());
    ref.setNetworkServiceProviderUuid(vo.getUuid());
    dbf.persist(ref);

    vo = dbf.findByUuid(vo.getUuid(), NetworkServiceProviderVO.class);
    evt.setInventory(NetworkServiceProviderInventory.valueOf(vo));
    String info =
        String.format(
            "successfully attach 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);
  }
  private void populateExtensions() {
    for (NetworkServiceProviderFactory extp :
        pluginRgty.getExtensionList(NetworkServiceProviderFactory.class)) {
      NetworkServiceProviderFactory old = providerFactories.get(extp.getType().toString());
      if (old != null) {
        throw new CloudRuntimeException(
            String.format(
                "duplicate NetworkServiceProviderFactory[%s, %s] for type[%s]",
                extp.getClass().getName(), old.getClass().getName(), extp.getType()));
      }
      providerFactories.put(extp.getType().toString(), extp);
    }

    for (ApplyNetworkServiceExtensionPoint extp :
        pluginRgty.getExtensionList(ApplyNetworkServiceExtensionPoint.class)) {
      ApplyNetworkServiceExtensionPoint old = providerExts.get(extp.getProviderType().toString());
      if (old != null) {
        throw new CloudRuntimeException(
            String.format(
                "duplicate ApplyNetworkServiceExtensionPoint[%s, %s] for type[%s]",
                extp.getClass().getName(), old.getClass().getName(), extp.getProviderType()));
      }
      providerExts.put(extp.getProviderType().toString(), extp);
    }

    nsExts = pluginRgty.getExtensionList(NetworkServiceExtensionPoint.class);
  }