Project

General

Profile

« Previous | Next » 

Revision 6440

Added by rnahf over 12 years ago

cleaned up mock tests on hzObjectPathMap. split out code for mocking a datastore into MockObjectPathMap.

View differences:

test/edu/ucsb/nceas/metacat/dataone/hazelcast.test.properties.xml
1
<?xml version="1.0" encoding="UTF-8"?>
2
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-basic.xsd"
3
           xmlns="http://www.hazelcast.com/schema/config"
4
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
5
    <group>
6
        <name>dev</name>
7
        <password>dev-pass</password>
8
    </group>
9
    <network>
10
        <port auto-increment="true">5701</port>
11
        <join>
12
            <multicast enabled="true">
13
                <multicast-group>224.2.2.3</multicast-group>
14
                <multicast-port>54327</multicast-port>
15
            </multicast>
16
            <tcp-ip enabled="false">
17
                <interface>127.0.0.1</interface>
18
            </tcp-ip>
19
        </join>
20
        <interfaces enabled="false">
21
            <interface>10.10.1.*</interface>
22
        </interfaces>
23
        <symmetric-encryption enabled="false">
24
            <!--
25
               encryption algorithm such as
26
               DES/ECB/PKCS5Padding,
27
               PBEWithMD5AndDES,
28
               AES/CBC/PKCS5Padding,
29
               Blowfish,
30
               DESede
31
            -->
32
            <algorithm>PBEWithMD5AndDES</algorithm>
33
            <!-- salt value to use when generating the secret key -->
34
            <salt>thesalt</salt>
35
            <!-- pass phrase to use when generating the secret key -->
36
            <password>thepass</password>
37
            <!-- iteration count to use when generating the secret key -->
38
            <iteration-count>19</iteration-count>
39
        </symmetric-encryption>
40
        <asymmetric-encryption enabled="false">
41
            <!-- encryption algorithm -->
42
            <algorithm>RSA/NONE/PKCS1PADDING</algorithm>
43
            <!-- private key password -->
44
            <keyPassword>thekeypass</keyPassword>
45
            <!-- private key alias -->
46
            <keyAlias>local</keyAlias>
47
            <!-- key store type -->
48
            <storeType>JKS</storeType>
49
            <!-- key store password -->
50
            <storePassword>thestorepass</storePassword>
51
            <!-- path to the key store -->
52
            <storePath>keystore</storePath>
53
        </asymmetric-encryption>
54
    </network>
55
    <executor-service>
56
        <core-pool-size>16</core-pool-size>
57
        <max-pool-size>64</max-pool-size>
58
        <keep-alive-seconds>60</keep-alive-seconds>
59
    </executor-service>
60
    <queue name="default">
61

  
62
        <!--
63
            Maximum size of the queue. When a JVM's local queue size reaches the maximum,
64
            all put/offer operations will get blocked until the queue size
65
            of the JVM goes down below the maximum.
66
            Any integer between 0 and Integer.MAX_VALUE. 0 means
67
            Integer.MAX_VALUE. Default is 0.
68
        -->
69
        <max-size-per-jvm>0</max-size-per-jvm>
70

  
71
        <!--
72
            Name of the map configuration that will be used for the backing distributed
73
            map for this queue.
74
        -->
75
        <backing-map-ref>default</backing-map-ref>
76

  
77
    </queue>
78
    <map name="default">
79
        <!--
80
            Number of backups. If 1 is set as the backup-count for example,
81
            then all entries of the map will be copied to another JVM for
82
            fail-safety. Valid numbers are 0 (no backup), 1, 2, 3.
83
        -->
84
        <backup-count>1</backup-count>
85
        <!--
86
            Valid values are:
87
            NONE (no eviction),
88
            LRU (Least Recently Used),
89
            LFU (Least Frequently Used).
90
            NONE is the default.
91
        -->
92
        <eviction-policy>NONE</eviction-policy>
93
        <!--
94
            Maximum size of the map. When max size is reached,
95
            map is evicted based on the policy defined.
96
            Any integer between 0 and Integer.MAX_VALUE. 0 means
97
            Integer.MAX_VALUE. Default is 0.
98
        -->
99
        <max-size policy="cluster_wide_map_size">0</max-size>
100
        <!--
101
            When max. size is reached, specified percentage of
102
            the map will be evicted. Any integer between 0 and 100.
103
            If 25 is set for example, 25% of the entries will
104
            get evicted.
105
        -->
106
        <eviction-percentage>25</eviction-percentage>
107

  
108
        <!--
109
            While recovering from split-brain (network partitioning),
110
            map entries in the small cluster will merge into the bigger cluster
111
            based on the policy set here. When an entry merge into the
112
            cluster, there might an existing entry with the same key already.
113
            Values of these entries might be different for that same key.
114
            Which value should be set for the key? Conflict is resolved by
115
            the policy set here. Default policy is hz.ADD_NEW_ENTRY
116

  
117
            There are built-in merge policies such as
118
            hz.NO_MERGE      ; no entry will merge.
119
            hz.ADD_NEW_ENTRY ; entry will be added if the merging entry's key
120
                               doesn't exist in the cluster.
121
            hz.HIGHER_HITS   ; entry with the higher hits wins.
122
            hz.LATEST_UPDATE ; entry with the latest update wins.
123
        -->
124
        <merge-policy>hz.ADD_NEW_ENTRY</merge-policy>
125
    </map>
126
    <map name="hzObjectPath">
127
        ...
128
        <map-store enabled="true">
129
            <!--
130
               Name of the class implementing MapLoader and/or MapStore. 
131
               The class should implement at least of these interfaces and
132
               contain no-argument constructor. Note that the inner classes are not supported.
133
            -->
134
            <class-name>edu.ucsb.nceas.metacat.dataone.hazelcast.ObjectPathMap</class-name>
135
            <!--
136
               Number of seconds to delay to call the MapStore.store(key, value).
137
               If the value is zero then it is write-through so MapStore.store(key, value)
138
               will be called as soon as the entry is updated.
139
               Otherwise it is write-behind so updates will be stored after write-delay-seconds
140
               value by calling Hazelcast.storeAll(map). Default value is 0.
141
            -->
142
            <write-delay-seconds>0</write-delay-seconds>
143
        </map-store>
144
    </map>
145
    <!-- Add your own map merge policy implementations here:     
146
    	<merge-policies>
147
           	<map-merge-policy name="MY_MERGE_POLICY">
148
            	<class-name>com.acme.MyOwnMergePolicy</class-name>
149
        	</map-merge-policy>
150
    	</merge-policies>
151
    -->
152

  
153
</hazelcast>
test/edu/ucsb/nceas/metacat/dataone/HzObjectPathMapTest.java
1
package edu.ucsb.nceas.metacat.dataone;
2

  
3
import java.util.Map;
4

  
5
import org.dataone.service.types.v1.Identifier;
6
import org.junit.Before;
7
import org.junit.Test;
8

  
9
import com.hazelcast.core.Hazelcast;
10
import com.hazelcast.core.HazelcastInstance;
11

  
12
import edu.ucsb.nceas.MCTestCase;
13

  
14

  
15
public class HzObjectPathMapTest extends MCTestCase {
16

  
17
	
18
	@Before
19
	public void setUp() {
20
		
21
	}
22
	
23
	@Test
24
    public void testInstantiation() {
25
        // start a member
26
        HazelcastInstance h1 = Hazelcast.newHazelcastInstance(null);
27
        Map map1 = h1.getMap("hzObjectPath");
28
        assertEquals(99, map1.size());
29
	}
30
	
31
	
32
	
33
	
34
	@Test public void testProducerConsumer() {
35
		// start a member
36
		
37
		System.getProperties().setProperty("hazelcast.config",
38
				"/Users/rnahf/software/workspace/nceas/metacat/" +
39
				"test/edu/ucsb/nceas/metacat/dataone/hazelcast.test.properties.xml");
40
		HazelcastInstance h1 = Hazelcast.newHazelcastInstance(null);
41
		Map serverMap = h1.getMap("hzObjectPath");
42
		
43
		
44
		System.getProperties().setProperty("hazelcast.hzObjectPathRole","consumer");
45

  
46
		HazelcastInstance h2 = Hazelcast.newHazelcastInstance(null);
47
		Map clientMap = h2.getMap("hzObjectPath");
48
		
49
		
50
		System.out.println(serverMap.get(createIdentifier("testID.35")));
51
		System.out.println(serverMap.get(createIdentifier("testID.23434")));
52

  
53
		String pathValue = (String) clientMap.get(createIdentifier("testID.35"));
54
		
55
		System.out.println("pathValue: " + pathValue);
56
		assertEquals("/path/testID.35", pathValue);
57
	}	
58
	
59
	
60
		
61
	private Identifier createIdentifier(String idValue) {
62
		Identifier id = new Identifier();
63
		id.setValue(idValue);
64
		return id;
65
	}
66

  
67
}
test/edu/ucsb/nceas/metacat/dataone/hazelcast/HzObjectPathMapTest.java
1
package edu.ucsb.nceas.metacat.dataone.hazelcast;
2

  
3
import static org.hamcrest.CoreMatchers.is;
4
import static org.junit.Assert.assertThat;
5

  
6
import java.io.File;
7
import java.util.Map;
8
import java.util.concurrent.Callable;
9

  
10
import org.dataone.service.types.v1.Identifier;
11
import org.junit.After;
12
import org.junit.Before;
13
import org.junit.Rule;
14
import org.junit.Test;
15
import org.junit.rules.ErrorCollector;
16

  
17
import com.hazelcast.core.Hazelcast;
18
import com.hazelcast.core.HazelcastInstance;
19

  
20
import edu.ucsb.nceas.MCTestCase;
21

  
22

  
23
public class HzObjectPathMapTest extends MCTestCase {
24
	public final static String CONFIG_PATH = "/Users/rnahf/" +
25
//			"projects/" +
26
			"software/workspace" + 
27
			"nceas/metacat/test/edu/ucsb/nceas/metacat/dataone/hazelcast";
28
	
29
	/**
30
	 * Need to use the error collector to handle JUnit assertions
31
	 * and keep going.  This is because setting up multiple tests of
32
	 * Hazelcast is not straightforward.
33
	 * The check methods in this class use this errorCollector
34
	 * the check methods 
35
	 */
36
	@Rule 
37
    public ErrorCollector errorCollector = new ErrorCollector();
38

  
39
	
40
	
41
    protected void checkEquals(final String message, final String s1, final String s2)
42
    {
43
 //   	System.out.println("assertion: " + message);
44
    	errorCollector.checkSucceeds(new Callable<Object>() 
45
        {
46
            public Object call() throws Exception 
47
            {
48
                assertThat(message, s1, is(s2));
49
                return null;
50
            }
51
        });
52
    }
53

  
54
    /**
55
	 * performs the equivalent of the junit assertTrue method
56
	 * using the errorCollector to record the error and keep going
57
	 * 
58
	 * @param message
59
	 * @param s1
60
	 * @param s2
61
	 */
62
    protected void checkTrue(final String message, final boolean b)
63
    {
64
//        System.out.println("assertion: " + message);
65
    	errorCollector.checkSucceeds(new Callable<Object>() 
66
        {
67
            public Object call() throws Exception 
68
            {
69
            	assertThat(message, true, is(b));
70
            	return null;
71
            }
72
        });
73
    }
74
    
75
    
76
    
77
	@After
78
    public void cleanup() throws Exception {
79
        Hazelcast.shutdownAll(); 
80
    }
81
    
82

  
83
	@Test
84
	public void testBehavior() {
85
		/**
86
		 * set up the two hazelcast instances (separate configurations)
87
		 * mapProvider is configured with the ObjectPathMap (MapLoader)
88
		 * mapUser is configured with a default config file (no MapLoader implementation)
89
		 */
90
		File configPath = new File(CONFIG_PATH + "hzObjectPathMap.provider.test.properties.xml");
91
		checkTrue("config file should exist", configPath.canRead());
92
		System.getProperties().setProperty("hazelcast.config", configPath.getAbsolutePath());
93
		HazelcastInstance mapProvider = Hazelcast.newHazelcastInstance(null);
94

  
95
		
96
		// setup and start the non-maploader member (d1_indexer)
97
		configPath = new File(CONFIG_PATH + "hzObjectPathMap.user.test.properties.xml");
98
		checkTrue("config file should exist", configPath.canRead());
99
		System.getProperties().setProperty("hazelcast.config", configPath.getAbsolutePath());	
100
		HazelcastInstance mapUser = Hazelcast.newHazelcastInstance(null);
101
		
102
		// try to read from uninstantiated map
103
		Map<Identifier,String> userMap = mapUser.getMap("hzObjectPath");		
104
		checkTrue("userMap should be empty at first", userMap.size() == 0);
105
		
106
		Map<Identifier,String> providerMap = mapProvider.getMap("hzObjectPath");
107
		checkTrue("providerMap should have keys", providerMap.size() > 0);
108
		checkTrue("userMap should have keys now", userMap.size() > 0);
109
		
110

  
111
		System.out.println("test Getting Preloaded Keys Via the UserMap"); 
112

  
113
		String pathValue = userMap.get(createIdentifier("testID.26"));
114
		System.out.println("pathValue: " + pathValue);
115
		checkEquals("userMap should contain a value for this", 
116
				"/path/testID.26", pathValue);
117

  
118

  
119
		System.out.println("test Getting Unloaded Keys Via the UserMap");
120
		pathValue = userMap.get(createIdentifier("anNewKey"));
121
		System.out.println("pathValue: " + pathValue);
122
		checkEquals("userMap should contain a value for this", 
123
				"/path/anNewKey", pathValue);
124

  
125

  
126
		System.out.println("test Entry Not Added When Key Not In Datastore");
127

  
128
		pathValue = userMap.get(createIdentifier("NO_CREATE_identifier"));
129
		System.out.println("pathValue: " + pathValue);
130
		checkEquals("providerInstance should return null if not found", null, pathValue);
131
		
132
		
133
	}
134
	
135
//		
136
//		System.out.println(serverMap.get(createIdentifier("testID.35")));
137
//		System.out.println(serverMap.get(createIdentifier("aNewIdentifier")));
138
//		
139
////		System.getProperties().setProperty("hazelcast.hzObjectPathRole","consumer");
140
//	
141
//		System.out.println("client Instance");
142
//		System.out.println("1 " + clientMap.get(createIdentifier("testID.35")));
143
//		System.out.println("2 " + clientMap.get(createIdentifier("aNewIdentifier")));
144
//		
145
//		String lookupMyPathPlease = "foo";
146
//		String pathValue = (String) clientMap.get(createIdentifier(lookupMyPathPlease));
147
//		System.out.println("remote retrieval of pathValue: " + pathValue);
148
//		
149
//		pathValue = (String) serverMap.get(createIdentifier(lookupMyPathPlease));		
150
//		System.out.println("server retrieval of pathValue: " + pathValue);
151
//			
152
//		pathValue = (String) clientMap.get(createIdentifier(lookupMyPathPlease));		
153
//		System.out.println("remote retrieval of pathValue again: " + pathValue);
154
//		
155
//		//assertEquals("/path/" + lookupMyPathPlease, pathValue);
156
//	}	
157
	
158
	
159
		
160
	private Identifier createIdentifier(String idValue) {
161
		Identifier id = new Identifier();
162
		id.setValue(idValue);
163
		return id;
164
	}
165

  
166
}
test/edu/ucsb/nceas/metacat/dataone/hazelcast/hzObjectPathMap.provider.test.properties.xml
1
<?xml version="1.0" encoding="UTF-8"?>
2
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-basic.xsd"
3
           xmlns="http://www.hazelcast.com/schema/config"
4
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
5
    <group>
6
        <name>dev</name>
7
        <password>dev-pass</password>
8
    </group>
9
    <network>
10
        <port auto-increment="true">5701</port>
11
        <join>
12
            <multicast enabled="true">
13
                <multicast-group>224.2.2.3</multicast-group>
14
                <multicast-port>54327</multicast-port>
15
            </multicast>
16
            <tcp-ip enabled="false">
17
                <interface>127.0.0.1</interface>
18
            </tcp-ip>
19
        </join>
20
        <interfaces enabled="false">
21
            <interface>10.10.1.*</interface>
22
        </interfaces>
23
        <symmetric-encryption enabled="false">
24
            <!--
25
               encryption algorithm such as
26
               DES/ECB/PKCS5Padding,
27
               PBEWithMD5AndDES,
28
               AES/CBC/PKCS5Padding,
29
               Blowfish,
30
               DESede
31
            -->
32
            <algorithm>PBEWithMD5AndDES</algorithm>
33
            <!-- salt value to use when generating the secret key -->
34
            <salt>thesalt</salt>
35
            <!-- pass phrase to use when generating the secret key -->
36
            <password>thepass</password>
37
            <!-- iteration count to use when generating the secret key -->
38
            <iteration-count>19</iteration-count>
39
        </symmetric-encryption>
40
        <asymmetric-encryption enabled="false">
41
            <!-- encryption algorithm -->
42
            <algorithm>RSA/NONE/PKCS1PADDING</algorithm>
43
            <!-- private key password -->
44
            <keyPassword>thekeypass</keyPassword>
45
            <!-- private key alias -->
46
            <keyAlias>local</keyAlias>
47
            <!-- key store type -->
48
            <storeType>JKS</storeType>
49
            <!-- key store password -->
50
            <storePassword>thestorepass</storePassword>
51
            <!-- path to the key store -->
52
            <storePath>keystore</storePath>
53
        </asymmetric-encryption>
54
    </network>
55
    <executor-service>
56
        <core-pool-size>16</core-pool-size>
57
        <max-pool-size>64</max-pool-size>
58
        <keep-alive-seconds>60</keep-alive-seconds>
59
    </executor-service>
60
    <queue name="default">
61

  
62
        <!--
63
            Maximum size of the queue. When a JVM's local queue size reaches the maximum,
64
            all put/offer operations will get blocked until the queue size
65
            of the JVM goes down below the maximum.
66
            Any integer between 0 and Integer.MAX_VALUE. 0 means
67
            Integer.MAX_VALUE. Default is 0.
68
        -->
69
        <max-size-per-jvm>0</max-size-per-jvm>
70

  
71
        <!--
72
            Name of the map configuration that will be used for the backing distributed
73
            map for this queue.
74
        -->
75
        <backing-map-ref>default</backing-map-ref>
76

  
77
    </queue>
78
    <map name="default">
79
        <!--
80
            Number of backups. If 1 is set as the backup-count for example,
81
            then all entries of the map will be copied to another JVM for
82
            fail-safety. Valid numbers are 0 (no backup), 1, 2, 3.
83
        -->
84
        <backup-count>1</backup-count>
85
        <!--
86
            Valid values are:
87
            NONE (no eviction),
88
            LRU (Least Recently Used),
89
            LFU (Least Frequently Used).
90
            NONE is the default.
91
        -->
92
        <eviction-policy>NONE</eviction-policy>
93
        <!--
94
            Maximum size of the map. When max size is reached,
95
            map is evicted based on the policy defined.
96
            Any integer between 0 and Integer.MAX_VALUE. 0 means
97
            Integer.MAX_VALUE. Default is 0.
98
        -->
99
        <max-size policy="cluster_wide_map_size">0</max-size>
100
        <!--
101
            When max. size is reached, specified percentage of
102
            the map will be evicted. Any integer between 0 and 100.
103
            If 25 is set for example, 25% of the entries will
104
            get evicted.
105
        -->
106
        <eviction-percentage>25</eviction-percentage>
107

  
108
        <!--
109
            While recovering from split-brain (network partitioning),
110
            map entries in the small cluster will merge into the bigger cluster
111
            based on the policy set here. When an entry merge into the
112
            cluster, there might an existing entry with the same key already.
113
            Values of these entries might be different for that same key.
114
            Which value should be set for the key? Conflict is resolved by
115
            the policy set here. Default policy is hz.ADD_NEW_ENTRY
116

  
117
            There are built-in merge policies such as
118
            hz.NO_MERGE      ; no entry will merge.
119
            hz.ADD_NEW_ENTRY ; entry will be added if the merging entry's key
120
                               doesn't exist in the cluster.
121
            hz.HIGHER_HITS   ; entry with the higher hits wins.
122
            hz.LATEST_UPDATE ; entry with the latest update wins.
123
        -->
124
        <merge-policy>hz.ADD_NEW_ENTRY</merge-policy>
125
    </map>
126
    <map name="hzObjectPath">
127
        ...
128
        <map-store enabled="true">
129
            <!--
130
               Name of the class implementing MapLoader and/or MapStore. 
131
               The class should implement at least of these interfaces and
132
               contain no-argument constructor. Note that the inner classes are not supported.
133
            -->
134
            <class-name>edu.ucsb.nceas.metacat.dataone.hazelcast.MockObjectPathMap</class-name>
135
            <!--
136
               Number of seconds to delay to call the MapStore.store(key, value).
137
               If the value is zero then it is write-through so MapStore.store(key, value)
138
               will be called as soon as the entry is updated.
139
               Otherwise it is write-behind so updates will be stored after write-delay-seconds
140
               value by calling Hazelcast.storeAll(map). Default value is 0.
141
            -->
142
            <write-delay-seconds>0</write-delay-seconds>
143
        </map-store>
144
    </map>
145
    <!-- Add your own map merge policy implementations here:     
146
    	<merge-policies>
147
           	<map-merge-policy name="MY_MERGE_POLICY">
148
            	<class-name>com.acme.MyOwnMergePolicy</class-name>
149
        	</map-merge-policy>
150
    	</merge-policies>
151
    -->
152

  
153
</hazelcast>
test/edu/ucsb/nceas/metacat/dataone/hazelcast/hzObjectPathMap.user.test.properties.xml
1
<?xml version="1.0" encoding="UTF-8"?>
2
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-basic.xsd"
3
           xmlns="http://www.hazelcast.com/schema/config"
4
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
5
    <group>
6
        <name>dev</name>
7
        <password>dev-pass</password>
8
    </group>
9
    <network>
10
        <port auto-increment="true">5701</port>
11
        <join>
12
            <multicast enabled="true">
13
                <multicast-group>224.2.2.3</multicast-group>
14
                <multicast-port>54327</multicast-port>
15
            </multicast>
16
            <tcp-ip enabled="false">
17
                <interface>127.0.0.1</interface>
18
            </tcp-ip>
19
        </join>
20
        <interfaces enabled="false">
21
            <interface>10.10.1.*</interface>
22
        </interfaces>
23
        <symmetric-encryption enabled="false">
24
            <!--
25
               encryption algorithm such as
26
               DES/ECB/PKCS5Padding,
27
               PBEWithMD5AndDES,
28
               AES/CBC/PKCS5Padding,
29
               Blowfish,
30
               DESede
31
            -->
32
            <algorithm>PBEWithMD5AndDES</algorithm>
33
            <!-- salt value to use when generating the secret key -->
34
            <salt>thesalt</salt>
35
            <!-- pass phrase to use when generating the secret key -->
36
            <password>thepass</password>
37
            <!-- iteration count to use when generating the secret key -->
38
            <iteration-count>19</iteration-count>
39
        </symmetric-encryption>
40
        <asymmetric-encryption enabled="false">
41
            <!-- encryption algorithm -->
42
            <algorithm>RSA/NONE/PKCS1PADDING</algorithm>
43
            <!-- private key password -->
44
            <keyPassword>thekeypass</keyPassword>
45
            <!-- private key alias -->
46
            <keyAlias>local</keyAlias>
47
            <!-- key store type -->
48
            <storeType>JKS</storeType>
49
            <!-- key store password -->
50
            <storePassword>thestorepass</storePassword>
51
            <!-- path to the key store -->
52
            <storePath>keystore</storePath>
53
        </asymmetric-encryption>
54
    </network>
55
    <executor-service>
56
        <core-pool-size>16</core-pool-size>
57
        <max-pool-size>64</max-pool-size>
58
        <keep-alive-seconds>60</keep-alive-seconds>
59
    </executor-service>
60
    <queue name="default">
61

  
62
        <!--
63
            Maximum size of the queue. When a JVM's local queue size reaches the maximum,
64
            all put/offer operations will get blocked until the queue size
65
            of the JVM goes down below the maximum.
66
            Any integer between 0 and Integer.MAX_VALUE. 0 means
67
            Integer.MAX_VALUE. Default is 0.
68
        -->
69
        <max-size-per-jvm>0</max-size-per-jvm>
70

  
71
        <!--
72
            Name of the map configuration that will be used for the backing distributed
73
            map for this queue.
74
        -->
75
        <backing-map-ref>default</backing-map-ref>
76

  
77
    </queue>
78
    <map name="default">
79
        <!--
80
            Number of backups. If 1 is set as the backup-count for example,
81
            then all entries of the map will be copied to another JVM for
82
            fail-safety. Valid numbers are 0 (no backup), 1, 2, 3.
83
        -->
84
        <backup-count>1</backup-count>
85
        <!--
86
            Valid values are:
87
            NONE (no eviction),
88
            LRU (Least Recently Used),
89
            LFU (Least Frequently Used).
90
            NONE is the default.
91
        -->
92
        <eviction-policy>NONE</eviction-policy>
93
        <!--
94
            Maximum size of the map. When max size is reached,
95
            map is evicted based on the policy defined.
96
            Any integer between 0 and Integer.MAX_VALUE. 0 means
97
            Integer.MAX_VALUE. Default is 0.
98
        -->
99
        <max-size policy="cluster_wide_map_size">0</max-size>
100
        <!--
101
            When max. size is reached, specified percentage of
102
            the map will be evicted. Any integer between 0 and 100.
103
            If 25 is set for example, 25% of the entries will
104
            get evicted.
105
        -->
106
        <eviction-percentage>25</eviction-percentage>
107

  
108
        <!--
109
            While recovering from split-brain (network partitioning),
110
            map entries in the small cluster will merge into the bigger cluster
111
            based on the policy set here. When an entry merge into the
112
            cluster, there might an existing entry with the same key already.
113
            Values of these entries might be different for that same key.
114
            Which value should be set for the key? Conflict is resolved by
115
            the policy set here. Default policy is hz.ADD_NEW_ENTRY
116

  
117
            There are built-in merge policies such as
118
            hz.NO_MERGE      ; no entry will merge.
119
            hz.ADD_NEW_ENTRY ; entry will be added if the merging entry's key
120
                               doesn't exist in the cluster.
121
            hz.HIGHER_HITS   ; entry with the higher hits wins.
122
            hz.LATEST_UPDATE ; entry with the latest update wins.
123
        -->
124
        <merge-policy>hz.ADD_NEW_ENTRY</merge-policy>
125
    </map>
126
    <!-- Add your own map merge policy implementations here:     
127
    	<merge-policies>
128
           	<map-merge-policy name="MY_MERGE_POLICY">
129
            	<class-name>com.acme.MyOwnMergePolicy</class-name>
130
        	</map-merge-policy>
131
    	</merge-policies>
132
    -->
133

  
134
</hazelcast>
test/edu/ucsb/nceas/metacat/dataone/hazelcast/MockObjectPathMap.java
1
package edu.ucsb.nceas.metacat.dataone.hazelcast;
2

  
3
import java.util.Collection;
4
import java.util.Collections;
5
import java.util.HashSet;
6
import java.util.Hashtable;
7
import java.util.List;
8
import java.util.Map;
9
import java.util.Set;
10

  
11
import org.dataone.service.types.v1.Identifier;
12

  
13
import com.hazelcast.core.MapLoader;
14

  
15
import edu.ucsb.nceas.metacat.IdentifierManager;
16
import edu.ucsb.nceas.metacat.McdbDocNotFoundException;
17
import edu.ucsb.nceas.metacat.properties.PropertyService;
18
import edu.ucsb.nceas.metacat.shared.ServiceException;
19
import edu.ucsb.nceas.utilities.FileUtil;
20
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
21

  
22

  
23
/**
24
 * MapLoader implementation for a hazelcast hzObjectPath.  This class is called
25
 * when the ObjectPathMap needs to refresh against the persistent data-store.
26
 * The use case for this class is to communicate the filepath between JVMs on
27
 * the same machine, specifically between the metacat instance and the d1_indexer.
28
 * 
29
 * d1_indexer will get Identifiers from elsewhere, but use this class to get
30
 * the paths to their associated files.  The getAllKeys() method can (and should)
31
 * return null in a live setting.  For unit testing, it may be useful to use
32
 * it to get some 
33
 * 
34
 * @author rnahf
35
 *
36
 */
37
public class MockObjectPathMap implements MapLoader<Identifier, String> {
38
	private static IdentifierManager im;
39
	private static String dataPath;
40
	private static String metadataPath;
41
	
42
	
43
	/**
44
	 * creates an ObjectPathMap
45
	 */
46
	public MockObjectPathMap() {
47
//		try {
48
//			PropertyService ps = PropertyService.getInstance();
49
//			dataPath = PropertyService.getProperty("application.datafilepath");
50
//			metadataPath = PropertyService.getProperty("application.documentfilepath");
51
//		} catch (PropertyNotFoundException e) {
52
//			// TODO Auto-generated catch block
53
//			e.printStackTrace();
54
//		} catch (ServiceException e) {
55
//			// TODO Auto-generated catch block
56
//			e.printStackTrace();
57
//		}
58
		dataPath = "/data/";
59
		metadataPath = "/metadata/";
60
		im = IdentifierManager.getInstance();
61
	}
62

  
63
	
64
	/*
65
	 * Metadata is stored in a different place on the filesystem than
66
	 * the data.  The doctype value for metadata can vary, but for data
67
	 * is always 'BIN', so using a simple if-then-else to separate
68
	 */
69
	private String pathToDocid(String localid) throws McdbDocNotFoundException  {
70
		
71
		return "/some/path/" + localid; 
72
//		Hashtable<String, Object> ht = im.getDocumentInfo(localid);
73
//		if (ht.get("doctype").equals("BIN")) {
74
//			return dataPath + FileUtil.getFS() + localid;
75
//		} else {
76
//			return metadataPath + FileUtil.getFS() + localid;
77
//		}		
78
	}
79

  
80
	
81
	/**
82
	 *  Implementation of hazelcast MapLoader interface method.
83
	 *  For the provided Identifier (as key), returns the path to the
84
	 *  document on the local filesystem.  Returns null if it can't 
85
	 *  create the path. 
86
	 */
87
	@Override
88
	public String load(Identifier key) 
89
	{
90

  
91
		String docid = null;
92
		String path = null;
93
		//			try {
94
		//				docid = im.getLocalId(key.getValue());
95
		//				path = pathToDocid(docid);			
96
		//			} catch (McdbDocNotFoundException e) {
97
		//				// TODO Auto-generated catch block
98
		//				e.printStackTrace();
99
		//				return null;
100
		//			}
101
		if (key.getValue().startsWith("NO_CREATE")) {
102
			return null;
103
		}
104
		path = "/path/" + key.getValue();
105
		return path;
106
	}
107
	
108
	
109
	/**
110
	 *  Implementation of hazelcast MapLoader interface method.  This method loads
111
	 *  mappings for all Identifiers in the parameters.  Any Identifier not found
112
	 *  is not included in the resulting map.
113
	 */
114
	@Override
115
	public Map<Identifier, String> loadAll(Collection<Identifier> identifiers) {
116
		
117
		
118
		Hashtable<Identifier,String> map = new Hashtable<Identifier,String>();
119
		for (Identifier id : identifiers) {
120
			map.put(id, "/path/" + id.getValue());
121
			//				try {
122
			//					String docid = im.getLocalId(id.getValue());
123
			//					map.put(id, pathToDocid(docid));
124
			//
125
			//				} catch (McdbDocNotFoundException e) {
126
			//					// TODO should the map load an empty path instead of
127
			//					// leaving out the entire entry?
128
			//					e.printStackTrace();
129
			//				}
130
		}
131
		return map;
132
	}
133

  
134
	
135
	/**
136
	 * Return the full set of guids in the local metacat repository as
137
	 * dataone Identifiers.
138
	 * 
139
	 * (Hazelcast allows avoiding pre-loading by returning NULL, so consider
140
	 * re-implementing if that serves the purpose of this class better)
141
	 */
142
	@Override
143
	public Set<Identifier> loadAllKeys() 
144
	{
145
		//		List<String> guids = im.getAllGUIDs();
146
		//		
147
		Set<Identifier> set = Collections.synchronizedSet(new HashSet<Identifier>());
148
		//		for (String guid : guids) {
149
		//			Identifier id = new Identifier();
150
		//			id.setValue(guid);
151
		//			set.add(id);
152
		//		}
153

  
154
		for (int i=1; i< 100; i++) {
155
			Identifier id = new Identifier();
156
			id.setValue("testID." + i);
157
			set.add(id);
158
		}
159
		return set;
160
		
161
	}
162
}
src/edu/ucsb/nceas/metacat/dataone/hazelcast/ObjectPathMap.java
22 22

  
23 23
/**
24 24
 * MapLoader implementation for a hazelcast hzObjectPath.  This class is called
25
 * when the ObjectPathMap needs to refresh against the persistent data-store.
25
 * when the IMap get methods needs to refresh against the persistent data-store.
26 26
 * The use case for this class is to communicate the filepath between JVMs on
27 27
 * the same machine, specifically between the metacat instance and the d1_indexer.
28 28
 * 
29 29
 * d1_indexer will get Identifiers from elsewhere, but use this class to get
30
 * the paths to their associated files.  The getAllKeys() method can (and should)
31
 * return null in a live setting.  For unit testing, it may be useful to use
32
 * it to get some 
30
 * the paths to their associated files.  The getAllKeys() method will
31
 * return null in a live setting, to avoid possibly expensive preloading
33 32
 * 
34 33
 * @author rnahf
35
 *
36 34
 */
37 35
public class ObjectPathMap implements MapLoader<Identifier, String> {
38 36
	private static IdentifierManager im;
39 37
	private static String dataPath;
40 38
	private static String metadataPath;
41 39
	
42
	private static boolean hasDataStore;
43

  
44

  
45 40
	
46 41
	/**
47 42
	 * creates an ObjectPathMap
48 43
	 */
49 44
	public ObjectPathMap() {
50
//		try {
51
//			PropertyService ps = PropertyService.getInstance();
52
//			dataPath = PropertyService.getProperty("application.datafilepath");
53
//			metadataPath = PropertyService.getProperty("application.documentfilepath");
54
//		} catch (PropertyNotFoundException e) {
55
//			// TODO Auto-generated catch block
56
//			e.printStackTrace();
57
//		} catch (ServiceException e) {
58
//			// TODO Auto-generated catch block
59
//			e.printStackTrace();
60
//		}
61
		dataPath = "/data/";
62
		metadataPath = "/metadata/";
45
		try {
46
			PropertyService ps = PropertyService.getInstance();
47
			dataPath = PropertyService.getProperty("application.datafilepath");
48
			metadataPath = PropertyService.getProperty("application.documentfilepath");
49
		} catch (PropertyNotFoundException e) {
50
			// TODO Auto-generated catch block
51
			e.printStackTrace();
52
		} catch (ServiceException e) {
53
			// TODO Auto-generated catch block
54
			e.printStackTrace();
55
		}
63 56
		im = IdentifierManager.getInstance();
64
		String role = System.getProperties().getProperty("hazelcast.hzObjectPathRole");
65
		if (role != null && role.equals("consumer")) {
66
			hasDataStore = false;
67
			System.out.println("new instance of ObjectPathMap: role = " + role);
68
		} else {
69
			hasDataStore = true;
70
			System.out.println("new instance of ObjectPathMap: role = " + role);
71
		}
72 57
	}
73 58

  
74 59
	
......
77 62
	 * the data.  The doctype value for metadata can vary, but for data
78 63
	 * is always 'BIN', so using a simple if-then-else to separate
79 64
	 */
80
	private String pathToDocid(String localid) throws McdbDocNotFoundException  {
81
		
82
		return "/some/path/" + localid; 
83
//		Hashtable<String, Object> ht = im.getDocumentInfo(localid);
84
//		if (ht.get("doctype").equals("BIN")) {
85
//			return dataPath + FileUtil.getFS() + localid;
86
//		} else {
87
//			return metadataPath + FileUtil.getFS() + localid;
88
//		}		
65
	private String pathToDocid(String localid) throws McdbDocNotFoundException  
66
	{	
67
		Hashtable<String, Object> ht = im.getDocumentInfo(localid);
68
		if (ht.get("doctype").equals("BIN")) {
69
			return dataPath + FileUtil.getFS() + localid;
70
		} else {
71
			return metadataPath + FileUtil.getFS() + localid;
72
		}		
89 73
	}
90 74

  
91 75
	
......
98 82
	@Override
99 83
	public String load(Identifier key) 
100 84
	{
101
		if (hasDataStore) {
102
			String docid = null;
103
			String path = null;
104
//			try {
105
//				docid = im.getLocalId(key.getValue());
106
//				path = pathToDocid(docid);			
107
//			} catch (McdbDocNotFoundException e) {
108
//				// TODO Auto-generated catch block
109
//				e.printStackTrace();
110
//				return null;
111
//			}
112
			path = "/path/" + key.getValue();
113
			return path;
114
		} else {
85

  
86
		String docid = null;
87
		String path = null;
88
		try {
89
			docid = im.getLocalId(key.getValue());
90
			path = pathToDocid(docid);			
91
		} catch (McdbDocNotFoundException e) {
92
			// TODO Auto-generated catch block
93
			e.printStackTrace();
115 94
			return null;
116 95
		}
96
		return path;
117 97
	}
118 98
	
119 99
	
......
125 105
	@Override
126 106
	public Map<Identifier, String> loadAll(Collection<Identifier> identifiers) {
127 107
		
128
		if (hasDataStore) {
129
			Hashtable<Identifier,String> map = new Hashtable<Identifier,String>();
130
			for (Identifier id : identifiers) {
131
				map.put(id, "/path/" + id.getValue());
132
//				try {
133
//					String docid = im.getLocalId(id.getValue());
134
//					map.put(id, pathToDocid(docid));
135
//
136
//				} catch (McdbDocNotFoundException e) {
137
//					// TODO should the map load an empty path instead of
138
//					// leaving out the entire entry?
139
//					e.printStackTrace();
140
//				}
108
		
109
		Hashtable<Identifier,String> map = new Hashtable<Identifier,String>();
110
		for (Identifier id : identifiers) {
111
			try {
112
				String docid = im.getLocalId(id.getValue());
113
				map.put(id, pathToDocid(docid));
114

  
115
			} catch (McdbDocNotFoundException e) {
116
				// TODO should the map load an empty path instead of
117
				// leaving out the entire entry?
118
				e.printStackTrace();
141 119
			}
142
			return map;
143
		} else {
144
			return null;
145 120
		}
121
		return map;
146 122
	}
147 123

  
148 124
	
......
150 126
	 * Return the full set of guids in the local metacat repository as
151 127
	 * dataone Identifiers.
152 128
	 * 
153
	 * (Hazelcast allows avoiding pre-loading by returning NULL, so consider
154
	 * re-implementing if that serves the purpose of this class better)
129
	 * (Hazelcast allows avoiding pre-loading by returning NULL, so will
130
	 * do this to avoid pre-loading a very long list unnecessarily)
155 131
	 */
156 132
	@Override
157
	public Set<Identifier> loadAllKeys() {
158

  
159
		if (hasDataStore) {
160
			//		List<String> guids = im.getAllGUIDs();
161
			//		
162
			Set<Identifier> set = Collections.synchronizedSet(new HashSet<Identifier>());
163
			//		for (String guid : guids) {
164
			//			Identifier id = new Identifier();
165
			//			id.setValue(guid);
166
			//			set.add(id);
167
			//		}
168

  
169
			for (int i=1; i< 100; i++) {
170
				Identifier id = new Identifier();
171
				id.setValue("testID." + i);
172
				set.add(id);
173
			}
174
			return set;
175
		} else {
176
			return null;
177
		}
133
	public Set<Identifier> loadAllKeys() 
134
	{
135
		return null;
136
		
137
//		List<String> guids = im.getAllGUIDs();
138
//
139
//		Set<Identifier> set = Collections.synchronizedSet(new HashSet<Identifier>());
140
//		for (String guid : guids) {
141
//			Identifier id = new Identifier();
142
//			id.setValue(guid);
143
//			set.add(id);
144
//		}
145
//		return set;
178 146
	}
179 147
}

Also available in: Unified diff