@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; }
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; }
@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"); }