public static Collection<Properties> getConnectionProperties(URI uri) { ServerDescriptor serverDescriptor = SERVERS.get(createKey(uri)); if (serverDescriptor != null) { return serverDescriptor.getConnections().values(); } else { return Collections.emptyList(); } }
@Override public Connection connect(URI uri, Properties properties) throws ConnectionException { if (PASSTHROUGH.equals(uri.getScheme())) { if (STRIPES.containsKey(uri.getAuthority())) { String serverName = uri.getHost(); PassthroughServer server = PassthroughServerRegistry.getSharedInstance().getServerForName(serverName); if (null != server) { String connectionName = properties.getProperty("connection.name"); if (null == connectionName) { connectionName = "Ehcache:ACTIVE-PASSIVE"; } Connection connection = server.connectNewClient(connectionName); STRIPES.get(uri.getAuthority()).add(connection); return connection; } } else { throw new IllegalArgumentException( "UnitTestConnectionService failed to find stripe" + uri.getAuthority()); } } checkURI(uri); ServerDescriptor serverDescriptor = SERVERS.get(uri); if (serverDescriptor == null) { throw new IllegalArgumentException("No server available for " + uri); } String name = properties.getProperty(ConnectionPropertyNames.CONNECTION_NAME); if (name == null) { name = "Ehcache:UNKNOWN"; } Connection connection = serverDescriptor.server.connectNewClient(name); serverDescriptor.add(connection, properties); LOGGER.info("Client opened {} to PassthroughServer at {}", formatConnectionId(connection), uri); /* * Uses a Proxy around Connection so closed connections can be removed from the ServerDescriptor. */ return (Connection) Proxy.newProxyInstance( Connection.class.getClassLoader(), new Class[] {Connection.class}, new ConnectionInvocationHandler(serverDescriptor, connection)); }
@Override @SuppressWarnings("unchecked") public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("close")) { serverDescriptor.remove(connection); LOGGER.info("Client closed {}", formatConnectionId(connection)); } if (method.getName().equals("getEntityRef")) { serverDescriptor.addKnownEntity((Class<? extends Entity>) args[0], args[1], args[2]); } try { return method.invoke(connection, args); } catch (InvocationTargetException e) { throw e.getCause(); } }
/** * Removes the {@link PassthroughServer} previously associated with the {@code URI} provided. The * server is stopped as it is removed. In addition to stopping the server, all open {@link * Connection} instances created through the {@link #connect(URI, Properties)} method are closed; * this is done to clean up the threads started in support of each open connection. * * @param uri the {@code URI} for which the server is removed * @return the removed {@code PassthroughServer} */ public static PassthroughServer remove(URI uri) { URI keyURI = createKey(uri); ServerDescriptor serverDescriptor = SERVERS.remove(keyURI); if (serverDescriptor != null) { for (Connection connection : serverDescriptor.getConnections().keySet()) { try { LOGGER.warn("Force close {}", formatConnectionId(connection)); connection.close(); } catch (AssertionError e) { // Ignored -- https://github.com/Terracotta-OSS/terracotta-apis/issues/102 } catch (IOException e) { // Ignored } } // open destroy connection. You need to make sure connection doesn't have any entities // associated with it. PassthroughConnection connection = serverDescriptor.server.connectNewClient("destroy-connection"); for (Entry entry : serverDescriptor.knownEntities.entrySet()) { @SuppressWarnings("unchecked") Class<? extends Entity> type = (Class) entry.getKey(); List args = (List) entry.getValue(); Long version = (Long) args.get(0); String stringArg = (String) args.get(1); try { EntityRef entityRef = connection.getEntityRef(type, version, stringArg); entityRef.destroy(); } catch (EntityNotProvidedException ex) { LOGGER.error("Entity destroy failed: ", ex); } catch (EntityNotFoundException ex) { LOGGER.error("Entity destroy failed: ", ex); } catch (PermanentEntityException ex) { LOGGER.error("Entity destroy failed (permanent???): ", ex); } } serverDescriptor.server.stop(); LOGGER.info("Stopped PassthroughServer at {}", keyURI); return serverDescriptor.server; } else { return null; } }