@Override
  @DB
  public RemoteAccessVpnVO startRemoteAccessVpn(long vpnId, boolean openFirewall)
      throws ResourceUnavailableException {
    Account caller = UserContext.current().getCaller();

    RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findById(vpnId);
    if (vpn == null) {
      throw new InvalidParameterValueException("Unable to find your vpn: " + vpnId);
    }

    _accountMgr.checkAccess(caller, null, true, vpn);

    Network network = _networkMgr.getNetwork(vpn.getNetworkId());

    boolean started = false;
    try {
      boolean firewallOpened = true;
      if (openFirewall) {
        firewallOpened = _firewallMgr.applyIngressFirewallRules(vpn.getServerAddressId(), caller);
      }

      if (firewallOpened) {
        for (RemoteAccessVPNServiceProvider element : _vpnServiceProviders) {
          if (element.startVpn(network, vpn)) {
            started = true;
            break;
          }
        }
      }

      return vpn;
    } finally {
      if (started) {
        Transaction txn = Transaction.currentTxn();
        txn.start();
        vpn.setState(RemoteAccessVpn.State.Running);
        _remoteAccessVpnDao.update(vpn.getServerAddressId(), vpn);

        // Start billing of existing VPN users in ADD and Active state
        List<VpnUserVO> vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId());
        for (VpnUserVO user : vpnUsers) {
          if (user.getState() != VpnUser.State.Revoke) {
            UsageEventUtils.publishUsageEvent(
                EventTypes.EVENT_VPN_USER_ADD,
                user.getAccountId(),
                0,
                user.getId(),
                user.getUsername(),
                user.getClass().getName(),
                user.getUuid());
          }
        }
        txn.commit();
      }
    }
  }
  @Override
  @DB
  public VpnUser addVpnUser(long vpnOwnerId, String username, String password) {
    Account caller = UserContext.current().getCaller();

    if (!username.matches("^[a-zA-Z0-9][a-zA-Z0-9@._-]{2,63}$")) {
      throw new InvalidParameterValueException(
          "Username has to be begin with an alphabet have 3-64 characters including alphabets, numbers and the set '@.-_'");
    }
    if (!password.matches("^[a-zA-Z0-9][a-zA-Z0-9@#+=._-]{2,31}$")) {
      throw new InvalidParameterValueException(
          "Password has to be 3-32 characters including alphabets, numbers and the set '@#+=.-_'");
    }
    Transaction txn = Transaction.currentTxn();
    txn.start();
    Account owner = _accountDao.lockRow(vpnOwnerId, true);
    if (owner == null) {
      throw new InvalidParameterValueException("Unable to add vpn user: Another operation active");
    }
    _accountMgr.checkAccess(caller, null, true, owner);

    // don't allow duplicated user names for the same account
    VpnUserVO vpnUser = _vpnUsersDao.findByAccountAndUsername(owner.getId(), username);
    if (vpnUser != null) {
      throw new InvalidParameterValueException(
          "VPN User with name " + username + " is already added for account " + owner);
    }

    long userCount = _vpnUsersDao.getVpnUserCount(owner.getId());
    if (userCount >= _userLimit) {
      throw new AccountLimitException(
          "Cannot add more than " + _userLimit + " remote access vpn users");
    }

    VpnUser user =
        _vpnUsersDao.persist(new VpnUserVO(vpnOwnerId, owner.getDomainId(), username, password));
    UsageEventUtils.publishUsageEvent(
        EventTypes.EVENT_VPN_USER_ADD,
        user.getAccountId(),
        0,
        user.getId(),
        user.getUsername(),
        user.getClass().getName(),
        user.getUuid());
    txn.commit();
    return user;
  }
Пример #3
0
 private static int getTotalTuples(int tableid) {
   int count = 0;
   try {
     Transaction t = new Transaction();
     t.start();
     SeqScan s = new SeqScan(t.getId(), tableid, null);
     s.open();
     while (s.hasNext()) {
       s.next();
       count++;
     }
     t.commit();
   } catch (Exception e) {
     e.printStackTrace();
     throw new RuntimeException(e);
   }
   return count;
 }
 @DB
 @Override
 public boolean removeVpnUser(long vpnOwnerId, String username, Account caller) {
   VpnUserVO user = _vpnUsersDao.findByAccountAndUsername(vpnOwnerId, username);
   if (user == null) {
     throw new InvalidParameterValueException("Could not find vpn user " + username);
   }
   _accountMgr.checkAccess(caller, null, true, user);
   Transaction txn = Transaction.currentTxn();
   txn.start();
   user.setState(State.Revoke);
   _vpnUsersDao.update(user.getId(), user);
   UsageEventUtils.publishUsageEvent(
       EventTypes.EVENT_VPN_USER_REMOVE,
       user.getAccountId(),
       0,
       user.getId(),
       user.getUsername(),
       user.getClass().getName(),
       user.getUuid());
   txn.commit();
   return true;
 }
Пример #5
0
  @Test
  public void test() throws Exception {
    XmlLoader.load(new FileInputStream("test/test.xml"));

    for (int i = 0; i < Rekord.getTableCount(); i++) {
      System.out.println(Rekord.getTable(i));
    }

    Transaction trans = Rekord.getTransaction();
    trans.start();

    /* INHERITANCE 1 LEVEL * /
    		Group g = new Group();
    		g.setName( "name#1" );
    		g.setPassword( "password#1" );
    		g.save();

    		g.setPassword( "passsword#2" );
    		g.save();

    		g.setName( "name#2" );
    		g.save();

    		g.delete();
    /**/

    /* INHERITANCE 2 LEVEL */
    CommentableGroup cg = new CommentableGroup();
    cg.setName("name#3");
    cg.setPassword("password#3");
    cg.save();

    cg.getCommentable().setCount(4);
    cg.setPassword("password#4");
    cg.save();
    /**/

    /* JOINING */

    SelectQuery<CommentableGroup> q =
        Select.build(CommentableGroup.TABLE, CommentableGroup.TABLE.getLoadProfileAll());

    //		SelectQuery<CommentableGroup> q = Select.from( CommentableGroup.TABLE );
    //
    //		TableAlias commentableGroup = q.getTableAlias();
    //		TableAlias group = q.alias( Group.TABLE );
    //		TableAlias rolePlayer = q.alias( RolePlayer.TABLE );
    //
    //		Join groupJoin = q.join( Join.INNER, group );
    //		groupJoin.where( Group.ROLE_PLAYER_ID ).eq( commentableGroup.alias(
    // CommentableGroup.GROUP_ID ) );
    //
    //		Join rolePlayerJoin = q.join( Join.INNER, rolePlayer );
    //		rolePlayerJoin.where( RolePlayer.ID ).eq( group.alias( Group.ROLE_PLAYER_ID ) );
    //
    //		q.select( commentableGroup.alias( CommentableGroup.COMMENTABLE_ID ) );
    //		q.select( group.alias( Group.PASSWORD ) );
    //		q.select( rolePlayer.alias( RolePlayer.NAME ) );

    System.out.println(q.create().list());
    /**/

    //		long uid0 = new SelectQuery<Model>( User.TABLE ).create().withOffset( 0 ).first( User.ID );
    //		long uid1 = new SelectQuery<Model>( User.TABLE ).create().withOffset( 1 ).first( User.ID );

    /* CRAZY (return-on-save, always-update, out, last-modified-columns) * /
    		Crazy c = new Crazy();
    		c.setDiameter( 4.5f );
    		c.save();
    		System.out.println( c );

    		Thread.sleep( 1000 );

    		c.setDiameter( 3.5f );
    		c.save();
    		System.out.println( c );

    		/* throws a ConcurrentModificationException * /
    		c.setLastModifiedTimestamp( new Timestamp( System.currentTimeMillis() - 10000 ) );
    		c.setDiameter( 2.5f );
    		c.save();

    /**/

    /* UPDATING (history table) * /
    		User u = User.byId( User.Load.ALL, uid0 );
    		u.setName( "New Name!" );
    		u.save();
    /**/

    /* DELETING * /
    		User u = User.byId( User.Load.SHORT_NAME, uid0 );
    		System.out.println( u.getName() );
    		System.out.println( u.exists() );
    		u.delete();
    		System.out.println( u.exists() );

    		User u1 = User.byId( User.Load.ALL, uid1 );
    		System.out.println( u1.getState() );
    		u1.getCommentsBy().clear();
    		u1.save();
    /**/

    //		User u1 = User.byId( User.Load.ALL, uid0 );
    //		System.out.println( u1 );

    //		User u = new User();
    //		u.setName( "lowercase" );
    //		u.save();

    //		User u = User.byId( User.Load.ID, uid1 );
    //		System.out.println( u );
    //		System.out.println( u.getCommentsBy() );
    //		System.out.println( u );

    /* NativeQuery * /
    		Query<User> nq = User.Queries.CREATED_BEFORE.create();
    		nq.bind( "date", User.CREATED_TIMESTAMP, new Timestamp( System.currentTimeMillis() ) );

    		System.out.println( nq.getReadableQuery() );

    		String name = nq.first( User.NAME );
            System.out.println( name );

            List<User> users = nq.list();

            System.out.println( users );

            User u = users.get( 0 );

            trans.start();

            Query<User> us = User.Queries.UPDATE_STATE.create();
            us.bind( u );
            us.bind( "new_state", User.STATE, UserState.REGISTERED );
            us.executeUpdate();
    /**/

    /*SelectQuery #1 * /
    		SelectQuery<Comment> numberOfComments = new SelectQuery<Comment>( Comment.TABLE );
    		numberOfComments.count().where( Comment.USER_ID ).eq( User.ID );

    		SelectQuery<User> query = new SelectQuery<User>( User.TABLE );
    		query.select( User.Load.ALL );
    		query.where( User.COMMENTABLE ).eqExp( "?cid" )
    			  .and( User.NAME ).eq( "LOWERCASE" )
    			  .and( User.CREATED_TIMESTAMP ).between( new Timestamp( System.currentTimeMillis() - 10000000000L ), new Timestamp( System.currentTimeMillis() ) )
    		      .and( numberOfComments ).gt( 0 );

    		System.out.println( query.create().bind( "cid", 5L ).list() );
    /**/

    /*SelectQuery #2* /
    		Condition c_user = is( Comment.USER_ID ).eq( User.ID );

            SelectQuery<Comment> numberOfComments = new SelectQuery<Comment>( Comment.TABLE ).count().where( c_user );

    		Timestamp t0 = new Timestamp( System.currentTimeMillis() - 10000000000L );
    		Timestamp t1 = new Timestamp( System.currentTimeMillis() );

            SelectQuery<User> query = new SelectQuery<User>( User.TABLE );
            query.select( User.Load.ALL );
            query.where(
                is( User.COMMENTABLE ).eqExp( "?cid" ),
                isString( User.NAME ).ieq( "clickerMONKEY" ),
                is( User.CREATED_TIMESTAMP ).between( t0, t1 ),
                is( numberOfComments ).gt( 0 ),
                or(
                    is( User.ID ).gt( 0L ),
                    is( User.ID ).lt( 0L )
                )
            );

            System.out.println( query.create().bind( "cid", 3L ).list() );
    /**/

    //        System.out.println( Select.all( Commentable.TABLE, Commentable.ID ) );

    //        System.out.println( Select.byUnique( User.TABLE, User.ID, 4L ) );

    trans.end(false);
    trans.close();
  }
  @DB
  @Override
  public boolean applyVpnUsers(long vpnOwnerId, String userName) {
    Account caller = UserContext.current().getCaller();
    Account owner = _accountDao.findById(vpnOwnerId);
    _accountMgr.checkAccess(caller, null, true, owner);

    s_logger.debug("Applying vpn users for " + owner);
    List<RemoteAccessVpnVO> vpns = _remoteAccessVpnDao.findByAccount(vpnOwnerId);

    List<VpnUserVO> users = _vpnUsersDao.listByAccount(vpnOwnerId);

    // If user is in Active state, we still have to resend them therefore their status has to be Add
    for (VpnUserVO user : users) {
      if (user.getState() == State.Active) {
        user.setState(State.Add);
        _vpnUsersDao.update(user.getId(), user);
      }
    }

    boolean success = true;

    boolean[] finals = new boolean[users.size()];
    for (RemoteAccessVPNServiceProvider element : _vpnServiceProviders) {
      s_logger.debug("Applying vpn access to " + element.getName());
      for (RemoteAccessVpnVO vpn : vpns) {
        try {
          String[] results = element.applyVpnUsers(vpn, users);
          if (results != null) {
            for (int i = 0; i < results.length; i++) {
              s_logger.debug(
                  "VPN User "
                      + users.get(i)
                      + (results[i] == null
                          ? " is set on "
                          : (" couldn't be set due to " + results[i]) + " on ")
                      + vpn);
              if (results[i] == null) {
                if (!finals[i]) {
                  finals[i] = true;
                }
              } else {
                finals[i] = false;
                success = false;
              }
            }
          }
        } catch (ResourceUnavailableException e) {
          s_logger.warn("Unable to apply vpn users ", e);
          success = false;

          for (int i = 0; i < finals.length; i++) {
            finals[i] = false;
          }
        }
      }
    }

    for (int i = 0; i < finals.length; i++) {
      VpnUserVO user = users.get(i);
      if (finals[i]) {
        if (user.getState() == State.Add) {
          user.setState(State.Active);
          _vpnUsersDao.update(user.getId(), user);
        } else if (user.getState() == State.Revoke) {
          _vpnUsersDao.remove(user.getId());
        }
      } else {
        if (user.getState() == State.Add && (user.getUsername()).equals(userName)) {
          Transaction txn = Transaction.currentTxn();
          txn.start();
          _vpnUsersDao.remove(user.getId());
          UsageEventUtils.publishUsageEvent(
              EventTypes.EVENT_VPN_USER_REMOVE,
              user.getAccountId(),
              0,
              user.getId(),
              user.getUsername(),
              user.getClass().getName(),
              user.getUuid());
          txn.commit();
        }
        s_logger.warn(
            "Failed to apply vpn for user "
                + user.getUsername()
                + ", accountId="
                + user.getAccountId());
      }
    }

    return success;
  }
  @Override
  @DB
  public void destroyRemoteAccessVpn(long ipId, Account caller)
      throws ResourceUnavailableException {
    RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findById(ipId);
    if (vpn == null) {
      s_logger.debug("vpn id=" + ipId + " does not exists ");
      return;
    }

    _accountMgr.checkAccess(caller, null, true, vpn);

    Network network = _networkMgr.getNetwork(vpn.getNetworkId());

    vpn.setState(RemoteAccessVpn.State.Removed);
    _remoteAccessVpnDao.update(vpn.getServerAddressId(), vpn);

    boolean success = false;
    try {
      for (RemoteAccessVPNServiceProvider element : _vpnServiceProviders) {
        if (element.stopVpn(network, vpn)) {
          success = true;
          break;
        }
      }
    } finally {
      if (success) {
        // Cleanup corresponding ports
        List<? extends FirewallRule> vpnFwRules = _rulesDao.listByIpAndPurpose(ipId, Purpose.Vpn);
        Transaction txn = Transaction.currentTxn();

        boolean applyFirewall = false;
        List<FirewallRuleVO> fwRules = new ArrayList<FirewallRuleVO>();
        // if related firewall rule is created for the first vpn port, it would be created for the 2
        // other ports as well, so need to cleanup the backend
        if (_rulesDao.findByRelatedId(vpnFwRules.get(0).getId()) != null) {
          applyFirewall = true;
        }

        if (applyFirewall) {
          txn.start();

          for (FirewallRule vpnFwRule : vpnFwRules) {
            // don't apply on the backend yet; send all 3 rules in a banch
            _firewallMgr.revokeRelatedFirewallRule(vpnFwRule.getId(), false);
            fwRules.add(_rulesDao.findByRelatedId(vpnFwRule.getId()));
          }

          s_logger.debug(
              "Marked "
                  + fwRules.size()
                  + " firewall rules as Revoked as a part of disable remote access vpn");

          txn.commit();

          // now apply vpn rules on the backend
          s_logger.debug(
              "Reapplying firewall rules for ip id="
                  + ipId
                  + " as a part of disable remote access vpn");
          success = _firewallMgr.applyIngressFirewallRules(ipId, caller);
        }

        if (success) {
          try {
            txn.start();
            _remoteAccessVpnDao.remove(ipId);
            // Stop billing of VPN users when VPN is removed. VPN_User_ADD events will be generated
            // when VPN is created again
            List<VpnUserVO> vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId());
            for (VpnUserVO user : vpnUsers) {
              // VPN_USER_REMOVE event is already generated for users in Revoke state
              if (user.getState() != VpnUser.State.Revoke) {
                UsageEventUtils.publishUsageEvent(
                    EventTypes.EVENT_VPN_USER_REMOVE,
                    user.getAccountId(),
                    0,
                    user.getId(),
                    user.getUsername(),
                    user.getClass().getName(),
                    user.getUuid());
              }
            }
            if (vpnFwRules != null) {
              for (FirewallRule vpnFwRule : vpnFwRules) {
                _rulesDao.remove(vpnFwRule.getId());
                s_logger.debug(
                    "Successfully removed firewall rule with ip id="
                        + vpnFwRule.getSourceIpAddressId()
                        + " and port "
                        + vpnFwRule.getSourcePortStart()
                        + " as a part of vpn cleanup");
              }
            }
            txn.commit();
          } catch (Exception ex) {
            txn.rollback();
            s_logger.warn("Unable to release the three vpn ports from the firewall rules", ex);
          }
        }
      }
    }
  }
  /**
   * Try to process a single transaction. Up to {@code MAX_ACCEPTABLE_FAIL_COUNT} attempts will be
   * made to process the transaction in cases where I/O errors or non-protocol server errors occur
   * during processing. Use of the underlying session is protected against concurrent use by other
   * threads by using the getSession/releaseSession features of this SessionManager's {@link
   * com.ausregistry.jtoolkit2.session.SessionPool}. This method guarantees that the session used
   * will be returned to the pool before the method returns.
   *
   * @throws FatalSessionException No session could be acquired to process the transaction. Check
   *     the exception message and log records for details.
   * @throws IOException Every attempt to execute the transaction command failed due to an
   *     IOException. This is the last such IOException.
   * @throws ParsingException Parsing of the response failed. Check the exception message for the
   *     cause.
   * @throws CommandFailedException The acceptable limit on the number of failed commands due to
   *     server error was exceeded in trying to process the command. This probably indicates a
   *     server limitation related to the command being processed.
   * @throws IllegalStateException The SessionManager had been shutdown or not started up prior to
   *     invoking this method.
   */
  @Override
  public void execute(Transaction tx)
      throws FatalSessionException, IOException, ParsingException, CommandFailedException,
          IllegalStateException {

    debugLogger.finest("enter");

    if (state == SMState.STOPPED) {
      throw new IllegalStateException();
    }

    Command cmd = tx.getCommand();
    Response response = tx.getResponse();

    int failCount = 0;
    boolean isExecuted = false;
    Session session = null;

    // if only processing one transaction, get a new session for each
    // attempt in case the session fails mid-transaction.
    while (!isExecuted && state != SMState.STOPPED) {
      try {
        session = sessionPool.getSession(cmd.getCommandType());
        StatsManager statsManager = session.getStatsManager();
        statsManager.incCommandCounter(cmd.getCommandType());

        tx.start();
        session.write(cmd);
        isExecuted = true;
        session.read(response);
        tx.setState(TransactionState.PROCESSED);
        statsManager.recordResponseTime(cmd.getCommandType(), tx.getResponseTime());

        Result[] results = response.getResults();
        assert results != null;
        if (results != null) {
          for (Result result : results) {
            assert result != null;
            statsManager.incResultCounter(result.getResultCode());
            int code = result.getResultCode();

            switch (code) {
              case ResultCode.CMD_FAILED:
                throw new CommandFailedException();
              case ResultCode.CMD_FAILED_CLOSING:
              default:
                throw new CommandFailedException();
            }
          }
        }
      } catch (CommandFailedException cfe) {
        userLogger.warning(cfe.getMessage());

        if (state != SMState.STOPPED && failCount < MAX_ACCEPTABLE_FAIL_COUNT) {

          failCount++;
        } else {
          throw cfe;
        }
      } catch (IOException ioe) {
        userLogger.warning(ioe.getMessage());
        userLogger.warning("net.socket.closed");
        session.close();
        if (state != SMState.STOPPED && failCount < MAX_ACCEPTABLE_FAIL_COUNT) {
          failCount++;
        } else {
          throw ioe;
        }
      } catch (InterruptedException ie) {
        // if interrupted by shutdown, then started will be false
        // Note: this still enters the finally block
        continue;
      } catch (SessionConfigurationException sce) {
        throw new FatalSessionException(sce);
      } catch (SessionOpenException soe) {
        throw new FatalSessionException(soe);
      } finally {
        sessionPool.releaseSession(session);
      }
    }

    if (!isExecuted && state == SMState.STOPPED) {
      throw new IllegalStateException();
    }

    debugLogger.finest("exit");
  }