Author: bdekruijff at gmail.com Date: Mon Nov 29 12:21:21 2010 New Revision: 452
Log: AMDATU-190 Dropped initial sandbox code Added: trunk/amdatu-httpproxy/ (props changed) trunk/amdatu-httpproxy/README.txt trunk/amdatu-httpproxy/clientservice/ (props changed) trunk/amdatu-httpproxy/clientservice/pom.xml trunk/amdatu-httpproxy/clientservice/src/ trunk/amdatu-httpproxy/clientservice/src/main/ trunk/amdatu-httpproxy/clientservice/src/main/java/ trunk/amdatu-httpproxy/clientservice/src/main/java/org/ trunk/amdatu-httpproxy/clientservice/src/main/java/org/amdatu/ trunk/amdatu-httpproxy/clientservice/src/main/java/org/amdatu/httpproxy/ trunk/amdatu-httpproxy/clientservice/src/main/java/org/amdatu/httpproxy/clientservice/ trunk/amdatu-httpproxy/clientservice/src/main/java/org/amdatu/httpproxy/clientservice/osgi/ trunk/amdatu-httpproxy/clientservice/src/main/java/org/amdatu/httpproxy/clientservice/osgi/Activator.java trunk/amdatu-httpproxy/clientservice/src/main/java/org/amdatu/httpproxy/clientservice/service/ trunk/amdatu-httpproxy/clientservice/src/main/java/org/amdatu/httpproxy/clientservice/service/HttpClientService.java trunk/amdatu-httpproxy/clientservice/src/test/ trunk/amdatu-httpproxy/clientservice/src/test/java/ trunk/amdatu-httpproxy/pom.xml trunk/amdatu-httpproxy/proxyservice/ (props changed) trunk/amdatu-httpproxy/proxyservice/pom.xml trunk/amdatu-httpproxy/proxyservice/src/ trunk/amdatu-httpproxy/proxyservice/src/main/ trunk/amdatu-httpproxy/proxyservice/src/main/java/ trunk/amdatu-httpproxy/proxyservice/src/main/java/org/ trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/ trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/ trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/ trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/cache/ trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/cache/CachingHttpClientfactory.java trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/cache/FSHttpCacheStorage.java trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/osgi/ trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/osgi/Activator.java trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/service/ trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/service/HttpProxyService.java trunk/amdatu-httpproxy/proxyservice/src/test/ trunk/amdatu-httpproxy/proxyservice/src/test/java/ trunk/amdatu-httpproxy/proxyservice/src/test/java/org/ trunk/amdatu-httpproxy/proxyservice/src/test/java/org/amdatu/ trunk/amdatu-httpproxy/proxyservice/src/test/java/org/amdatu/httpproxy/ trunk/amdatu-httpproxy/proxyservice/src/test/java/org/amdatu/httpproxy/proxyservice/ trunk/amdatu-httpproxy/proxyservice/src/test/java/org/amdatu/httpproxy/proxyservice/CacheTesting.java Added: trunk/amdatu-httpproxy/README.txt ============================================================================== --- (empty file) +++ trunk/amdatu-httpproxy/README.txt Mon Nov 29 12:21:21 2010 @@ -0,0 +1,3 @@ +Subproject: Amdatu HttpProxy +Status : Sandbox / PoC +Info : http://jira.amdatu.org/jira/browse/AMDATU-190 Added: trunk/amdatu-httpproxy/clientservice/pom.xml ============================================================================== --- (empty file) +++ trunk/amdatu-httpproxy/clientservice/pom.xml Mon Nov 29 12:21:21 2010 @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.amdatu.httpproxy</groupId> + <artifactId>httpproxy</artifactId> + <version>0.0.6-SNAPSHOT</version> + </parent> + <artifactId>clientservice</artifactId> + <packaging>bundle</packaging> + <name>Amdatu HttpProxy test client service</name> + <description>Just for testing</description> + + <dependencies> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-Activator>org.amdatu.httpproxy.clientservice.osgi.Activator</Bundle-Activator> + <Bundle-SymbolicName>org.amdatu.httpproxy.clientservice</Bundle-SymbolicName> + <Embed-Dependency>*;scope=compile</Embed-Dependency> + <Embed-Transitive>false</Embed-Transitive> + <Bundle-ClassPath>.</Bundle-ClassPath> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> Added: trunk/amdatu-httpproxy/clientservice/src/main/java/org/amdatu/httpproxy/clientservice/osgi/Activator.java ============================================================================== --- (empty file) +++ trunk/amdatu-httpproxy/clientservice/src/main/java/org/amdatu/httpproxy/clientservice/osgi/Activator.java Mon Nov 29 12:21:21 2010 @@ -0,0 +1,44 @@ +/* +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.httpproxy.clientservice.osgi; + +import org.amdatu.httpproxy.clientservice.service.HttpClientService; +import org.apache.felix.dm.DependencyActivatorBase; +import org.apache.felix.dm.DependencyManager; +import org.apache.http.client.HttpClient; +import org.osgi.framework.BundleContext; +import org.osgi.service.log.LogService; + +/** + */ +public final class Activator extends DependencyActivatorBase { + + @Override + public void init(BundleContext context, DependencyManager manager) throws Exception { + + manager.add( + createComponent() + .setImplementation(HttpClientService.class) + .add(createServiceDependency().setService(HttpClient.class).setRequired(true)) + .add(createServiceDependency().setService(LogService.class).setRequired(false))); + } + + @Override + public void destroy(BundleContext context, DependencyManager manager) throws Exception { + } +} Added: trunk/amdatu-httpproxy/clientservice/src/main/java/org/amdatu/httpproxy/clientservice/service/HttpClientService.java ============================================================================== --- (empty file) +++ trunk/amdatu-httpproxy/clientservice/src/main/java/org/amdatu/httpproxy/clientservice/service/HttpClientService.java Mon Nov 29 12:21:21 2010 @@ -0,0 +1,112 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.httpproxy.clientservice.service; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.osgi.service.log.LogService; + +public class HttpClientService { + + // injected + private volatile HttpClient m_httpClient; + private volatile LogService m_logService; + + public HttpClientService() { + + } + + public void init() { + + if (m_logService != null) + m_logService.log(LogService.LOG_WARNING, "Service init"); + } + + public void destroy() { + + if (m_logService != null) + m_logService.log(LogService.LOG_WARNING, "Service destroy"); + } + + public void start() throws ClientProtocolException, IOException { + + long start = System.currentTimeMillis(); + doTheGet(); + System.err.println("Request 1: " + (System.currentTimeMillis() - start)); + + start = System.currentTimeMillis(); + doTheGet(); + System.err.println("Request 2: " + (System.currentTimeMillis() - start)); + + if (m_logService != null) + m_logService.log(LogService.LOG_WARNING, "Service start"); + } + + public void stop() { + if (m_logService != null) + m_logService.log(LogService.LOG_WARNING, "Service stop"); + } + + public void doTheGet() { + HttpGet get = new HttpGet("http://www.vi.nl/wm/f/lib.js"); + long start = System.currentTimeMillis(); + + HttpResponse res; + InputStream is = null; + BufferedInputStream bis = null; + try { + res = m_httpClient.execute(get); + is = res.getEntity().getContent(); + bis = new BufferedInputStream(is); + byte[] bytes = new byte[1024]; + byte[] all = new byte[0]; + int i = bis.read(bytes); + while (i > 0) { + byte[] newbytes = new byte[all.length + i]; + for (int j = 0; j < all.length; j++) + newbytes[j] = all[j]; + for (int k = 0; k < i; k++) + newbytes[all.length + k] = bytes[k]; + all = newbytes; + i = bis.read(bytes); + } + bis.close(); + } + catch (ClientProtocolException e) {} + catch (IOException e) {} + finally { + if (bis != null) + try { + bis.close(); + } + catch (IOException e1) {} + finally { + if (is != null) + try { + bis.close(); + } + catch (IOException e1) {} + } + } + } +} Added: trunk/amdatu-httpproxy/pom.xml ============================================================================== --- (empty file) +++ trunk/amdatu-httpproxy/pom.xml Mon Nov 29 12:21:21 2010 @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.amdatu</groupId> + <artifactId>amdatu</artifactId> + <version>0.0.6-SNAPSHOT</version> + </parent> + <groupId>org.amdatu.httpproxy</groupId> + <artifactId>httpproxy</artifactId> + <packaging>pom</packaging> + <name>Amdatu HTTPProxy Project</name> + <description>This project provides a HTTP proxy</description> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + <version>4.1</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.1-beta1</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient-cache</artifactId> + <version>4.1-beta1</version> + <scope>provided</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <modules> + <module>proxyservice</module> + <module>clientservice</module> + </modules> +</project> Added: trunk/amdatu-httpproxy/proxyservice/pom.xml ============================================================================== --- (empty file) +++ trunk/amdatu-httpproxy/proxyservice/pom.xml Mon Nov 29 12:21:21 2010 @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.amdatu.httpproxy</groupId> + <artifactId>httpproxy</artifactId> + <version>0.0.6-SNAPSHOT</version> + </parent> + <artifactId>proxyservice</artifactId> + <packaging>bundle</packaging> + <name>Amdatu HttpProxy service</name> + <description>This bundle provides a HTTP proxy service</description> + + <dependencies> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient-cache</artifactId> + <scope>compile</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-Activator>org.amdatu.httpproxy.proxyservice.osgi.Activator</Bundle-Activator> + <Bundle-SymbolicName>org.amdatu.httpproxy.proxyservice</Bundle-SymbolicName> + <Embed-Dependency>*;scope=compile</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Bundle-ClassPath>.</Bundle-ClassPath> + <Import-Package> + *;resolution:=optional + </Import-Package> + <Export-Package> + org.apache.http;version=4.1, + org.apache.http.client;version=4.1, + org.apache.http.client.methods;version=4.1, + org.apache.http.conn;version=4.1, + org.apache.http.conn.scheme;version=4.1, + org.apache.http.params;version=4.1, + org.apache.http.protocol;version=4.1 + </Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> Added: trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/cache/CachingHttpClientfactory.java ============================================================================== --- (empty file) +++ trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/cache/CachingHttpClientfactory.java Mon Nov 29 12:21:21 2010 @@ -0,0 +1,115 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.httpproxy.proxyservice.cache; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; +import java.util.zip.GZIPInputStream; + +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.HttpEntity; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.client.cache.HttpCacheStorage; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.entity.HttpEntityWrapper; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.client.cache.CacheConfig; +import org.apache.http.impl.client.cache.CachingHttpClient; +import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; +import org.apache.http.protocol.HttpContext; + +public final class CachingHttpClientfactory { + + public static CachingHttpClient getCachingHttpClient(final File cacheDirectory) { + + // Creating a backend client with multithreaded capabilities and gzip support + SchemeRegistry registry = new SchemeRegistry(); + registry.register( + new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); + registry.register( + new Scheme("https", 443, SSLSocketFactory.getSocketFactory())); + ClientConnectionManager manager = new ThreadSafeClientConnManager(registry, 1000, TimeUnit.MILLISECONDS); + DefaultHttpClient hc = new DefaultHttpClient(manager); + hc.addRequestInterceptor(new GzipHttpRequestInterceptor()); + hc.addResponseInterceptor(new GzipHttpResponseInterceptor()); + + // Configure with a simple filebased FS storage and a max object size. + CacheConfig cc = new CacheConfig(); + cc.setMaxObjectSizeBytes(1024 * 1000); + HttpCacheStorage hcs = new FSHttpCacheStorage(cacheDirectory); + return new CachingHttpClient(hc, hcs, cc); + + } + + static class GzipHttpRequestInterceptor implements HttpRequestInterceptor { + public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { + if (!request.containsHeader("Accept-Encoding")) { + request.addHeader("Accept-Encoding", "gzip"); + } + } + } + + static class GzipHttpResponseInterceptor implements HttpResponseInterceptor { + public void process(final HttpResponse response, final HttpContext context) throws HttpException, + IOException { + HttpEntity entity = response.getEntity(); + if (entity != null) { + Header ceheader = entity.getContentEncoding(); + if (ceheader != null) { + HeaderElement[] codecs = ceheader.getElements(); + for (int i = 0; i < codecs.length; i++) { + if (codecs[i].getName().equalsIgnoreCase("gzip")) { + response.setEntity(new GzipDecompressingEntity(response.getEntity())); + return; + } + } + } + } + } + } + + static class GzipDecompressingEntity extends HttpEntityWrapper { + + public GzipDecompressingEntity(final HttpEntity entity) { + super(entity); + } + + @Override + public InputStream getContent() throws IOException, IllegalStateException { + // the wrapped entity's getContent() decides about repeatability + InputStream wrappedin = wrappedEntity.getContent(); + return new GZIPInputStream(wrappedin); + } + + @Override + public long getContentLength() { + // length of ungzipped content is not known + return -1; + } + } +} Added: trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/cache/FSHttpCacheStorage.java ============================================================================== --- (empty file) +++ trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/cache/FSHttpCacheStorage.java Mon Nov 29 12:21:21 2010 @@ -0,0 +1,127 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.httpproxy.proxyservice.cache; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URI; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.http.client.cache.HttpCacheEntry; +import org.apache.http.client.cache.HttpCacheEntrySerializer; +import org.apache.http.client.cache.HttpCacheStorage; +import org.apache.http.client.cache.HttpCacheUpdateCallback; +import org.apache.http.client.cache.HttpCacheUpdateException; +import org.apache.http.impl.client.cache.DefaultHttpCacheEntrySerializer; + +// TODO writing could be async +public class FSHttpCacheStorage implements HttpCacheStorage { + + private final HttpCacheEntrySerializer m_cacheEntrySerializer; + private final File m_dataDirectory; + + public FSHttpCacheStorage(final File dataDirectory) { + m_dataDirectory = dataDirectory; + m_cacheEntrySerializer = new DefaultHttpCacheEntrySerializer() { + + }; + } + + public HttpCacheEntry getEntry(final String uri) throws IOException { + File storageFile = getStorageFile(uri); + if (!storageFile.exists()) { + return null; + } + + InputStream is = null; + try { + is = new BufferedInputStream(new FileInputStream(storageFile)); + HttpCacheEntry ce = m_cacheEntrySerializer.readFrom(is); + return ce; + } + finally { + if (is != null) + is.close(); + } + } + + public void putEntry(String uri, HttpCacheEntry entry) throws IOException { + File storageFile = getStorageFile(uri); + if (!storageFile.exists()) { + if (!storageFile.getParentFile().exists()) { + storageFile.getParentFile().mkdirs(); + } + } + + OutputStream os = null; + try { + os = new BufferedOutputStream(new FileOutputStream(storageFile)); + m_cacheEntrySerializer.writeTo(entry, os); + } + finally { + if (os != null) + os.close(); + } + } + + public void removeEntry(String uri) throws IOException { + File storageFile = getStorageFile(uri); + if (storageFile.exists()) { + storageFile.delete(); + } + } + + public void updateEntry(String uri, HttpCacheUpdateCallback callback) throws IOException, HttpCacheUpdateException { + // not sure what to do here + HttpCacheEntry existing = getEntry(uri); + HttpCacheEntry updated = null; + if (existing != null) + updated = callback.update(existing); + if (updated != null) + putEntry(uri, updated); + } + + private File getStorageFile(final String uriString) throws IOException { + + // FIXME ignoring {} variants + String nonVariantUri = uriString; + if (uriString.startsWith("{")) { + nonVariantUri = uriString.substring(uriString.indexOf("}") + 1); + } + + URI uri = URI.create(nonVariantUri); + File hostDirectory = new File(m_dataDirectory, uri.getHost()); + + String path = uri.getPath(); + String[] pathParts = path.split("/"); + File pathDirectory = hostDirectory; + for (int i = 0; i < (pathParts.length - 1); i++) { + String pathPart = pathParts[i]; + pathDirectory = new File(pathDirectory, pathPart); + } + File dataFile = new File(pathDirectory, "" + pathParts[pathParts.length - 1] + ".ser"); + return dataFile; + } +} Added: trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/osgi/Activator.java ============================================================================== --- (empty file) +++ trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/osgi/Activator.java Mon Nov 29 12:21:21 2010 @@ -0,0 +1,49 @@ +/* +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.httpproxy.proxyservice.osgi; + +import org.amdatu.httpproxy.proxyservice.service.HttpProxyService; +import org.apache.felix.dm.DependencyActivatorBase; +import org.apache.felix.dm.DependencyManager; +import org.apache.http.client.HttpClient; +import org.osgi.framework.BundleContext; +import org.osgi.service.log.LogService; + +/** + */ +public final class Activator extends DependencyActivatorBase { + + @Override + public void init(BundleContext context, DependencyManager manager) throws Exception { + + // FIXME hardcoded bundle storage + HttpProxyService hps = new HttpProxyService(); + hps.setDataDirectory(context.getDataFile("cache")); + hps.start(); + + manager.add( + createComponent() + .setImplementation(hps) + .setInterface(HttpClient.class.getName(), null) + .add(createServiceDependency().setService(LogService.class).setRequired(false))); + } + + @Override + public void destroy(BundleContext context, DependencyManager manager) throws Exception { + } +} Added: trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/service/HttpProxyService.java ============================================================================== --- (empty file) +++ trunk/amdatu-httpproxy/proxyservice/src/main/java/org/amdatu/httpproxy/proxyservice/service/HttpProxyService.java Mon Nov 29 12:21:21 2010 @@ -0,0 +1,137 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.httpproxy.proxyservice.service; + +import java.io.File; +import java.io.IOException; + +import org.amdatu.httpproxy.proxyservice.cache.CachingHttpClientfactory; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.impl.client.cache.CachingHttpClient; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; +import org.osgi.service.log.LogService; + +public class HttpProxyService implements HttpClient { + + // injected + private volatile LogService m_logService; + + private CachingHttpClient m_cachingHttpClient; + private File m_dataDirectory; + + public HttpProxyService() { + } + + public synchronized File getDataDirectory() { + return m_dataDirectory; + } + + public synchronized void setDataDirectory(File dataDirectory) throws IOException { + if (!dataDirectory.isAbsolute()) { + File userDirectory = new File(System.getProperty("user.dir")); + dataDirectory = new File(userDirectory, dataDirectory.getPath()); + } + if (!((dataDirectory.exists() && dataDirectory.canRead() && dataDirectory.canWrite()) || dataDirectory + .mkdirs())) { + throw new IOException("Unable to access data directory: " + + dataDirectory.getAbsolutePath()); + } + m_dataDirectory = dataDirectory; + } + + public void start() { + m_cachingHttpClient = + CachingHttpClientfactory.getCachingHttpClient(m_dataDirectory); + if (m_logService != null) + m_logService.log(LogService.LOG_INFO, "Service started with datadir: " + m_dataDirectory.getAbsolutePath()); + } + + public void stop() { + m_cachingHttpClient = null; + if (m_logService != null) + m_logService.log(LogService.LOG_INFO, "Service stopped"); + } + + public HttpResponse execute(HttpUriRequest request) throws IOException, ClientProtocolException { + long start = System.currentTimeMillis(); + HttpResponse response = m_cachingHttpClient.execute(request); + if (m_logService != null) + m_logService.log(LogService.LOG_WARNING, "Fetched " + request.getURI().getScheme() + "://" + + request.getURI().getHost() + ":" + request.getURI().getPort() + + request.getURI().getPath() + request.getURI().getQuery() + + " in " + (System.currentTimeMillis() - start) + " ms"); + if (m_logService != null) + m_logService.log(LogService.LOG_WARNING, "Cache stats (h/m/u): " + m_cachingHttpClient.getCacheHits() + "/" + + m_cachingHttpClient.getCacheMisses() + "/" + m_cachingHttpClient.getCacheUpdates()); + return response; + } + + public HttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException, + ClientProtocolException { + return m_cachingHttpClient.execute(request, context); + } + + public HttpResponse execute(HttpHost target, HttpRequest request) throws IOException, ClientProtocolException { + return m_cachingHttpClient.execute(target, request); + } + + public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, + ClientProtocolException { + return m_cachingHttpClient.execute(request, responseHandler); + } + + public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws IOException, + ClientProtocolException { + return m_cachingHttpClient.execute(target, request, context); + } + + public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) + throws IOException, + ClientProtocolException { + return m_cachingHttpClient.execute(request, responseHandler, context); + } + + public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler) + throws IOException, + ClientProtocolException { + return m_cachingHttpClient.execute(target, request, responseHandler); + } + + public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler, + HttpContext context) + throws IOException, ClientProtocolException { + return m_cachingHttpClient.execute(target, request, responseHandler, context); + } + + public ClientConnectionManager getConnectionManager() { + // TODO defend + return m_cachingHttpClient.getConnectionManager(); + } + + public HttpParams getParams() { + // TODO defend + return m_cachingHttpClient.getParams(); + } +} Added: trunk/amdatu-httpproxy/proxyservice/src/test/java/org/amdatu/httpproxy/proxyservice/CacheTesting.java ============================================================================== --- (empty file) +++ trunk/amdatu-httpproxy/proxyservice/src/test/java/org/amdatu/httpproxy/proxyservice/CacheTesting.java Mon Nov 29 12:21:21 2010 @@ -0,0 +1,267 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.httpproxy.proxyservice; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.Logger; + +import org.amdatu.httpproxy.proxyservice.service.HttpProxyService; +import org.apache.commons.logging.LogFactory; +import org.apache.commons.logging.impl.Jdk14Logger; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; + +public class CacheTesting { + + private final static String JAVA_IO_TMPDIR = System.getProperty("java.io.tmpdir"); + + private static File m_absoluteTestRootDirectory; + private static String m_relativeTestRootDirectory; + + @Rule + public TestName m_testName = new TestName(); + + private HttpProxyService m_httpProxyService; + private File m_testDirectory; + + @BeforeClass + public static void setUpOnce() throws IOException { + Random rand = new Random(); + int randomInt = 1 + Math.abs(rand.nextInt()); + m_relativeTestRootDirectory = HttpProxyService.class.getSimpleName() + "_" + randomInt; + m_absoluteTestRootDirectory = + new File(JAVA_IO_TMPDIR + File.separator + m_relativeTestRootDirectory); + m_absoluteTestRootDirectory.mkdirs(); + + LogFactory.getFactory().setAttribute("org.apache.commons.logging.Log", Jdk14Logger.class.getName()); + } + + @Before + public void setUp() throws IOException { + + Enumeration<String> loggerNames = LogManager.getLogManager().getLoggerNames(); + while (loggerNames.hasMoreElements()) { + Logger l = Logger.getLogger(loggerNames.nextElement()); + l.setLevel(Level.ALL); + for (Handler h : l.getHandlers()) { + h.setLevel(Level.ALL); + } + } + + m_testDirectory = new File(m_absoluteTestRootDirectory, m_testName.getMethodName()); + m_testDirectory.mkdir(); + + m_httpProxyService = new HttpProxyService(); + m_httpProxyService.setDataDirectory(m_testDirectory); + m_httpProxyService.start(); + } + + @After + public void tearDown() { +// m_httpProxyService.stop(); + } + + @Test + public void initialTest() { + + if (true) + return; + + HttpProxyService cl = m_httpProxyService; + cl.start(); + + try { + for (int i = 0; i < 10; i++) { + HttpUriRequest hur1 = new HttpGet("http://www.vi.nl/wm/f/lib.js"); + HttpResponse hr1 = cl.execute(hur1); + hr1.getEntity().getContent().close(); + try { + Thread.sleep(10000); + } + catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + finally { + cl.stop(); + } + } + + String[] urls = + new String[] { + "http://www.vi.nl/wm/f/lib.js", + "http://www.vi.nl/wm/f/lib.js" + }; +// new String[] { +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0-javadoc.jar", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0-javadoc.jar.asc", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0-javadoc.jar.asc.md5", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0-javadoc.jar.asc.sha1", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0-javadoc.jar.md5", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0-javadoc.jar.sha1", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0-sources.jar", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0-sources.jar.asc", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0-sources.jar.asc.md5", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0-sources.jar.asc.sha1", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0-sources.jar.md5", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0-sources.jar.sha1", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0.jar", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0.jar.asc", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0.jar.asc.md5", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0.jar.asc.sha1", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0.jar.md5", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0.jar.sha1", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0.pom", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0.pom.asc", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0.pom.asc.md5", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0.pom.asc.sha1", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0.pom.md5", +// "http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-ant-plugin/2.0/maven-ant-plugin-2.0.pom.sha1" +// }; + + CountDownLatch latch = new CountDownLatch(1); + + @Test + public void mavenTest() throws ClientProtocolException, IOException { + + if (true) + return; + + ExecutorService exe = Executors.newFixedThreadPool(10); + + for (int i = 0; i < 1; i++) { + exe.execute(new Runnable() { + public void run() { + + HttpProxyService cl = m_httpProxyService; + + HttpUriRequest hur = null; + for (String url : urls) { + hur = new HttpGet(url); + HttpResponse hr1; + try { +// hr1 = cl.execute(hur); +// hr1.getEntity().getContent().close(); + cl.execute(hur, new ResponseHandler<String>() { + + public String handleResponse(HttpResponse res) throws ClientProtocolException, + IOException { + res.getEntity().getContent().close(); + return null; + } + }); + } + catch (ClientProtocolException e) { + e.printStackTrace(); + } + catch (IOException e) { + e.printStackTrace(); + } + } + try { + Thread.sleep(10); + } + catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + System.out.println("----"); + for (String url : urls) { + hur = new HttpGet(url); + HttpResponse hr1; + try { +// hr1 = cl.execute(hur); +// hr1.getEntity().getContent().close(); + cl.execute(hur, new ResponseHandler<String>() { + + public String handleResponse(HttpResponse res) throws ClientProtocolException, + IOException { + InputStream is = res.getEntity().getContent(); + BufferedInputStream bis = new BufferedInputStream(is); + byte[] bytes = new byte[1024]; + byte[] all = new byte[0]; + + int i = bis.read(bytes); + while (i > 0) { + + byte[] newbytes = new byte[all.length + i]; + for (int j = 0; j < all.length; j++) { + newbytes[j] = all[j]; + } + for (int k = 0; k < i; k++) { + newbytes[all.length + k] = bytes[k]; + } + all = newbytes; + i = bis.read(bytes); + } + bis.close(); + System.err + .println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + + new String(all, "utf-8")); + return null; + } + }); + } + catch (ClientProtocolException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + latch.countDown(); + } + }); + } + try { + latch.await(30, TimeUnit.SECONDS); + } + catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +}
