You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by ap...@apache.org on 2009/08/01 13:48:21 UTC

svn commit: r799847 - in /mina/sandbox/vysper/trunk/server/core: ./ src/main/java/org/apache/vysper/xmpp/state/presence/ src/main/resources/ src/test/java/org/apache/vysper/xmpp/state/presence/

Author: apaliwal
Date: Sat Aug  1 11:48:21 2009
New Revision: 799847

URL: http://svn.apache.org/viewvc?rev=799847&view=rev
Log:
JIRA Issue: VYSPER-164
Submitted By: apaliwal at apache.org

Description: Added EhCache based Caching implementation and related test class

Added:
    mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/state/presence/AbstractBaseCache.java   (with props)
    mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/state/presence/EhCachePresenceCacheImpl.java   (with props)
    mina/sandbox/vysper/trunk/server/core/src/main/resources/
    mina/sandbox/vysper/trunk/server/core/src/main/resources/ehcache.xml   (with props)
    mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/state/presence/EhCachePresenceCacheImplTest.java   (with props)
Modified:
    mina/sandbox/vysper/trunk/server/core/pom.xml

Modified: mina/sandbox/vysper/trunk/server/core/pom.xml
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/core/pom.xml?rev=799847&r1=799846&r2=799847&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/server/core/pom.xml (original)
+++ mina/sandbox/vysper/trunk/server/core/pom.xml Sat Aug  1 11:48:21 2009
@@ -143,6 +143,14 @@
       <artifactId>log4j</artifactId>
       <scope>test</scope>
     </dependency>
+
+      <dependency>
+        <groupId>net.sf.ehcache</groupId>
+        <artifactId>ehcache</artifactId>
+        <version>1.6.1</version>
+        <type>jar</type>
+        <!--classifier>jaronly</classifier-->
+   </dependency>
   </dependencies>
 
   <build>

Added: mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/state/presence/AbstractBaseCache.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/state/presence/AbstractBaseCache.java?rev=799847&view=auto
==============================================================================
--- mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/state/presence/AbstractBaseCache.java (added)
+++ mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/state/presence/AbstractBaseCache.java Sat Aug  1 11:48:21 2009
@@ -0,0 +1,92 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.vysper.xmpp.state.presence;
+
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.stanza.PresenceStanza;
+
+/**
+ * Base Cache implementation class. Has utility functions and implements
+ * common validations here. Other classes can extend this class and implement
+ * only the put, get and remove functions.
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ */
+public abstract class AbstractBaseCache implements LatestPresenceCache {
+
+    /**
+     * Validates basic Entity Data. Current implementation has following checks
+     * 1. Entity cannot be null
+     * 2. Resource cannot be null 
+     *
+     * @param entity    Entity to be verified
+     */
+    protected void checkEntry(Entity entity) {
+        if (entity == null) {
+            throw new PresenceCachingException("Entity cannot be null");
+        }
+
+        if (entity.getResource() == null) {
+            throw new PresenceCachingException("presense stanzas are cached per resource, failure for "
+                                                + entity.getFullQualifiedName());
+        }
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public void put(Entity entity, PresenceStanza presenceStanza)
+                                    throws PresenceCachingException {
+        checkEntry(entity);
+
+        // Can't store null entity
+        if(presenceStanza == null) {
+            throw new PresenceCachingException("Presence Stanza cannot be null");            
+        }
+
+        put0(entity, presenceStanza);
+    }
+
+    /**
+     * Put the entry in the cache. The basic validations have been done in the
+     * calling function.
+     *
+     * @param entity            Key for the PresenceStanza
+     * @param presenceStanza    PresenceStanza to be stored
+     * @throws PresenceCachingException
+     */
+    public abstract void put0(Entity entity, PresenceStanza presenceStanza)
+                                    throws PresenceCachingException;
+
+    public PresenceStanza get(Entity entity) throws PresenceCachingException {
+        checkEntry(entity);
+        return get0(entity);
+    }
+
+    /**
+     * returns the PresenceStanza, with Entity as key
+     *
+     * @param entity        Key for the Cache entry
+     * @return              PresenceStanza related with the key
+     * @throws PresenceCachingException
+     */
+    public abstract PresenceStanza get0(Entity entity)
+                                            throws PresenceCachingException;
+}
\ No newline at end of file

Propchange: mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/state/presence/AbstractBaseCache.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/state/presence/AbstractBaseCache.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/state/presence/EhCachePresenceCacheImpl.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/state/presence/EhCachePresenceCacheImpl.java?rev=799847&view=auto
==============================================================================
--- mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/state/presence/EhCachePresenceCacheImpl.java (added)
+++ mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/state/presence/EhCachePresenceCacheImpl.java Sat Aug  1 11:48:21 2009
@@ -0,0 +1,139 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+
+package org.apache.vysper.xmpp.state.presence;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Element;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.stanza.PresenceStanza;
+
+import java.net.URL;
+
+/**
+ * EhCache based cache Presence cache implementation. The imlpementation stores
+ * the PresenceStanza into two cache's. One is for Entity as a key. However to
+ * cater to request for bare JID's, we store the smae entry into another cahce
+ * with JID as a key. Since the PresenceStanza is stores as a reference, the
+ * memory penalty is not too much.
+ *
+ * The Policy for the cahce is LRU. The cahce is created from ehcache.xml file
+ * The cahce is in-memory only and doesn't store data to the same. If disk
+ * storage is needed, the same can be achieved by updating the ehcache.xml file.
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ */
+public class EhCachePresenceCacheImpl extends AbstractBaseCache {
+
+    // Key to fetch Presence Cache
+    private static final String PRESENCE_CACHE = "PresenceCache";
+
+    // Key to fetch JID Presence Cache
+    private static final String JID_PRESENCE_CACHE = "JIDCache";
+
+    // Cache instance to store the presence information against Entity
+    private Cache presenceCache = null;
+    
+    // Cache instance to store presence information against JID
+    private Cache jidPresenceCache = null;
+
+    /**
+     * Defaulr Contructor
+     */
+    public EhCachePresenceCacheImpl() {
+        createCache();
+    }
+
+    /**
+     * Create the ehcache based on ehcache.xml file
+     * Create two cache instances to store PresenceStanza against Entity and
+     * JID
+     */
+    protected void createCache() {
+        URL configFileURL = getClass().getResource("ehcache.xml");
+        if(configFileURL == null) {
+
+        }
+        CacheManager.create();
+
+        presenceCache = CacheManager.getInstance().getCache(PRESENCE_CACHE);
+        jidPresenceCache = CacheManager.getInstance().getCache(JID_PRESENCE_CACHE); 
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public void put0(Entity entity, PresenceStanza presenceStanza)
+                                    throws PresenceCachingException {
+        // Create EhCache elements to be stored
+        Element cacheElement = new Element(entity, presenceStanza);
+        Element jidElement = new Element(entity.getBareJID(), presenceStanza);
+
+        presenceCache.put(cacheElement);
+        jidPresenceCache.put(jidElement);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public PresenceStanza get0(Entity entity) throws PresenceCachingException {
+        // Get the Element from cache
+        Element cacheElement = presenceCache.get(entity);
+
+        // return the value from presence cache
+        if(cacheElement != null) {
+            return (PresenceStanza)cacheElement.getObjectValue();
+        }
+        return null;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public PresenceStanza getForBareJID(Entity entity) throws PresenceCachingException {
+        // return null for null entries
+        if(entity == null) {
+            return null;           
+        }
+
+        Element cacheElement = jidPresenceCache.get(entity);
+
+        // return the value from presence cache
+        if(cacheElement != null) {
+            return (PresenceStanza)cacheElement.getObjectValue();
+        }
+        return null;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public void remove(Entity entity) {
+        // if entity is null, keep silent
+        if(entity == null) {
+            return;            
+        }
+
+        // Remove the cache from presence and jid presence cache
+        presenceCache.remove(entity);
+        jidPresenceCache.remove(entity.getBareJID());
+    }
+}
\ No newline at end of file

Propchange: mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/state/presence/EhCachePresenceCacheImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/state/presence/EhCachePresenceCacheImpl.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: mina/sandbox/vysper/trunk/server/core/src/main/resources/ehcache.xml
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/core/src/main/resources/ehcache.xml?rev=799847&view=auto
==============================================================================
--- mina/sandbox/vysper/trunk/server/core/src/main/resources/ehcache.xml (added)
+++ mina/sandbox/vysper/trunk/server/core/src/main/resources/ehcache.xml Sat Aug  1 11:48:21 2009
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="ehcache.xsd" >
+
+    <!--
+    CacheManager Configuration
+    ==========================
+    An ehcache.xml corresponds to a single CacheManager.
+
+    See instructions below or the ehcache schema (ehcache.xsd) on how to configure.
+
+    System property tokens can be specified in this file which are replaced when the configuration
+    is loaded. For example multicastGroupPort=${multicastGroupPort} can be replaced with the
+    System property either from an environment variable or a system property specified with a
+    command line switch such as -DmulticastGroupPort=4446.
+
+    DiskStore configuration
+    =======================
+
+    The diskStore element is optional. To turn off disk store path creation, comment out the diskStore
+    element below.
+
+    Configure it if you have overflowToDisk or diskPersistent enabled for any cache.
+
+    If it is not configured, and a cache is created which requires a disk store, a warning will be
+     issued and java.io.tmpdir will automatically be used.
+
+    diskStore has only one attribute - "path". It is the path to the directory where
+    .data and .index files will be created.
+
+    If the path is one of the following Java System Property it is replaced by its value in the
+    running VM. For backward compatibility these are not specified without being enclosed in the ${token}
+    replacement syntax.
+
+    The following properties are translated:
+    * user.home - User's home directory
+    * user.dir - User's current working directory
+    * java.io.tmpdir - Default temp file path
+    * ehcache.disk.store.dir - A system property you would normally specify on the command line
+      e.g. java -Dehcache.disk.store.dir=/u01/myapp/diskdir ...
+
+    Subdirectories can be specified below the property e.g. java.io.tmpdir/one
+
+    -->
+    <diskStore path="java.io.tmpdir"/>
+
+
+    <!--
+    Mandatory Default Cache configuration. These settings will be applied to caches
+    created programmtically using CacheManager.add(String cacheName).
+
+    The defaultCache has an implicit name "default" which is a reserved cache name.
+    -->
+    <defaultCache
+            maxElementsInMemory="10000"
+            eternal="false"
+            timeToIdleSeconds="120"
+            timeToLiveSeconds="120"
+            overflowToDisk="false"
+            diskSpoolBufferSizeMB="30"
+            maxElementsOnDisk="10000000"
+            diskPersistent="false"
+            diskExpiryThreadIntervalSeconds="120"
+            memoryStoreEvictionPolicy="LRU"
+            />
+
+    <!--
+    	Caches
+    -->
+
+    <!--
+    	Cache for Presence with Entity as key
+    -->
+    <cache name="PresenceCache"
+           maxElementsInMemory="10000"
+           eternal="true"
+           overflowToDisk="false"
+           memoryStoreEvictionPolicy="LRU"/>
+
+	<!--
+    	Cache for Presence with JID as key
+    -->
+    <cache name="JIDCache"
+           maxElementsInMemory="10000"
+           eternal="true"
+           overflowToDisk="false"
+           memoryStoreEvictionPolicy="LRU"/>
+
+</ehcache>
\ No newline at end of file

Propchange: mina/sandbox/vysper/trunk/server/core/src/main/resources/ehcache.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/sandbox/vysper/trunk/server/core/src/main/resources/ehcache.xml
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: mina/sandbox/vysper/trunk/server/core/src/main/resources/ehcache.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/state/presence/EhCachePresenceCacheImplTest.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/state/presence/EhCachePresenceCacheImplTest.java?rev=799847&view=auto
==============================================================================
--- mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/state/presence/EhCachePresenceCacheImplTest.java (added)
+++ mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/state/presence/EhCachePresenceCacheImplTest.java Sat Aug  1 11:48:21 2009
@@ -0,0 +1,124 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.vysper.xmpp.state.presence;
+
+import org.apache.vysper.xmpp.stanza.PresenceStanza;
+import org.apache.vysper.xmpp.stanza.XMPPCoreStanza;
+import org.apache.vysper.xmpp.stanza.StanzaBuilder;
+import org.apache.vysper.xmpp.modules.core.TestUser;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+
+/**
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ */
+public class EhCachePresenceCacheImplTest extends LatestPresenceCacheTestCase {
+
+    LatestPresenceCache presenceCache  = new EhCachePresenceCacheImpl();
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected LatestPresenceCache getCache() {
+        return presenceCache;
+    }
+
+    /**
+     * Test Cache is created properly
+     */
+    public void testCreateCache() {
+        assertNotNull(presenceCache);        
+    }
+
+    public void testPut() {
+        presenceCache.put(getEntity(), getPresenceStanza(initiatingUser));
+        assertNotNull(presenceCache.get(getEntity()));
+    }
+
+    public void testRemove() {
+        Entity entity = getEntity();
+        presenceCache.put(entity, getPresenceStanza(initiatingUser));
+        presenceCache.remove(entity);
+
+        // It should return null
+        assertNull("Entry should be null", presenceCache.get(entity));
+        assertNull("Entry should be null in JID Cache", presenceCache.getForBareJID(entity));
+    }
+
+    public void testGetNullParam() {
+        try {
+            presenceCache.get(null);
+        } catch (PresenceCachingException ex) {
+            assertTrue("Exception was expected was null entry", true);
+        } catch (Exception e) {
+            fail("Only PresenceCachingException is expected");
+        }
+    }
+
+    public void testPutNullEntityParam() {
+         try {
+            presenceCache.put(null, getPresenceStanza(initiatingUser));
+        } catch (PresenceCachingException ex) {
+            assertTrue("Exception was expected was null entry", true);
+        } catch (Exception e) {
+            fail("Only PresenceCachingException is expected");
+        }
+    }
+
+    public void testPutNullPresenceParam() {
+         try {
+            presenceCache.put(getEntity(), null);
+        } catch (PresenceCachingException ex) {
+            assertTrue("Exception was expected was null entry", true);
+        } catch (Exception e) {
+            fail("Only PresenceCachingException is expected");
+        }
+    }
+
+    /**
+     * Returns an Entity to be used as a key
+     * @return
+     */
+    protected Entity getEntity() {
+        try {
+            Entity entity = EntityImpl.parse("tester@apache.org/test");
+            return entity;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    /**
+     * Creates a PresenceStanza instance to be used as value for cache
+     * 
+     * @param user  User whose Presence Information is to be created
+     * @return  Presence Information of the User
+     */
+    protected PresenceStanza getPresenceStanza(TestUser user) {
+        XMPPCoreStanza initialPresence = XMPPCoreStanza.getWrapper(StanzaBuilder.createPresenceStanza(user.getEntityFQ(),
+                                                                                                       null, null, null, null, null).getFinalStanza());
+        return (PresenceStanza)initialPresence;
+    }
+
+}
\ No newline at end of file

Propchange: mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/state/presence/EhCachePresenceCacheImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/state/presence/EhCachePresenceCacheImplTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date