]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
2c05547e59efa2b8de42de6d57a7e576fba59172
[tmp/jakarta-migration.git] /
1 /**
2  * This document is a part of the source code and related artifacts
3  * for CollectionSpace, an open source collections management system
4  * for museums and related institutions:
5  *
6  * http://www.collectionspace.org
7  * http://wiki.collectionspace.org
8  *
9  * Copyright © 2009 Regents of the University of California
10  *
11  * Licensed under the Educational Community License (ECL), Version 2.0.
12  * You may not use this file except in compliance with this License.
13  *
14  * You may obtain a copy of the ECL 2.0 License at
15  * https://source.collectionspace.org/collection-space/LICENSE.txt
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 package org.collectionspace.services.client.test;
24
25 import java.util.List;
26 import javax.ws.rs.core.MediaType;
27 import javax.ws.rs.core.Response;
28
29 import org.collectionspace.services.client.CollectionObjectClient;
30 import org.collectionspace.services.collectionobject.CollectionobjectsCommon;
31 import org.collectionspace.services.collectionobject.domain.naturalhistory.CollectionObjectNaturalhistory;
32 import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
33 import org.collectionspace.services.collectionobject.OtherNumberList;
34 import org.jboss.resteasy.client.ClientResponse;
35
36 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
37 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
38 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
39 import org.testng.Assert;
40 import org.testng.annotations.Test;
41
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 /**
46  * CollectionObjectServiceTest, carries out tests against a
47  * deployed and running CollectionObject Service.
48  * 
49  * $LastChangedRevision$
50  * $LastChangedDate$
51  */
52 public class CollectionObjectServiceTest extends AbstractServiceTest {
53
54     private final Logger logger =
55             LoggerFactory.getLogger(CollectionObjectServiceTest.class);
56     // Instance variables specific to this test.
57     private CollectionObjectClient client = new CollectionObjectClient();
58     private String knownResourceId = null;
59
60     /*
61      * This method is called only by the parent class, AbstractServiceTest
62      */
63     @Override
64     protected String getServicePathComponent() {
65         return client.getServicePathComponent();
66     }
67
68     // ---------------------------------------------------------------
69     // CRUD tests : CREATE tests
70     // ---------------------------------------------------------------
71     // Success outcomes
72     @Override
73     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class)
74     public void create(String testName) throws Exception {
75
76         // Perform setup, such as initializing the type of service request
77         // (e.g. CREATE, DELETE), its valid and expected status codes, and
78         // its associated HTTP method name (e.g. POST, DELETE).
79         setupCreate(testName);
80
81         // Submit the request to the service and store the response.
82         String identifier = createIdentifier();
83         MultipartOutput multipart =
84                 createCollectionObjectInstance(client.getCommonPartName(), identifier);
85         ClientResponse<Response> res = client.create(multipart);
86         int statusCode = res.getStatus();
87
88         // Check the status code of the response: does it match
89         // the expected response(s)?
90         //
91         // Specifically:
92         // Does it fall within the set of valid status codes?
93         // Does it exactly match the expected status code?
94         if (logger.isDebugEnabled()) {
95             logger.debug(testName + ": status = " + statusCode);
96         }
97         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
98                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
99         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
100
101         // Store the ID returned from this create operation
102         // for additional tests below.
103         knownResourceId = extractId(res);
104         if (logger.isDebugEnabled()) {
105             logger.debug(testName + ": knownResourceId=" + knownResourceId);
106         }
107     }
108
109     /* (non-Javadoc)
110      * @see org.collectionspace.services.client.test.ServiceTest#createList()
111      */
112     @Override
113     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
114     dependsOnMethods = {"create"})
115     public void createList(String testName) throws Exception {
116         for (int i = 0; i < 3; i++) {
117             create(testName);
118         }
119     }
120
121     // Failure outcomes
122     // Placeholders until the three tests below can be uncommented.
123     // See Issue CSPACE-401.
124     @Override
125     public void createWithEmptyEntityBody(String testName) throws Exception {
126     }
127
128     @Override
129     public void createWithMalformedXml(String testName) throws Exception {
130     }
131
132     @Override
133     public void createWithWrongXmlSchema(String testName) throws Exception {
134     }
135
136
137     /*
138     @Override
139     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
140     dependsOnMethods = {"create", "testSubmitRequest"})
141     public void createWithEmptyEntityBody(String testName) throwsException {
142     
143     // Perform setup.
144     setupCreateWithEmptyEntityBody(testName);
145
146     // Submit the request to the service and store the response.
147     String method = REQUEST_TYPE.httpMethodName();
148     String url = getServiceRootURL();
149     String mediaType = MediaType.APPLICATION_XML;
150     final String entity = "";
151     int statusCode = submitRequest(method, url, mediaType, entity);
152
153     // Check the status code of the response: does it match
154     // the expected response(s)?
155     if(logger.isDebugEnabled()){
156     logger.debug(testName + ": url=" + url +
157     " status=" + statusCode);
158     }
159     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
160     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
161     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
162     }
163
164     @Override
165     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
166     dependsOnMethods = {"create", "testSubmitRequest"})
167     public void createWithMalformedXml(String testName) throws Exception {
168     
169     // Perform setup.
170     setupCreateWithMalformedXml(testName);
171
172     // Submit the request to the service and store the response.
173     String method = REQUEST_TYPE.httpMethodName();
174     String url = getServiceRootURL();
175     String mediaType = MediaType.APPLICATION_XML;
176     final String entity = MALFORMED_XML_DATA; // Constant from base class.
177     int statusCode = submitRequest(method, url, mediaType, entity);
178
179     // Check the status code of the response: does it match
180     // the expected response(s)?
181     if(logger.isDebugEnabled()){
182     logger.debug(testName + ": url=" + url +
183     " status=" + statusCode);
184     }
185     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
186     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
187     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
188     }
189
190     @Override
191     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
192     dependsOnMethods = {"create", "testSubmitRequest"})
193     public void createWithWrongXmlSchema(String testName) throws Exception {
194     
195     // Perform setup.
196     setupCreateWithWrongXmlSchema(testName);
197
198     // Submit the request to the service and store the response.
199     String method = REQUEST_TYPE.httpMethodName();
200     String url = getServiceRootURL();
201     String mediaType = MediaType.APPLICATION_XML;
202     final String entity = WRONG_XML_SCHEMA_DATA;
203     int statusCode = submitRequest(method, url, mediaType, entity);
204
205     // Check the status code of the response: does it match
206     // the expected response(s)?
207     if(logger.isDebugEnabled()){
208     logger.debug(testName + ": url=" + url +
209     " status=" + statusCode);
210     }
211     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
212     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
213     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
214     }
215      */
216     // ---------------------------------------------------------------
217     // CRUD tests : READ tests
218     // ---------------------------------------------------------------
219     // Success outcomes
220     @Override
221     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
222     dependsOnMethods = {"create"})
223     public void read(String testName) throws Exception {
224
225         // Perform setup.
226         setupRead(testName);
227
228         // Submit the request to the service and store the response.
229         ClientResponse<MultipartInput> res = client.read(knownResourceId);
230         int statusCode = res.getStatus();
231
232         // Check the status code of the response: does it match
233         // the expected response(s)?
234         if (logger.isDebugEnabled()) {
235             logger.debug(testName + ": status = " + statusCode);
236         }
237         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
238                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
239         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
240
241         MultipartInput input = (MultipartInput) res.getEntity();
242         CollectionobjectsCommon collectionObject =
243                 (CollectionobjectsCommon) extractPart(input,
244                 client.getCommonPartName(), CollectionobjectsCommon.class);
245         Assert.assertNotNull(collectionObject);
246     }
247
248     // Failure outcomes
249     @Override
250     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
251     dependsOnMethods = {"read"})
252     public void readNonExistent(String testName) throws Exception {
253
254         // Perform setup.
255         setupReadNonExistent(testName);
256
257         // Submit the request to the service and store the response.
258         ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
259         int statusCode = res.getStatus();
260
261         // Check the status code of the response: does it match
262         // the expected response(s)?
263         if (logger.isDebugEnabled()) {
264             logger.debug(testName + ": status = " + statusCode);
265         }
266         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
267                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
268         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
269     }
270
271     // ---------------------------------------------------------------
272     // CRUD tests : READ_LIST tests
273     // ---------------------------------------------------------------
274     // Success outcomes
275     @Override
276     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
277     dependsOnMethods = {"createList", "read"})
278     public void readList(String testName) throws Exception {
279
280         // Perform setup.
281         setupReadList(testName);
282
283         // Submit the request to the service and store the response.
284         ClientResponse<CollectionobjectsCommonList> res = client.readList();
285         CollectionobjectsCommonList list = res.getEntity();
286         int statusCode = res.getStatus();
287
288         // Check the status code of the response: does it match
289         // the expected response(s)?
290         if (logger.isDebugEnabled()) {
291             logger.debug(testName + ": status = " + statusCode);
292         }
293         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
294                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
295         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
296
297         // Optionally output additional data about list members for debugging.
298         boolean iterateThroughList = false;
299         if (iterateThroughList && logger.isDebugEnabled()) {
300             List<CollectionobjectsCommonList.CollectionObjectListItem> items =
301                     list.getCollectionObjectListItem();
302             int i = 0;
303
304             for (CollectionobjectsCommonList.CollectionObjectListItem item : items) {
305                 logger.debug(testName + ": list-item[" + i + "] csid=" +
306                         item.getCsid());
307                 logger.debug(testName + ": list-item[" + i + "] objectNumber=" +
308                         item.getObjectNumber());
309                 logger.debug(testName + ": list-item[" + i + "] URI=" +
310                         item.getUri());
311                 i++;
312
313             }
314         }
315     }
316
317     // Failure outcomes
318     // None at present.
319     // ---------------------------------------------------------------
320     // CRUD tests : UPDATE tests
321     // ---------------------------------------------------------------
322     // Success outcomes
323     @Override
324     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
325     dependsOnMethods = {"read"})
326     public void update(String testName) throws Exception {
327
328         // Perform setup.
329         setupUpdate(testName);
330
331         ClientResponse<MultipartInput> res =
332                 client.read(knownResourceId);
333         if (logger.isDebugEnabled()) {
334             logger.debug(testName + ": read status = " + res.getStatus());
335         }
336         Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
337
338         if (logger.isDebugEnabled()) {
339             logger.debug("got object to update with ID: " + knownResourceId);
340         }
341         MultipartInput input = (MultipartInput) res.getEntity();
342         CollectionobjectsCommon collectionObject =
343                 (CollectionobjectsCommon) extractPart(input,
344                 client.getCommonPartName(), CollectionobjectsCommon.class);
345         Assert.assertNotNull(collectionObject);
346
347         // Update the content of this resource.
348         collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
349         collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
350         if (logger.isDebugEnabled()) {
351             verbose("updated object", collectionObject,
352                     CollectionobjectsCommon.class);
353         }
354         // Submit the request to the service and store the response.
355         MultipartOutput output = new MultipartOutput();
356         OutputPart commonPart = output.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
357         commonPart.getHeaders().add("label", client.getCommonPartName());
358
359         res = client.update(knownResourceId, output);
360         int statusCode = res.getStatus();
361         // Check the status code of the response: does it match the expected response(s)?
362         if (logger.isDebugEnabled()) {
363             logger.debug(testName + ": status = " + statusCode);
364         }
365         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
366                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
367         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
368
369
370         input = (MultipartInput) res.getEntity();
371         CollectionobjectsCommon updatedCollectionObject =
372                 (CollectionobjectsCommon) extractPart(input,
373                 client.getCommonPartName(), CollectionobjectsCommon.class);
374         Assert.assertNotNull(updatedCollectionObject);
375
376         Assert.assertEquals(updatedCollectionObject.getObjectName(),
377                 collectionObject.getObjectName(),
378                 "Data in updated object did not match submitted data.");
379
380     }
381
382     // Failure outcomes
383     // Placeholders until the three tests below can be uncommented.
384     // See Issue CSPACE-401.
385     @Override
386     public void updateWithEmptyEntityBody(String testName) throws Exception {
387     }
388
389     @Override
390     public void updateWithMalformedXml(String testName) throws Exception {
391     }
392
393     @Override
394     public void updateWithWrongXmlSchema(String testName) throws Exception {
395     }
396
397     /*
398     @Override
399     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
400     dependsOnMethods = {"create", "update", "testSubmitRequest"})
401     public void updateWithEmptyEntityBody(String testName) throws Exception {
402     
403     // Perform setup.
404     setupUpdateWithEmptyEntityBody(testName);
405
406     // Submit the request to the service and store the response.
407     String method = REQUEST_TYPE.httpMethodName();
408     String url = getResourceURL(knownResourceId);
409     String mediaType = MediaType.APPLICATION_XML;
410     final String entity = "";
411     int statusCode = submitRequest(method, url, mediaType, entity);
412
413     // Check the status code of the response: does it match
414     // the expected response(s)?
415     if(logger.isDebugEnabled()){
416     logger.debug(testName + ": url=" + url +
417     " status=" + statusCode);
418     }
419     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
420     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
421     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
422     }
423
424     @Override
425     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
426     dependsOnMethods = {"create", "update", "testSubmitRequest"})
427     public void updateWithMalformedXml() throws Exception {
428
429     // Perform setup.
430     setupUpdateWithMalformedXml(testName);
431
432     // Submit the request to the service and store the response.
433     String method = REQUEST_TYPE.httpMethodName();
434     String url = getResourceURL(knownResourceId);
435     final String entity = MALFORMED_XML_DATA;
436     String mediaType = MediaType.APPLICATION_XML;
437     int statusCode = submitRequest(method, url, mediaType, entity);
438
439     // Check the status code of the response: does it match
440     // the expected response(s)?
441     if(logger.isDebugEnabled()){
442     logger.debug(testName + ": url=" + url +
443     " status=" + statusCode);
444     }
445     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
446     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
447     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
448     }
449
450     @Override
451     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
452     dependsOnMethods = {"create", "update", "testSubmitRequest"})
453     public void updateWithWrongXmlSchema(String testName) throws Exception {
454     
455     // Perform setup.
456     setupUpdateWithWrongXmlSchema(String testName);
457
458     // Submit the request to the service and store the response.
459     String method = REQUEST_TYPE.httpMethodName();
460     String url = getResourceURL(knownResourceId);
461     String mediaType = MediaType.APPLICATION_XML;
462     final String entity = WRONG_XML_SCHEMA_DATA;
463     int statusCode = submitRequest(method, url, mediaType, entity);
464
465     // Check the status code of the response: does it match
466     // the expected response(s)?
467     if(logger.isDebugEnabled()){
468     logger.debug(testName + ": url=" + url +
469     " status=" + statusCode);
470     }
471     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
472     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
473     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
474     }
475      */
476     @Override
477     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
478     dependsOnMethods = {"update", "testSubmitRequest"})
479     public void updateNonExistent(String testName) throws Exception {
480
481         // Perform setup.
482         setupUpdateNonExistent(testName);
483
484         // Submit the request to the service and store the response.
485         //
486         // Note: The ID used in this 'create' call may be arbitrary.
487         // The only relevant ID may be the one used in updateCollectionObject(), below.
488         MultipartOutput multipart =
489                 createCollectionObjectInstance(client.getCommonPartName(),
490                 NON_EXISTENT_ID);
491         ClientResponse<MultipartInput> res =
492                 client.update(NON_EXISTENT_ID, multipart);
493         int statusCode = res.getStatus();
494
495         // Check the status code of the response: does it match
496         // the expected response(s)?
497         if (logger.isDebugEnabled()) {
498             logger.debug(testName + ": status = " + statusCode);
499         }
500         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
501                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
502         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
503     }
504
505     // ---------------------------------------------------------------
506     // CRUD tests : DELETE tests
507     // ---------------------------------------------------------------
508     // Success outcomes
509     @Override
510     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
511     dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
512     public void delete(String testName) throws Exception {
513
514         // Perform setup.
515         setupDelete(testName);
516
517         // Submit the request to the service and store the response.
518         ClientResponse<Response> res = client.delete(knownResourceId);
519         int statusCode = res.getStatus();
520
521         // Check the status code of the response: does it match
522         // the expected response(s)?
523         if (logger.isDebugEnabled()) {
524             logger.debug(testName + ": status = " + statusCode);
525         }
526         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
527                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
528         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
529     }
530
531     // Failure outcomes
532     @Override
533     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
534     dependsOnMethods = {"delete"})
535     public void deleteNonExistent(String testName) throws Exception {
536
537         // Perform setup.
538         setupDeleteNonExistent(testName);
539
540         // Submit the request to the service and store the response.
541         ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
542         int statusCode = res.getStatus();
543
544         // Check the status code of the response: does it match
545         // the expected response(s)?
546         if (logger.isDebugEnabled()) {
547             logger.debug(testName + ": status = " + statusCode);
548         }
549         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
550                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
551         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
552     }
553
554     // ---------------------------------------------------------------
555     // Utility tests : tests of code used in tests above
556     // ---------------------------------------------------------------
557     /**
558      * Tests the code for manually submitting data that is used by several
559      * of the methods above.
560      */
561     @Test(dependsOnMethods = {"create", "read"})
562     public void testSubmitRequest() throws Exception {
563
564         // Expected status code: 200 OK
565         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
566
567         // Submit the request to the service and store the response.
568         String method = ServiceRequestType.READ.httpMethodName();
569         String url = getResourceURL(knownResourceId);
570         int statusCode = submitRequest(method, url);
571
572         // Check the status code of the response: does it match
573         // the expected response(s)?
574         if (logger.isDebugEnabled()) {
575             logger.debug("testSubmitRequest: url=" + url +
576                     " status=" + statusCode);
577         }
578         Assert.assertEquals(statusCode, EXPECTED_STATUS);
579
580     }
581
582     // ---------------------------------------------------------------
583     // Utility methods used by tests above
584     // ---------------------------------------------------------------
585     private MultipartOutput createCollectionObjectInstance(String commonPartName,
586             String identifier) {
587         return createCollectionObjectInstance(commonPartName,
588                 "objectNumber-" + identifier,
589                 "objectName-" + identifier);
590     }
591
592     private MultipartOutput createCollectionObjectInstance(String commonPartName,
593             String objectNumber, String objectName) {
594         CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
595         OtherNumberList onList = new OtherNumberList();
596         List<String> ons = onList.getOtherNumber();
597         ons.add("urn:org.collectionspace.id:24082390");
598         ons.add("urn:org.walkerart.id:123");
599         collectionObject.setOtherNumbers(onList);
600         collectionObject.setObjectNumber(objectNumber);
601         collectionObject.setObjectName(objectName);
602         collectionObject.setAge(""); //test for null string
603         collectionObject.setBriefDescription("Papier mache bird mask with horns, " +
604                 "painted red with black and yellow spots. " +
605                 "Puerto Rico. ca. 8&quot; high, 6&quot; wide, projects 10&quot; (with horns).");
606         MultipartOutput multipart = new MultipartOutput();
607         OutputPart commonPart = multipart.addPart(collectionObject,
608                 MediaType.APPLICATION_XML_TYPE);
609         commonPart.getHeaders().add("label", commonPartName);
610
611         if (logger.isDebugEnabled()) {
612             verbose("to be created, collectionobject common ",
613                     collectionObject, CollectionobjectsCommon.class);
614         }
615
616         CollectionObjectNaturalhistory conh = new CollectionObjectNaturalhistory();
617         conh.setNhString("test-string");
618         conh.setNhInt(999);
619         conh.setNhLong(9999);
620         OutputPart nhPart = multipart.addPart(conh, MediaType.APPLICATION_XML_TYPE);
621         nhPart.getHeaders().add("label", getNHPartName());
622
623         if (logger.isDebugEnabled()) {
624             verbose("to be created, collectionobject nhistory",
625                     conh, CollectionObjectNaturalhistory.class);
626         }
627         return multipart;
628
629     }
630
631     private String getNHPartName() {
632         return "collectionobjects-naturalhistory";
633     }
634 }