public static DeviceOracle createDeviceOracle(
      String macStr,
      Long vlan,
      String entityClassName,
      String ipStr,
      String dpidStr,
      Short switchPortNumber)
      throws BigDBException {
    if (macStr == null) {
      throw new BigDBException("Mac Address cannot be null.");
    }
    Short vlanShort = vlan == null ? null : Short.valueOf(vlan.shortValue());
    Integer port = switchPortNumber == null ? null : Integer.valueOf(switchPortNumber);
    Integer ipv4 = ipStr == null ? null : IPv4.toIPv4Address(ipStr);
    Long dpid = dpidStr == null ? null : HexString.toLong(dpidStr);
    IEntityClass entityClass =
        getDeviceService().getEntityClassifier().getEntityClassByName(entityClassName);
    if (entityClass == null) {
      throw new BigDBException(
          "Invalid entity class name, config the " + "entity class first: " + entityClassName);
    }
    Entity en = new Entity(HexString.toLong(macStr), vlanShort, ipv4, dpid, port, null);

    String deviceId = IndexedEntity.getKeyString(entityClassName, en, entityClass.getKeyFields());
    return new DeviceOracle(deviceId, macStr, vlanShort, entityClassName, ipStr, dpidStr, port);
  }
  @BigDBQuery
  public static Object getDeviceOracle(@BigDBParam("query") Query query) throws BigDBException {
    String entityClassName = null;

    assert query.getSteps() != null;
    assert query.getSteps().size() == 1;
    assert query.getStep(0).getName().equals(CURRENT_STEP_NAME);

    Step currentStep = query.getStep(0);

    final String id = currentStep.getExactMatchPredicateString(ID_FIELD_NAME);
    String macStr = currentStep.getExactMatchPredicateString(MAC_FIELD_NAME);
    Long vlanObj = (Long) currentStep.getExactMatchPredicateValue(VLAN_FIELD_NAME);
    entityClassName = currentStep.getExactMatchPredicateString(ENTITY_CLASS_FIELD_NAME);
    String dpidStr = currentStep.getExactMatchPredicateString(SWITCH_DPID_FIELD_NAME);
    Short portShort = (Short) currentStep.getExactMatchPredicateValue(SWITCH_PORT_FIELD_NAME);
    String ipStr = currentStep.getExactMatchPredicateString(IP_ADDRESS_FIELD_NAME);

    if (id != null && (macStr != null || vlanObj != null || entityClassName != null)) {
      throw new BigDBException(
          "This query only accepts a device id or "
              + "a combination of mac, vlan and entity-class-name, "
              + "but not both.");
    }
    if (id != null) {
      // convert from device-id to individual components
      try {
        IndexedEntity.EntityWithClassName e = IndexedEntity.getNamedEntityFromKeyString(id);
        DeviceOracle d =
            new DeviceOracle(
                id,
                e.getEntity().getMacAddress(),
                e.getEntity().getVlan(),
                e.getEntityClassName(),
                e.getEntity().getIpv4Address(),
                e.getEntity().getSwitchDPID(),
                e.getEntity().getSwitchPort());
        ArrayList<DeviceOracle> dd = new ArrayList<DeviceOracle>();
        dd.add(d);
        return dd;
      } catch (Exception e) {
        throw new BigDBException("Invalid device id " + id);
      }
    } else if (macStr != null && entityClassName != null) {
      DeviceOracle d =
          createDeviceOracle(macStr, vlanObj, entityClassName, ipStr, dpidStr, portShort);

      ArrayList<DeviceOracle> dd = new ArrayList<DeviceOracle>();
      dd.add(d);
      return dd;
    } else {
      throw new BigDBException(
          "This query requires a device id or a "
              + "combination of mac, vlan and entity-class-name");
    }
  }