1 | package clarin.cmdi.componentregistry.rest; |
---|
2 | |
---|
3 | import clarin.cmdi.componentregistry.impl.database.ComponentRegistryTestDatabase; |
---|
4 | import clarin.cmdi.componentregistry.model.AbstractDescription; |
---|
5 | import static clarin.cmdi.componentregistry.rest.ComponentRegistryRestService.USERSPACE_PARAM; |
---|
6 | import static org.junit.Assert.assertEquals; |
---|
7 | import static org.junit.Assert.fail; |
---|
8 | |
---|
9 | import java.io.InputStream; |
---|
10 | import java.util.ArrayList; |
---|
11 | import java.util.Arrays; |
---|
12 | import java.util.List; |
---|
13 | |
---|
14 | import javax.ws.rs.core.MediaType; |
---|
15 | |
---|
16 | import org.junit.Before; |
---|
17 | import org.junit.Test; |
---|
18 | import org.junit.runner.RunWith; |
---|
19 | |
---|
20 | import clarin.cmdi.componentregistry.model.ComponentDescription; |
---|
21 | import clarin.cmdi.componentregistry.model.ProfileDescription; |
---|
22 | import clarin.cmdi.componentregistry.model.RegisterResponse; |
---|
23 | |
---|
24 | import com.sun.jersey.api.client.ClientResponse; |
---|
25 | import com.sun.jersey.multipart.FormDataMultiPart; |
---|
26 | import java.util.Collections; |
---|
27 | import java.util.Comparator; |
---|
28 | import org.slf4j.Logger; |
---|
29 | import org.slf4j.LoggerFactory; |
---|
30 | import org.springframework.beans.factory.annotation.Autowired; |
---|
31 | import org.springframework.jdbc.core.JdbcTemplate; |
---|
32 | import org.springframework.test.context.ContextConfiguration; |
---|
33 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; |
---|
34 | |
---|
35 | @RunWith(SpringJUnit4ClassRunner.class) |
---|
36 | @ContextConfiguration(locations = { "/applicationContext.xml" }) |
---|
37 | public class ConcurrentRestServiceTest extends ComponentRegistryRestServiceTestCase { |
---|
38 | |
---|
39 | private final static Logger LOG = LoggerFactory.getLogger(ConcurrentRestServiceTest.class); |
---|
40 | private int NR_OF_PROFILES = 50; |
---|
41 | private int NR_OF_COMPONENTS = 50; |
---|
42 | |
---|
43 | @Autowired |
---|
44 | private JdbcTemplate jdbcTemplate; |
---|
45 | |
---|
46 | @Before |
---|
47 | public void init() { |
---|
48 | ComponentRegistryTestDatabase.resetAndCreateAllTables(jdbcTemplate); |
---|
49 | createUserRecord(); |
---|
50 | } |
---|
51 | |
---|
52 | @Override |
---|
53 | protected String getApplicationContextFile() { |
---|
54 | return "classpath:applicationContext.xml"; |
---|
55 | } |
---|
56 | |
---|
57 | @Test |
---|
58 | public void testConcurrentRegisterProfile() throws Exception { |
---|
59 | List<String> errors = new ArrayList(); |
---|
60 | List<Thread> ts = new ArrayList<Thread>(); |
---|
61 | |
---|
62 | registerProfiles(ts, NR_OF_PROFILES, errors, "false"); |
---|
63 | registerProfiles(ts, NR_OF_PROFILES, errors, "true"); |
---|
64 | |
---|
65 | registerComponents(ts, NR_OF_COMPONENTS, errors, "false"); |
---|
66 | registerComponents(ts, NR_OF_COMPONENTS, errors, "true"); |
---|
67 | runAllThreads(ts); |
---|
68 | if (errors.size() > 0) { |
---|
69 | System.out.println(Arrays.toString(errors.toArray())); |
---|
70 | fail(); |
---|
71 | } |
---|
72 | assertProfiles(NR_OF_PROFILES, "false"); |
---|
73 | assertProfiles(NR_OF_PROFILES, "true"); |
---|
74 | |
---|
75 | assertComponents(NR_OF_COMPONENTS, "false"); |
---|
76 | assertComponents(NR_OF_COMPONENTS, "true"); |
---|
77 | } |
---|
78 | |
---|
79 | private void assertProfiles(int nrOfProfiles, String userSpace) { |
---|
80 | List<ProfileDescription> response = getAuthenticatedResource( |
---|
81 | getResource().path("/registry/profiles").queryParam(USERSPACE_PARAM, userSpace)). |
---|
82 | accept(MediaType.APPLICATION_XML).get( |
---|
83 | PROFILE_LIST_GENERICTYPE); |
---|
84 | Collections.sort(response, descriptionComparator); |
---|
85 | assertEquals("half should be deleted", nrOfProfiles / 2, response.size()); |
---|
86 | for (int i = 0; i < nrOfProfiles / 2; i++) { |
---|
87 | ProfileDescription desc = response.get(i); |
---|
88 | assertEquals("Test Profile" + (i * 2 + 1000), desc.getName()); |
---|
89 | assertEquals("Test Profile" + (i * 2 + 1000) + " Description", desc.getDescription()); |
---|
90 | } |
---|
91 | } |
---|
92 | private Comparator<AbstractDescription> descriptionComparator = new Comparator<AbstractDescription>() { |
---|
93 | |
---|
94 | @Override |
---|
95 | public int compare(AbstractDescription o1, AbstractDescription o2) { |
---|
96 | return o1.getName().compareTo(o2.getName()); |
---|
97 | } |
---|
98 | }; |
---|
99 | |
---|
100 | private void assertComponents(int nrOfComponents, String userSpace) { |
---|
101 | List<ComponentDescription> cResponse = getAuthenticatedResource( |
---|
102 | getResource().path("/registry/components").queryParam(USERSPACE_PARAM, userSpace)). |
---|
103 | accept(MediaType.APPLICATION_XML).get( |
---|
104 | COMPONENT_LIST_GENERICTYPE); |
---|
105 | Collections.sort(cResponse, descriptionComparator); |
---|
106 | assertEquals("half should be deleted", nrOfComponents / 2, cResponse.size()); |
---|
107 | for (int i = 0; i < nrOfComponents / 2; i++) { |
---|
108 | ComponentDescription desc = cResponse.get(i); |
---|
109 | assertEquals("Test Component" + (i * 2 + 1000), desc.getName()); |
---|
110 | assertEquals("Test Component" + (i * 2 + 1000) + " Description", desc.getDescription()); |
---|
111 | } |
---|
112 | } |
---|
113 | |
---|
114 | private void runAllThreads(List<Thread> ts) throws InterruptedException { |
---|
115 | for (Thread thread : ts) { |
---|
116 | thread.start(); |
---|
117 | thread.join(10); |
---|
118 | } |
---|
119 | for (Thread thread : ts) { |
---|
120 | thread.join(); //Wait till all are finished |
---|
121 | } |
---|
122 | } |
---|
123 | |
---|
124 | private void registerProfiles(List<Thread> ts, int size, final List<String> errors, String userSpace) throws InterruptedException { |
---|
125 | for (int i = 0; i < size; i++) { |
---|
126 | final boolean shouldDelete = (i % 2) == 1; |
---|
127 | Thread thread = createThread("/registry/profiles/", userSpace, "Test Profile" + (i + 1000), shouldDelete, RegistryTestHelper.getTestProfileContent(), errors); |
---|
128 | ts.add(thread); |
---|
129 | } |
---|
130 | } |
---|
131 | |
---|
132 | private void registerComponents(List<Thread> ts, int size, final List<String> errors, String userSpace) throws InterruptedException { |
---|
133 | for (int i = 0; i < size; i++) { |
---|
134 | final boolean shouldDelete = (i % 2) == 1; |
---|
135 | Thread thread = createThread("/registry/components/", userSpace, "Test Component" + (i + 1000), shouldDelete, |
---|
136 | RegistryTestHelper.getComponentTestContent(), errors); |
---|
137 | ts.add(thread); |
---|
138 | } |
---|
139 | } |
---|
140 | |
---|
141 | private Thread createThread(final String path, final String userSpace, final String name, final boolean alsoDelete, |
---|
142 | InputStream content, final List<String> errors) throws InterruptedException { |
---|
143 | final FormDataMultiPart form = new FormDataMultiPart(); |
---|
144 | form.field(ComponentRegistryRestService.DATA_FORM_FIELD, content, MediaType.APPLICATION_OCTET_STREAM_TYPE); |
---|
145 | form.field(ComponentRegistryRestService.NAME_FORM_FIELD, name); |
---|
146 | form.field(ComponentRegistryRestService.DESCRIPTION_FORM_FIELD, name + " Description"); |
---|
147 | Thread t = new Thread(new Runnable() { |
---|
148 | |
---|
149 | @Override |
---|
150 | public void run() { |
---|
151 | // System.out.println("THREAD STARTED"+Thread.currentThread().getName()); |
---|
152 | RegisterResponse registerResponse = getAuthenticatedResource( |
---|
153 | getResource().path(path).queryParam(USERSPACE_PARAM, userSpace)). |
---|
154 | type(MediaType.MULTIPART_FORM_DATA).post( |
---|
155 | RegisterResponse.class, form); |
---|
156 | if (!registerResponse.isRegistered()) { |
---|
157 | errors.add("Failed to register " + Arrays.toString(registerResponse.getErrors().toArray())); |
---|
158 | } |
---|
159 | LOG.debug(">>>>>>>>>>>>>>>> [Thread " + hashCode() + "] REGISTERING DESCRIPTION " + name + " " + registerResponse.getDescription().getId() + (Boolean.valueOf(userSpace) ? " userspace" : "") + (alsoDelete ? " alsoDelete" : "")); |
---|
160 | if (alsoDelete) { |
---|
161 | LOG.debug(">>>>>>>>>>>>>>>> [Thread " + hashCode() + "] DELETING DESCRIPTION " + name + " " + registerResponse.getDescription().getId() + (Boolean.valueOf(userSpace) ? " userspace " : "") + (alsoDelete ? " alsoDelete" : "")); |
---|
162 | ClientResponse response = getAuthenticatedResource( |
---|
163 | getResource().path(path + registerResponse.getDescription().getId()).queryParam(USERSPACE_PARAM, userSpace)). |
---|
164 | delete(ClientResponse.class); |
---|
165 | if (response.getStatus() != 200) { |
---|
166 | errors.add("Failed to delete " + registerResponse.getDescription()); |
---|
167 | } |
---|
168 | } |
---|
169 | // System.out.println("THREAD FINISHED"+Thread.currentThread().getName()); |
---|
170 | } |
---|
171 | }); |
---|
172 | return t; |
---|
173 | |
---|
174 | } |
---|
175 | } |
---|