source: ComponentRegistry/trunk/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/ConcurrentRestServiceTest.java @ 4098

Last change on this file since 4098 was 4098, checked in by George.Georgovassilis@mpi.nl, 10 years ago

#360, #431, #432: JPA and unified component entities

File size: 7.7 KB
Line 
1package clarin.cmdi.componentregistry.rest;
2
3import clarin.cmdi.componentregistry.impl.database.ComponentRegistryTestDatabase;
4import clarin.cmdi.componentregistry.model.BaseDescription;
5import clarin.cmdi.componentregistry.model.ComponentDescription;
6import clarin.cmdi.componentregistry.model.ProfileDescription;
7import clarin.cmdi.componentregistry.model.RegisterResponse;
8
9import com.sun.jersey.api.client.ClientResponse;
10import com.sun.jersey.multipart.FormDataMultiPart;
11
12import java.io.InputStream;
13import java.util.ArrayList;
14import java.util.Arrays;
15import java.util.Collections;
16import java.util.Comparator;
17import java.util.List;
18
19import javax.ws.rs.core.MediaType;
20
21import org.junit.Before;
22import org.junit.BeforeClass;
23import org.junit.Test;
24import org.slf4j.Logger;
25import org.slf4j.LoggerFactory;
26import org.springframework.beans.factory.annotation.Autowired;
27import org.springframework.jdbc.core.JdbcTemplate;
28
29import static clarin.cmdi.componentregistry.rest.ComponentRegistryRestService.USERSPACE_PARAM;
30import static org.junit.Assert.*;
31
32/**
33 *
34 * @author george.georgovassilis@mpi.nl
35 *
36 */
37public class ConcurrentRestServiceTest extends
38        ComponentRegistryRestServiceTestCase {
39
40    private final static Logger LOG = LoggerFactory
41            .getLogger(ConcurrentRestServiceTest.class);
42    private final int NR_OF_PROFILES = 20;
43    private final int NR_OF_COMPONENTS = 20;
44   
45    @Autowired
46    private JdbcTemplate jdbcTemplate;
47
48   
49    @Before
50    public void init() {
51        ComponentRegistryTestDatabase.resetAndCreateAllTables(jdbcTemplate);
52        createUserRecord();
53    }
54
55    @Test
56    public void testConcurrentRegisterProfile() throws Exception {
57        List<String> errors = new ArrayList<String>();
58        List<Thread> ts = new ArrayList<Thread>();
59
60        registerProfiles(ts, NR_OF_PROFILES, errors, false);
61        registerProfiles(ts, NR_OF_PROFILES, errors, true);
62
63        registerComponents(ts, NR_OF_COMPONENTS, errors, false);
64        registerComponents(ts, NR_OF_COMPONENTS, errors, true);
65        runAllThreads(ts);
66        if (errors.size() > 0) {
67            System.out.println(Arrays.toString(errors.toArray()));
68            for (String e : errors)
69                System.err.println(e);
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, boolean userSpace) {
80        List<ProfileDescription> response = getAuthenticatedResource(
81                getResource().path("/registry/profiles").queryParam(
82                        USERSPACE_PARAM, "" + userSpace)).accept(
83                MediaType.APPLICATION_XML).get(PROFILE_LIST_GENERICTYPE);
84        Collections.sort(response, descriptionComparator);
85        assertEquals("half should be deleted", nrOfProfiles / 2,
86                response.size());
87        for (int i = 0; i < nrOfProfiles / 2; i++) {
88            ProfileDescription desc = response.get(i);
89            assertEquals("Test Profile" + (i * 2 + 1000), desc.getName());
90            assertEquals("Test Profile" + (i * 2 + 1000) + " Description",
91                    desc.getDescription());
92        }
93    }
94
95    private Comparator<BaseDescription> descriptionComparator = new Comparator<BaseDescription>() {
96
97        @Override
98        public int compare(BaseDescription o1, BaseDescription o2) {
99            return o1.getName().compareTo(o2.getName());
100        }
101    };
102
103    private void assertComponents(int nrOfComponents, boolean userSpace) {
104        List<ComponentDescription> cResponse = getAuthenticatedResource(
105                getResource().path("/registry/components").queryParam(
106                        USERSPACE_PARAM, "" + userSpace)).accept(
107                MediaType.APPLICATION_XML).get(COMPONENT_LIST_GENERICTYPE);
108        Collections.sort(cResponse, descriptionComparator);
109        assertEquals("half should be deleted", nrOfComponents / 2,
110                cResponse.size());
111        for (int i = 0; i < nrOfComponents / 2; i++) {
112            ComponentDescription desc = cResponse.get(i);
113            assertEquals("Test Component" + (i * 2 + 1000), desc.getName());
114            assertEquals("Test Component" + (i * 2 + 1000) + " Description",
115                    desc.getDescription());
116        }
117    }
118
119    private void runAllThreads(List<Thread> ts) throws InterruptedException {
120        for (Thread thread : ts) {
121            thread.start();
122            thread.join(10);
123        }
124        for (Thread thread : ts) {
125            thread.join(); // Wait till all are finished
126        }
127    }
128
129    private void registerProfiles(List<Thread> ts, int size,
130            final List<String> errors, boolean userSpace)
131            throws InterruptedException {
132        for (int i = 0; i < size; i++) {
133            final boolean shouldDelete = (i % 2) == 1;
134            LOG.debug("Profile {} should be registered in {} and {}",
135                    new Object[] { i + 1000,
136                            userSpace ? "user space" : "public space",
137                            shouldDelete ? "ALSO DELETED" : "not deleted" });
138            Thread thread = createThread("/registry/profiles/", userSpace,
139                    "Test Profile" + (i + 1000), shouldDelete,
140                    RegistryTestHelper.getTestProfileContent(), errors);
141            ts.add(thread);
142        }
143    }
144
145    private void registerComponents(List<Thread> ts, int size,
146            final List<String> errors, boolean userSpace)
147            throws InterruptedException {
148        for (int i = 0; i < size; i++) {
149            final boolean shouldDelete = (i % 2) == 1;
150            LOG.debug("Component {} should be registered in {} and {}",
151                    new Object[] { i + 1000,
152                            userSpace ? "user space" : "public space",
153                            shouldDelete ? "ALSO DELETED" : "not deleted" });
154            Thread thread = createThread("/registry/components/", userSpace,
155                    "Test Component" + (i + 1000), shouldDelete,
156                    RegistryTestHelper.getComponentTestContent(), errors);
157            ts.add(thread);
158        }
159    }
160
161    private Thread createThread(final String path, final boolean userSpace,
162            final String name, final boolean alsoDelete, InputStream content,
163            final List<String> errors) throws InterruptedException {
164        final FormDataMultiPart form = new FormDataMultiPart();
165        form.field(IComponentRegistryRestService.DATA_FORM_FIELD, content,
166                MediaType.APPLICATION_OCTET_STREAM_TYPE);
167        form.field(IComponentRegistryRestService.NAME_FORM_FIELD, name);
168        form.field(IComponentRegistryRestService.DESCRIPTION_FORM_FIELD, name
169                + " Description");
170        Thread t = new Thread(new Runnable() {
171
172            @Override
173            public void run() {
174                long timestamp=-System.currentTimeMillis();
175                try {
176                    // System.out.println("THREAD STARTED"+Thread.currentThread().getName());
177                    RegisterResponse registerResponse = getAuthenticatedResource(
178                            getResource().path(path).queryParam(
179                                    USERSPACE_PARAM, "" + userSpace)).type(
180                            MediaType.MULTIPART_FORM_DATA).post(
181                            RegisterResponse.class, form);
182                    if (!registerResponse.isRegistered()) {
183                        errors.add("Failed to register "
184                                + Arrays.toString(registerResponse.getErrors()
185                                        .toArray()));
186                    }
187                    LOG.debug(">>>>>>>>>>>>>>>> [Thread " + hashCode()
188                            + "] REGISTERING DESCRIPTION " + name + " "
189                            + registerResponse.getDescription().getId()
190                            + (Boolean.valueOf(userSpace) ? " userspace" : "")
191                            + (alsoDelete ? " alsoDelete" : ""));
192                    if (alsoDelete) {
193                        LOG.debug(">>>>>>>>>>>>>>>> [Thread "
194                                + hashCode()
195                                + "] DELETING DESCRIPTION "
196                                + name
197                                + " "
198                                + registerResponse.getDescription().getId()
199                                + (Boolean.valueOf(userSpace) ? " userspace "
200                                        : "")
201                                + (alsoDelete ? " alsoDelete" : ""));
202                        ClientResponse response = getAuthenticatedResource(
203                                getResource().path(
204                                        path
205                                                + registerResponse
206                                                        .getDescription()
207                                                        .getId()).queryParam(
208                                        USERSPACE_PARAM, "" + userSpace))
209                                .delete(ClientResponse.class);
210                        if (response.getStatus() != 200) {
211                            errors.add("Failed to delete "
212                                    + registerResponse.getDescription());
213                        }
214                    }
215                    // System.out.println("THREAD FINISHED"+Thread.currentThread().getName());
216                } finally {
217                    timestamp+=System.currentTimeMillis();
218                    LOG.info(Thread.currentThread().getName()+" duration: "+timestamp+" ms");
219                }
220            }
221        });
222        return t;
223
224    }
225}
Note: See TracBrowser for help on using the repository browser.