/** * 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.camel.component.olingo2; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.olingo2.api.batch.Olingo2BatchChangeRequest; import org.apache.camel.component.olingo2.api.batch.Olingo2BatchQueryRequest; import org.apache.camel.component.olingo2.api.batch.Olingo2BatchRequest; import org.apache.camel.component.olingo2.api.batch.Olingo2BatchResponse; import org.apache.camel.component.olingo2.api.batch.Operation; import org.apache.camel.component.olingo2.api.impl.Olingo2AppImpl; import org.apache.camel.component.olingo2.api.impl.SystemQueryOption; import org.apache.camel.component.olingo2.internal.Olingo2Constants; import org.apache.camel.test.AvailablePortFinder; import org.apache.olingo.odata2.api.commons.HttpStatusCodes; import org.apache.olingo.odata2.api.edm.Edm; import org.apache.olingo.odata2.api.ep.entry.ODataEntry; import org.apache.olingo.odata2.api.ep.feed.ODataFeed; import org.apache.olingo.odata2.api.servicedocument.ServiceDocument; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Test class for {@link org.apache.camel.component.olingo2.api.Olingo2App} APIs. * <p> * The integration test runs against Apache Olingo 2.0 sample server * which is dynamically installed and started during the test. * </p> */ public class Olingo2ComponentTest extends AbstractOlingo2TestSupport { private static final Logger LOG = LoggerFactory.getLogger(Olingo2ComponentTest.class); private static final int PORT = AvailablePortFinder.getNextAvailable(); private static final String ID_PROPERTY = "Id"; private static final String MANUFACTURERS = "Manufacturers"; private static final String TEST_MANUFACTURER = "Manufacturers('1')"; private static final String CARS = "Cars"; private static final String TEST_RESOURCE_CONTENT_ID = "1"; private static final String ADDRESS = "Address"; private static final String TEST_RESOURCE = "$1"; private static final String TEST_RESOURCE_ADDRESS = TEST_RESOURCE + "/Address"; private static final String TEST_CREATE_MANUFACTURER = "DefaultContainer.Manufacturers('123')"; private static final String TEST_SERVICE_URL = "http://localhost:" + PORT + "/MyFormula.svc"; private static Olingo2SampleServer server; public Olingo2ComponentTest() { setDefaultTestProperty("serviceUri", "http://localhost:" + PORT + "/MyFormula.svc"); } @BeforeClass public static void beforeClass() throws Exception { startServers(PORT); Olingo2SampleServer.generateSampleData(TEST_SERVICE_URL); } @AfterClass public static void afterClass() throws Exception { if (server != null) { server.stop(); server.destroy(); } } protected static void startServers(int port) throws Exception { server = new Olingo2SampleServer(port, "/olingo2_ref"); server.start(); } @Test public void testRead() throws Exception { final Map<String, Object> headers = new HashMap<String, Object>(); // read ServiceDocument final ServiceDocument document = requestBodyAndHeaders("direct://READSERVICEDOC", null, headers); assertNotNull(document); assertFalse("ServiceDocument entity sets", document.getEntitySetsInfo().isEmpty()); LOG.info("Service document has {} entity sets", document.getEntitySetsInfo().size()); // parameter type is java.util.Map final HashMap<String, String> queryParams = new HashMap<String, String>(); queryParams.put(SystemQueryOption.$top.name(), "5"); headers.put("CamelOlingo2.queryParams", queryParams); // read ODataFeed final ODataFeed manufacturers = requestBodyAndHeaders("direct://READFEED", null, headers); assertNotNull(manufacturers); final List<ODataEntry> manufacturersEntries = manufacturers.getEntries(); assertFalse("Manufacturers empty entries", manufacturersEntries.isEmpty()); LOG.info("Manufacturers feed has {} entries", manufacturersEntries.size()); // read ODataEntry headers.clear(); headers.put(Olingo2Constants.PROPERTY_PREFIX + "keyPredicate", "'1'"); final ODataEntry manufacturer = requestBodyAndHeaders("direct://READENTRY", null, headers); assertNotNull(manufacturer); final Map<String, Object> properties = manufacturer.getProperties(); assertEquals("Manufacturer Id", "1", properties.get(ID_PROPERTY)); LOG.info("Manufacturer: {}", properties.toString()); } @Test public void testCreateUpdateDelete() throws Exception { final Map<String, Object> data = getEntityData(); Map<String, Object> address; final ODataEntry manufacturer = requestBody("direct://CREATE", data); assertNotNull("Created Manufacturer", manufacturer); final Map<String, Object> properties = manufacturer.getProperties(); assertEquals("Created Manufacturer Id", "123", properties.get(ID_PROPERTY)); LOG.info("Created Manufacturer: {}", properties); // update data.put("Name", "MyCarManufacturer Renamed"); address = (Map<String, Object>)data.get("Address"); address.put("Street", "Main Street"); HttpStatusCodes status = requestBody("direct://UPDATE", data); assertNotNull("Update status", status); assertEquals("Update status", HttpStatusCodes.NO_CONTENT.getStatusCode(), status.getStatusCode()); LOG.info("Update status: {}", status); // delete status = requestBody("direct://DELETE", null); assertNotNull("Delete status", status); assertEquals("Delete status", HttpStatusCodes.NO_CONTENT.getStatusCode(), status.getStatusCode()); LOG.info("Delete status: {}", status); } private Map<String, Object> getEntityData() { final Map<String, Object> data = new HashMap<String, Object>(); data.put("Id", "123"); data.put("Name", "MyCarManufacturer"); data.put("Founded", new Date()); Map<String, Object> address = new HashMap<String, Object>(); address.put("Street", "Main"); address.put("ZipCode", "42421"); address.put("City", "Fairy City"); address.put("Country", "FarFarAway"); data.put("Address", address); return data; } @Test public void testBatch() throws Exception { final List<Olingo2BatchRequest> batchParts = new ArrayList<Olingo2BatchRequest>(); // 1. Edm query batchParts.add(Olingo2BatchQueryRequest.resourcePath(Olingo2AppImpl.METADATA).build()); // 2. feed query batchParts.add(Olingo2BatchQueryRequest.resourcePath(MANUFACTURERS).build()); // 3. read batchParts.add(Olingo2BatchQueryRequest.resourcePath(TEST_MANUFACTURER).build()); // 4. read with expand final HashMap<String, String> queryParams = new HashMap<String, String>(); queryParams.put(SystemQueryOption.$expand.toString(), CARS); batchParts.add(Olingo2BatchQueryRequest.resourcePath(TEST_MANUFACTURER).queryParams(queryParams).build()); // 5. create final Map<String, Object> data = getEntityData(); batchParts.add(Olingo2BatchChangeRequest.resourcePath(MANUFACTURERS). contentId(TEST_RESOURCE_CONTENT_ID).operation(Operation.CREATE).body(data).build()); // 6. update address in created entry final Map<String, Object> updateData = new HashMap<String, Object>(data); Map<String, Object> address = (Map<String, Object>) updateData.get(ADDRESS); address.put("Street", "Main Street"); batchParts.add( Olingo2BatchChangeRequest.resourcePath(TEST_RESOURCE_ADDRESS).operation(Operation.UPDATE).body(address).build()); // 7. update updateData.put("Name", "MyCarManufacturer Renamed"); batchParts.add(Olingo2BatchChangeRequest.resourcePath(TEST_RESOURCE).operation(Operation.UPDATE) .body(updateData).build()); // 8. delete batchParts.add(Olingo2BatchChangeRequest.resourcePath(TEST_RESOURCE).operation(Operation.DELETE).build()); // 9. read to verify delete batchParts.add(Olingo2BatchQueryRequest.resourcePath(TEST_CREATE_MANUFACTURER).build()); // execute batch request final List<Olingo2BatchResponse> responseParts = requestBody("direct://BATCH", batchParts); assertNotNull("Batch response", responseParts); assertEquals("Batch responses expected", 9, responseParts.size()); final Edm edm = (Edm) responseParts.get(0).getBody(); assertNotNull(edm); LOG.info("Edm entity sets: {}", edm.getEntitySets()); final ODataFeed feed = (ODataFeed) responseParts.get(1).getBody(); assertNotNull(feed); LOG.info("Read feed: {}", feed.getEntries()); ODataEntry dataEntry = (ODataEntry) responseParts.get(2).getBody(); assertNotNull(dataEntry); LOG.info("Read entry: {}", dataEntry.getProperties()); dataEntry = (ODataEntry) responseParts.get(3).getBody(); assertNotNull(dataEntry); LOG.info("Read entry with $expand: {}", dataEntry.getProperties()); dataEntry = (ODataEntry) responseParts.get(4).getBody(); assertNotNull(dataEntry); LOG.info("Created entry: {}", dataEntry.getProperties()); int statusCode = responseParts.get(5).getStatusCode(); assertEquals(HttpStatusCodes.NO_CONTENT.getStatusCode(), statusCode); LOG.info("Update address status: {}", statusCode); statusCode = responseParts.get(6).getStatusCode(); assertEquals(HttpStatusCodes.NO_CONTENT.getStatusCode(), statusCode); LOG.info("Update entry status: {}", statusCode); statusCode = responseParts.get(7).getStatusCode(); assertEquals(HttpStatusCodes.NO_CONTENT.getStatusCode(), statusCode); LOG.info("Delete status: {}", statusCode); assertEquals(HttpStatusCodes.NOT_FOUND.getStatusCode(), responseParts.get(8).getStatusCode()); final Exception exception = (Exception) responseParts.get(8).getBody(); assertNotNull(exception); LOG.info("Read deleted entry exception: {}", exception); } @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { public void configure() { // test routes for read from("direct://READSERVICEDOC") .to("olingo2://read/"); from("direct://READFEED") .to("olingo2://read/Manufacturers?$orderBy=Name%20asc"); from("direct://READENTRY") .to("olingo2://read/DefaultContainer.Manufacturers"); // test route for create from("direct://CREATE") .to("olingo2://create/Manufacturers"); // test route for update from("direct://UPDATE") .to("olingo2://update/Manufacturers('123')"); // test route for delete from("direct://DELETE") .to("olingo2://delete/Manufacturers('123')"); /* // test route for merge from("direct://MERGE") .to("olingo2://merge"); // test route for patch from("direct://PATCH") .to("olingo2://patch"); */ // test route for batch from("direct://BATCH") .to("olingo2://batch"); } }; } }