public void event(Handler handler, Event event) { try { eventQueue.put(Pair.<Handler, Message>of(handler, event)); } catch (InterruptedException e) { throw Util.newError(e, "Exception while executing " + event); } }
public void run() { try { for (; ; ) { final Pair<Handler, Message> entry = eventQueue.take(); final Handler handler = entry.left; final Message message = entry.right; try { // A message is either a command or an event. // A command returns a value that must be read by // the caller. if (message instanceof Command<?>) { Command<?> command = (Command<?>) message; try { Locus.push(command.getLocus()); Object result = command.call(); responseQueue.put(command, Pair.of(result, (Throwable) null)); } catch (PleaseShutdownException e) { responseQueue.put(command, Pair.of(null, (Throwable) null)); return; // exit event loop } catch (Throwable e) { responseQueue.put(command, Pair.of(null, e)); } finally { Locus.pop(command.getLocus()); } } else { Event event = (Event) message; event.acceptWithoutResponse(handler); // Broadcast the event to anyone who is interested. RolapUtil.MONITOR_LOGGER.debug(message); } } catch (Throwable e) { // REVIEW: Somewhere better to send it? e.printStackTrace(); } } } catch (InterruptedException e) { // REVIEW: Somewhere better to send it? e.printStackTrace(); } catch (Throwable e) { e.printStackTrace(); } }
Object execute(Handler handler, Command command) { try { eventQueue.put(Pair.<Handler, Message>of(handler, command)); } catch (InterruptedException e) { throw Util.newError(e, "Interrupted while sending " + command); } try { return responseMap.get(command); } catch (InterruptedException e) { throw Util.newError(e, "Interrupted while awaiting " + command); } }
public void sendEvent(Event event) { // The implementation does not need to take any locks. try { if (Thread.interrupted()) { // Interrupt should not happen. Mondrian uses cancel without // setting interrupt. But if interrupts are happening, it's // best to know now, rather than failing next time we make a // blocking system call. throw new AssertionError(); } ACTOR.eventQueue.put(Pair.<Handler, Message>of(handler, event)); } catch (InterruptedException e) { throw Util.newError(e, "Exception while sending event " + event); } }
<T> T execute(Handler handler, Command<T> command) { try { eventQueue.put(Pair.<Handler, Message>of(handler, command)); } catch (InterruptedException e) { throw Util.newError(e, "Exception while executing " + command); } try { final Pair<Object, Throwable> pair = responseQueue.take(command); if (pair.right != null) { if (pair.right instanceof RuntimeException) { throw (RuntimeException) pair.right; } else if (pair.right instanceof Error) { throw (Error) pair.right; } else { throw new RuntimeException(pair.right); } } else { return (T) pair.left; } } catch (InterruptedException e) { throw Util.newError(e, "Exception while executing " + command); } }
public void testDataSourceOverrideUserPass() throws SQLException, NamingException { // use the datasource property to connect to the database Util.PropertyList properties = TestContext.instance().getConnectionProperties().clone(); final Dialect dialect = TestContext.instance().getDialect(); if (dialect.getDatabaseProduct() == Dialect.DatabaseProduct.ACCESS) { // Access doesn't accept user/password, so this test is pointless. return; } final String jdbcUser = properties.get(RolapConnectionProperties.JdbcUser.name()); final String jdbcPassword = properties.get(RolapConnectionProperties.JdbcPassword.name()); if (jdbcUser == null || jdbcPassword == null) { // Can only run this test if username and password are explicit. return; } // Define a data source with bogus user and password. properties.put(RolapConnectionProperties.JdbcUser.name(), "bogususer"); properties.put(RolapConnectionProperties.JdbcPassword.name(), "boguspassword"); properties.put(RolapConnectionProperties.PoolNeeded.name(), "false"); final StringBuilder buf = new StringBuilder(); final DataSource dataSource = RolapConnection.createDataSource(null, properties, buf); final String desc = buf.toString(); assertTrue(desc, desc.startsWith("Jdbc=")); assertTrue(desc, desc.indexOf("JdbcUser=bogususer; JdbcPassword=boguspassword") >= 0); final String jndiName = "jndiDataSource"; THREAD_INITIAL_CONTEXT.set( new InitialContext() { public Object lookup(String str) { return str.equals(jndiName) ? dataSource : null; } }); // Create a property list that we will use for the actual mondrian // connection. Replace the original JDBC info with the data source we // just created. final Util.PropertyList properties2 = new Util.PropertyList(); for (Pair<String, String> entry : properties) { properties2.put(entry.getKey(), entry.getValue()); } properties2.remove(RolapConnectionProperties.Jdbc.name()); properties2.put(RolapConnectionProperties.DataSource.name(), jndiName); // With JdbcUser and JdbcPassword credentials in the mondrian connect // string, the data source's "user" and "password" properties are // overridden and the connection succeeds. properties2.put(RolapConnectionProperties.JdbcUser.name(), jdbcUser); properties2.put(RolapConnectionProperties.JdbcPassword.name(), jdbcPassword); mondrian.olap.Connection connection = null; try { connection = DriverManager.getConnection(properties2, null); Query query = connection.parseQuery("select from [Sales]"); final Result result = connection.execute(query); assertNotNull(result); } finally { if (connection != null) { connection.close(); connection = null; } } // If we don't specify JdbcUser and JdbcPassword in the mondrian // connection properties, mondrian uses the data source's // bogus credentials, and the connection fails. properties2.remove(RolapConnectionProperties.JdbcUser.name()); properties2.remove(RolapConnectionProperties.JdbcPassword.name()); for (String poolNeeded : Arrays.asList("false", "true")) { // Important to test with & without pooling. Connection pools // typically do not let you change user, so it's important that // mondrian handles these right. properties2.put(RolapConnectionProperties.PoolNeeded.name(), poolNeeded); try { connection = DriverManager.getConnection(properties2, null); fail("Expected exception"); } catch (MondrianException e) { final String s = TestContext.getStackTrace(e); assertTrue( s, s.indexOf("Error while creating SQL connection: " + "DataSource=jndiDataSource") >= 0); switch (dialect.getDatabaseProduct()) { case DERBY: assertTrue( s, s.indexOf( "Caused by: java.sql.SQLException: " + "Schema 'BOGUSUSER' does not exist") >= 0); break; case ORACLE: assertTrue( s, s.indexOf( "Caused by: java.sql.SQLException: ORA-01017: " + "invalid username/password; logon denied") >= 0); break; case MYSQL: assertTrue( s, s.indexOf( "Caused by: java.sql.SQLException: Access denied " + "for user 'bogususer'") >= 0); break; case POSTGRESQL: assertTrue( s, s.indexOf( "Caused by: org.postgresql.util.PSQLException: " + "FATAL: password authentication failed for " + "user \"bogususer\"") >= 0); break; } } finally { if (connection != null) { connection.close(); connection = null; } } } }
/** * Places a (request, response) pair onto the queue. * * @param k Request * @param v Response * @throws InterruptedException if interrupted while waiting */ public void put(K k, V v) throws InterruptedException { queue.put(Pair.of(k, v)); }