[OLINGO-564] Merge branch 'master' into OLINGO-564
This commit is contained in:
commit
3c0990910a
|
@ -0,0 +1,296 @@
|
||||||
|
/*
|
||||||
|
* 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.olingo.fit.tecsvc.client;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.apache.olingo.client.api.ODataClient;
|
||||||
|
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
||||||
|
import org.apache.olingo.client.api.communication.response.ODataInvokeResponse;
|
||||||
|
import org.apache.olingo.client.core.ODataClientFactory;
|
||||||
|
import org.apache.olingo.commons.api.domain.ODataCollectionValue;
|
||||||
|
import org.apache.olingo.commons.api.domain.ODataComplexValue;
|
||||||
|
import org.apache.olingo.commons.api.domain.ODataEntity;
|
||||||
|
import org.apache.olingo.commons.api.domain.ODataEntitySet;
|
||||||
|
import org.apache.olingo.commons.api.domain.ODataProperty;
|
||||||
|
import org.apache.olingo.commons.api.domain.ODataValue;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||||
|
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||||
|
import org.apache.olingo.fit.AbstractBaseTestITCase;
|
||||||
|
import org.apache.olingo.fit.tecsvc.TecSvcConst;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ActionImportITCase extends AbstractBaseTestITCase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void primitveAction() throws Exception {
|
||||||
|
URI actionURI =
|
||||||
|
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTString").build();
|
||||||
|
ODataInvokeResponse<ODataProperty> response =
|
||||||
|
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ODataProperty.class).execute();
|
||||||
|
assertEquals(200, response.getStatusCode());
|
||||||
|
assertEquals("UARTString string value", response.getBody().getPrimitiveValue().toValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void primitveActionInvalidParameters() throws Exception {
|
||||||
|
Map<String, ODataValue> parameters = new HashMap<String, ODataValue>();
|
||||||
|
parameters.put("Invalid", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt32(1));
|
||||||
|
URI actionURI =
|
||||||
|
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTString").build();
|
||||||
|
try {
|
||||||
|
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ODataProperty.class, parameters)
|
||||||
|
.execute();
|
||||||
|
fail("Expected an ODataClientErrorException");
|
||||||
|
} catch (ODataClientErrorException e) {
|
||||||
|
assertEquals(400, e.getStatusLine().getStatusCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void primitveCollectionAction() throws Exception {
|
||||||
|
URI actionURI =
|
||||||
|
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollStringTwoParam").build();
|
||||||
|
Map<String, ODataValue> parameters = new HashMap<String, ODataValue>();
|
||||||
|
parameters.put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 3));
|
||||||
|
parameters.put("ParameterDuration", getClient().getObjectFactory().newPrimitiveValueBuilder().setType(
|
||||||
|
EdmPrimitiveTypeKind.Duration).setValue(new BigDecimal(1)).build());
|
||||||
|
ODataInvokeResponse<ODataProperty> response =
|
||||||
|
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ODataProperty.class, parameters)
|
||||||
|
.execute();
|
||||||
|
assertEquals(200, response.getStatusCode());
|
||||||
|
ODataCollectionValue<ODataValue> valueArray = response.getBody().getCollectionValue();
|
||||||
|
assertEquals(3, valueArray.size());
|
||||||
|
Iterator<ODataValue> iterator = valueArray.iterator();
|
||||||
|
assertEquals("PT1S", iterator.next().asPrimitive().toValue());
|
||||||
|
assertEquals("PT2S", iterator.next().asPrimitive().toValue());
|
||||||
|
assertEquals("PT3S", iterator.next().asPrimitive().toValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void complexAction() throws Exception {
|
||||||
|
URI actionURI =
|
||||||
|
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCTTwoPrimParam").build();
|
||||||
|
Map<String, ODataValue> parameters = new HashMap<String, ODataValue>();
|
||||||
|
parameters.put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 3));
|
||||||
|
ODataInvokeResponse<ODataProperty> response =
|
||||||
|
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ODataProperty.class, parameters)
|
||||||
|
.execute();
|
||||||
|
assertEquals(200, response.getStatusCode());
|
||||||
|
ODataComplexValue complexValue = response.getBody().getComplexValue();
|
||||||
|
ODataProperty propInt16 = complexValue.get("PropertyInt16");
|
||||||
|
assertNotNull(propInt16);
|
||||||
|
assertEquals(3, propInt16.getPrimitiveValue().toValue());
|
||||||
|
ODataProperty propString = complexValue.get("PropertyString");
|
||||||
|
assertNotNull(propString);
|
||||||
|
assertEquals("UARTCTTwoPrimParam string value", propString.getPrimitiveValue().toValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void complexCollectionActionNoContent() throws Exception {
|
||||||
|
URI actionURI =
|
||||||
|
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollCTTwoPrimParam").build();
|
||||||
|
Map<String, ODataValue> parameters = new HashMap<String, ODataValue>();
|
||||||
|
parameters.put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 0));
|
||||||
|
ODataInvokeResponse<ODataProperty> response =
|
||||||
|
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ODataProperty.class, parameters)
|
||||||
|
.execute();
|
||||||
|
assertEquals(200, response.getStatusCode());
|
||||||
|
ODataCollectionValue<ODataValue> complexValueCollection = response.getBody().getCollectionValue();
|
||||||
|
assertEquals(0, complexValueCollection.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void complexCollectionActionSubContent() throws Exception {
|
||||||
|
URI actionURI =
|
||||||
|
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollCTTwoPrimParam").build();
|
||||||
|
Map<String, ODataValue> parameters = new HashMap<String, ODataValue>();
|
||||||
|
parameters.put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 1));
|
||||||
|
ODataInvokeResponse<ODataProperty> response =
|
||||||
|
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ODataProperty.class, parameters)
|
||||||
|
.execute();
|
||||||
|
assertEquals(200, response.getStatusCode());
|
||||||
|
ODataCollectionValue<ODataValue> complexValueCollection = response.getBody().getCollectionValue();
|
||||||
|
assertEquals(1, complexValueCollection.size());
|
||||||
|
Iterator<ODataValue> iterator = complexValueCollection.iterator();
|
||||||
|
|
||||||
|
ODataComplexValue next = iterator.next().asComplex();
|
||||||
|
assertEquals(16, next.get("PropertyInt16").getPrimitiveValue().toValue());
|
||||||
|
assertEquals("Test123", next.get("PropertyString").getPrimitiveValue().toValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void complexCollectionActionAllContent() throws Exception {
|
||||||
|
URI actionURI =
|
||||||
|
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollCTTwoPrimParam").build();
|
||||||
|
Map<String, ODataValue> parameters = new HashMap<String, ODataValue>();
|
||||||
|
parameters.put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 3));
|
||||||
|
ODataInvokeResponse<ODataProperty> response =
|
||||||
|
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ODataProperty.class, parameters)
|
||||||
|
.execute();
|
||||||
|
assertEquals(200, response.getStatusCode());
|
||||||
|
ODataCollectionValue<ODataValue> complexValueCollection = response.getBody().getCollectionValue();
|
||||||
|
assertEquals(3, complexValueCollection.size());
|
||||||
|
Iterator<ODataValue> iterator = complexValueCollection.iterator();
|
||||||
|
|
||||||
|
ODataComplexValue next = iterator.next().asComplex();
|
||||||
|
assertEquals(16, next.get("PropertyInt16").getPrimitiveValue().toValue());
|
||||||
|
assertEquals("Test123", next.get("PropertyString").getPrimitiveValue().toValue());
|
||||||
|
|
||||||
|
next = iterator.next().asComplex();
|
||||||
|
assertEquals(17, next.get("PropertyInt16").getPrimitiveValue().toValue());
|
||||||
|
assertEquals("Test456", next.get("PropertyString").getPrimitiveValue().toValue());
|
||||||
|
|
||||||
|
next = iterator.next().asComplex();
|
||||||
|
assertEquals(18, next.get("PropertyInt16").getPrimitiveValue().toValue());
|
||||||
|
assertEquals("Test678", next.get("PropertyString").getPrimitiveValue().toValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void entityActionETTwoKeyTwoPrim() throws Exception {
|
||||||
|
URI actionURI =
|
||||||
|
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTETTwoKeyTwoPrimParam").build();
|
||||||
|
Map<String, ODataValue> parameters = new HashMap<String, ODataValue>();
|
||||||
|
parameters
|
||||||
|
.put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) -365));
|
||||||
|
ODataInvokeResponse<ODataEntity> response =
|
||||||
|
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ODataEntity.class, parameters)
|
||||||
|
.execute();
|
||||||
|
assertEquals(200, response.getStatusCode());
|
||||||
|
ODataEntity entity = response.getBody();
|
||||||
|
ODataProperty propInt16 = entity.getProperty("PropertyInt16");
|
||||||
|
assertNotNull(propInt16);
|
||||||
|
assertEquals(-365, propInt16.getPrimitiveValue().toValue());
|
||||||
|
ODataProperty propString = entity.getProperty("PropertyString");
|
||||||
|
assertNotNull(propString);
|
||||||
|
assertEquals("Test String2", propString.getPrimitiveValue().toValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void entityCollectionActionETKeyNav() throws Exception {
|
||||||
|
URI actionURI =
|
||||||
|
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollETKeyNavParam").build();
|
||||||
|
Map<String, ODataValue> parameters = new HashMap<String, ODataValue>();
|
||||||
|
parameters
|
||||||
|
.put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 3));
|
||||||
|
ODataInvokeResponse<ODataEntitySet> response =
|
||||||
|
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ODataEntitySet.class, parameters)
|
||||||
|
.execute();
|
||||||
|
assertEquals(200, response.getStatusCode());
|
||||||
|
ODataEntitySet entitySet = response.getBody();
|
||||||
|
assertEquals(3, entitySet.getEntities().size());
|
||||||
|
Integer key = 1;
|
||||||
|
for (ODataEntity entity : entitySet.getEntities()) {
|
||||||
|
assertEquals(key, entity.getProperty("PropertyInt16").getPrimitiveValue().toValue());
|
||||||
|
key++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void entityCollectionActionETKeyNavEmptyCollection() throws Exception {
|
||||||
|
URI actionURI =
|
||||||
|
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollETKeyNavParam").build();
|
||||||
|
Map<String, ODataValue> parameters = new HashMap<String, ODataValue>();
|
||||||
|
parameters
|
||||||
|
.put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 0));
|
||||||
|
ODataInvokeResponse<ODataEntitySet> response =
|
||||||
|
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ODataEntitySet.class, parameters)
|
||||||
|
.execute();
|
||||||
|
assertEquals(200, response.getStatusCode());
|
||||||
|
ODataEntitySet entitySet = response.getBody();
|
||||||
|
assertEquals(0, entitySet.getEntities().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void entityCollectionActionETKeyNavNegativeParam() throws Exception {
|
||||||
|
URI actionURI =
|
||||||
|
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollETKeyNavParam").build();
|
||||||
|
Map<String, ODataValue> parameters = new HashMap<String, ODataValue>();
|
||||||
|
parameters
|
||||||
|
.put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) -10));
|
||||||
|
ODataInvokeResponse<ODataEntitySet> response =
|
||||||
|
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ODataEntitySet.class, parameters)
|
||||||
|
.execute();
|
||||||
|
assertEquals(200, response.getStatusCode());
|
||||||
|
ODataEntitySet entitySet = response.getBody();
|
||||||
|
assertEquals(0, entitySet.getEntities().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void entityCollectionActionETAllPrim() throws Exception {
|
||||||
|
URI actionURI =
|
||||||
|
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollESAllPrimParam").build();
|
||||||
|
Calendar time = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
||||||
|
time.clear();
|
||||||
|
time.set(Calendar.HOUR_OF_DAY, 3);
|
||||||
|
time.set(Calendar.MINUTE, 0);
|
||||||
|
time.set(Calendar.SECOND, 0);
|
||||||
|
Map<String, ODataValue> parameters = new HashMap<String, ODataValue>();
|
||||||
|
parameters
|
||||||
|
.put("ParameterTimeOfDay", getClient().getObjectFactory().newPrimitiveValueBuilder().setType(
|
||||||
|
EdmPrimitiveTypeKind.TimeOfDay).setValue(time).build());
|
||||||
|
ODataInvokeResponse<ODataEntitySet> response =
|
||||||
|
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ODataEntitySet.class, parameters)
|
||||||
|
.execute();
|
||||||
|
assertEquals(200, response.getStatusCode());
|
||||||
|
ODataEntitySet entitySet = response.getBody();
|
||||||
|
assertEquals(3, entitySet.getEntities().size());
|
||||||
|
Integer key = 1;
|
||||||
|
for (ODataEntity entity : entitySet.getEntities()) {
|
||||||
|
assertEquals(key, entity.getProperty("PropertyInt16").getPrimitiveValue().toValue());
|
||||||
|
key++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void entityActionETAllPrim() throws Exception {
|
||||||
|
URI actionURI =
|
||||||
|
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTESAllPrimParam").build();
|
||||||
|
Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
||||||
|
dateTime.clear();
|
||||||
|
dateTime.set(1012, 2, 0, 0, 0, 0);
|
||||||
|
Map<String, ODataValue> parameters = new HashMap<String, ODataValue>();
|
||||||
|
parameters
|
||||||
|
.put("ParameterDate", getClient().getObjectFactory().newPrimitiveValueBuilder().setType(
|
||||||
|
EdmPrimitiveTypeKind.Date).setValue(dateTime).build());
|
||||||
|
ODataInvokeResponse<ODataEntity> response =
|
||||||
|
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ODataEntity.class, parameters)
|
||||||
|
.execute();
|
||||||
|
// Check 201
|
||||||
|
assertEquals(201, response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ODataClient getClient() {
|
||||||
|
ODataClient odata = ODataClientFactory.getClient();
|
||||||
|
odata.getConfiguration().setDefaultPubFormat(ODataFormat.JSON_NO_METADATA);
|
||||||
|
return odata;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -37,6 +37,8 @@ public enum SegmentType {
|
||||||
COUNT("$count"),
|
COUNT("$count"),
|
||||||
BOUND_OPERATION,
|
BOUND_OPERATION,
|
||||||
UNBOUND_OPERATION,
|
UNBOUND_OPERATION,
|
||||||
|
BOUND_ACTION,
|
||||||
|
UNBOUND_ACTION,
|
||||||
METADATA("$metadata"),
|
METADATA("$metadata"),
|
||||||
BATCH("$batch"),
|
BATCH("$batch"),
|
||||||
LINKS("$links"),
|
LINKS("$links"),
|
||||||
|
|
|
@ -355,4 +355,12 @@ public interface URIBuilder {
|
||||||
* @see org.apache.olingo.client.api.uri.QueryOption#SELECT
|
* @see org.apache.olingo.client.api.uri.QueryOption#SELECT
|
||||||
*/
|
*/
|
||||||
URIBuilder expandWithSelect(String expandItem, String... selectItems);
|
URIBuilder expandWithSelect(String expandItem, String... selectItems);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends action segment to the URI.
|
||||||
|
*
|
||||||
|
* @param action Action name
|
||||||
|
* @return current URIBuilder instance
|
||||||
|
*/
|
||||||
|
URIBuilder appendActionCallSegment(String action);
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,6 +179,13 @@ public class URIBuilderImpl implements URIBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URIBuilder appendActionCallSegment(final String action) {
|
||||||
|
segments.add(new Segment(
|
||||||
|
segments.size() == 1 ? SegmentType.UNBOUND_ACTION : SegmentType.BOUND_ACTION, action));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URIBuilder appendOperationCallSegment(final String operation) {
|
public URIBuilder appendOperationCallSegment(final String operation) {
|
||||||
segments.add(new Segment(
|
segments.add(new Segment(
|
||||||
|
@ -266,7 +273,9 @@ public class URIBuilderImpl implements URIBuilder {
|
||||||
case BOUND_OPERATION:
|
case BOUND_OPERATION:
|
||||||
segmentsBuilder.append(getBoundOperationSeparator());
|
segmentsBuilder.append(getBoundOperationSeparator());
|
||||||
break;
|
break;
|
||||||
|
case BOUND_ACTION:
|
||||||
|
segmentsBuilder.append(getBoundOperationSeparator());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (segmentsBuilder.length() > 0 && segmentsBuilder.charAt(segmentsBuilder.length() - 1) != '/') {
|
if (segmentsBuilder.length() > 0 && segmentsBuilder.charAt(segmentsBuilder.length() - 1) != '/') {
|
||||||
segmentsBuilder.append('/');
|
segmentsBuilder.append('/');
|
||||||
|
|
|
@ -100,10 +100,10 @@ public class URIBuilderTest extends AbstractTest {
|
||||||
final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
|
final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
|
||||||
appendEntitySetSegment("Categories").appendKeySegment(1).
|
appendEntitySetSegment("Categories").appendKeySegment(1).
|
||||||
appendNavigationSegment("Products").appendNavigationSegment("Model").
|
appendNavigationSegment("Products").appendNavigationSegment("Model").
|
||||||
appendOperationCallSegment("AllOrders");
|
appendActionCallSegment("AllOrders");
|
||||||
|
|
||||||
assertEquals(new org.apache.http.client.utils.URIBuilder(
|
assertEquals(new org.apache.http.client.utils.URIBuilder(
|
||||||
SERVICE_ROOT + "/Categories(1)/Products/Model.AllOrders()").build(), uriBuilder.build());
|
SERVICE_ROOT + "/Categories(1)/Products/Model.AllOrders").build(), uriBuilder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -158,6 +158,7 @@ public class Entity extends Linked {
|
||||||
for (Property property : properties) {
|
for (Property property : properties) {
|
||||||
if (name.equals(property.getName())) {
|
if (name.equals(property.getName())) {
|
||||||
result = property;
|
result = property;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -235,21 +235,27 @@ public interface ServiceHandler extends Processor {
|
||||||
* During a batch operation, this method starts the transaction (if any) before any operation is handled
|
* During a batch operation, this method starts the transaction (if any) before any operation is handled
|
||||||
* by the service. No nested transactions.
|
* by the service. No nested transactions.
|
||||||
* @return must return a unique transaction id that references a atomic operation.
|
* @return must return a unique transaction id that references a atomic operation.
|
||||||
|
* @throws ODataTranslatedException
|
||||||
|
* @throws ODataApplicationException
|
||||||
*/
|
*/
|
||||||
String startTransaction();
|
String startTransaction() throws ODataTranslatedException, ODataApplicationException;;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When a batch operation is complete and all the intermediate service requests are successful, then
|
* When a batch operation is complete and all the intermediate service requests are successful, then
|
||||||
* commit is called with transaction id returned in the startTransaction method.
|
* commit is called with transaction id returned in the startTransaction method.
|
||||||
* @param txnId
|
* @param txnId
|
||||||
|
* @throws ODataTranslatedException
|
||||||
|
* @throws ODataApplicationException
|
||||||
*/
|
*/
|
||||||
void commit(String txnId);
|
void commit(String txnId) throws ODataTranslatedException, ODataApplicationException;;
|
||||||
/**
|
/**
|
||||||
* When a batch operation is in-complete due to an error in the middle of changeset, then rollback is
|
* When a batch operation is in-complete due to an error in the middle of changeset, then rollback is
|
||||||
* called with transaction id, that returned from startTransaction method.
|
* called with transaction id, that returned from startTransaction method.
|
||||||
* @param txnId
|
* @param txnId
|
||||||
|
* @throws ODataTranslatedException
|
||||||
|
* @throws ODataApplicationException
|
||||||
*/
|
*/
|
||||||
void rollback(String txnId);
|
void rollback(String txnId) throws ODataTranslatedException, ODataApplicationException;;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is not complete, more URL parsing changes required. Cross join between two entities.
|
* This is not complete, more URL parsing changes required. Cross join between two entities.
|
||||||
|
|
|
@ -77,12 +77,25 @@ public class BatchRequest extends ServiceRequest {
|
||||||
|
|
||||||
for (BatchRequestPart part : parts) {
|
for (BatchRequestPart part : parts) {
|
||||||
if (part.isChangeSet()) {
|
if (part.isChangeSet()) {
|
||||||
String txnId = handler.startTransaction();
|
String txnId = null;
|
||||||
partResponse = processChangeSet(part, handler);
|
try {
|
||||||
if (partResponse.getResponses().get(0).getStatusCode() > 400) {
|
txnId = handler.startTransaction();
|
||||||
handler.rollback(txnId);
|
partResponse = processChangeSet(part, handler);
|
||||||
|
if (partResponse.getResponses().get(0).getStatusCode() > 400) {
|
||||||
|
handler.rollback(txnId);
|
||||||
|
}
|
||||||
|
handler.commit(txnId);
|
||||||
|
} catch(ODataTranslatedException e) {
|
||||||
|
if (txnId != null) {
|
||||||
|
handler.rollback(txnId);
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
} catch (ODataApplicationException e) {
|
||||||
|
if (txnId != null) {
|
||||||
|
handler.rollback(txnId);
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
handler.commit(txnId);
|
|
||||||
} else {
|
} else {
|
||||||
// single request, a static request
|
// single request, a static request
|
||||||
ODataRequest partRequest = part.getRequests().get(0);
|
ODataRequest partRequest = part.getRequests().get(0);
|
||||||
|
|
|
@ -273,6 +273,11 @@ public class DataRequest extends ServiceRequest {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// in update, delete entity cases, predicate must be there
|
||||||
|
if ((isPATCH() || isPUT() || isDELETE())
|
||||||
|
&& (getKeyPredicates() == null || getKeyPredicates().isEmpty())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -630,6 +630,48 @@ public class TripPinDataModel {
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean updateEntity(EdmEntitySet edmEntitySet, String eTag, String key, Object keyValue,
|
||||||
|
boolean merge, Entity changes, String baseURL) throws ODataApplicationException {
|
||||||
|
boolean updated = false;
|
||||||
|
|
||||||
|
if (merge) {
|
||||||
|
EntityCollection set = getEntitySet(edmEntitySet.getName());
|
||||||
|
Iterator<Entity> it = set.getEntities().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Entity entity = it.next();
|
||||||
|
if (entity.getProperty(key).getValue().equals(keyValue) && eTag.equals("*")
|
||||||
|
|| eTag.equals(entity.getETag())) {
|
||||||
|
|
||||||
|
for (Property p :changes.getProperties()) {
|
||||||
|
for (Property p1: entity.getProperties()) {
|
||||||
|
if (p.getName().equals(p1.getName())) {
|
||||||
|
p1.setValue(p1.getValueType(), p.getValue());
|
||||||
|
updated = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// this is delete, then insert
|
||||||
|
EntityCollection set = getEntitySet(edmEntitySet.getName());
|
||||||
|
Iterator<Entity> it = set.getEntities().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Entity entity = it.next();
|
||||||
|
if (entity.getProperty(key).getValue().equals(keyValue) && eTag.equals("*")
|
||||||
|
|| eTag.equals(entity.getETag())) {
|
||||||
|
Property p = entity.getProperty(key);
|
||||||
|
changes.addProperty(p);
|
||||||
|
createEntity(edmEntitySet, changes, baseURL);
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean deleteEntity(String entitySetName, String eTag, String key, Object keyValue) {
|
public boolean deleteEntity(String entitySetName, String eTag, String key, Object keyValue) {
|
||||||
EntityCollection set = getEntitySet(entitySetName);
|
EntityCollection set = getEntitySet(entitySetName);
|
||||||
Iterator<Entity> it = set.getEntities().iterator();
|
Iterator<Entity> it = set.getEntities().iterator();
|
||||||
|
|
|
@ -273,9 +273,25 @@ public class TripPinHandler implements ServiceHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateEntity(DataRequest request, Entity entity, boolean merge, String entityETag,
|
public void updateEntity(DataRequest request, Entity entity, boolean merge, String eTag,
|
||||||
EntityResponse response) throws ODataTranslatedException, ODataApplicationException {
|
EntityResponse response) throws ODataTranslatedException, ODataApplicationException {
|
||||||
response.writeServerError(true);
|
EdmEntitySet edmEntitySet = request.getEntitySet();
|
||||||
|
|
||||||
|
Entity currentEntity = this.dataModel.getEntity(edmEntitySet.getName(), request.getKeyPredicates());
|
||||||
|
if (currentEntity == null) {
|
||||||
|
response.writeNotFound(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String key = edmEntitySet.getEntityType().getKeyPredicateNames().get(0);
|
||||||
|
String baseURL = request.getODataRequest().getRawBaseUri();
|
||||||
|
boolean updated = this.dataModel.updateEntity(edmEntitySet, eTag, key, currentEntity
|
||||||
|
.getProperty(key).getValue(), merge, entity, baseURL);
|
||||||
|
|
||||||
|
if (updated) {
|
||||||
|
response.writeUpdatedEntity();
|
||||||
|
} else {
|
||||||
|
response.writeNotModified();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.apache.http.HttpRequest;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.methods.HttpDelete;
|
import org.apache.http.client.methods.HttpDelete;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPatch;
|
||||||
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
import org.apache.http.client.methods.HttpPut;
|
import org.apache.http.client.methods.HttpPut;
|
||||||
import org.apache.http.entity.ByteArrayEntity;
|
import org.apache.http.entity.ByteArrayEntity;
|
||||||
|
@ -418,6 +419,32 @@ public class TripPinServiceTest {
|
||||||
EntityUtils.consumeQuietly(response.getEntity());
|
EntityUtils.consumeQuietly(response.getEntity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateEntity() throws Exception {
|
||||||
|
String payload = "{" +
|
||||||
|
" \"Emails\":[" +
|
||||||
|
" \"Krista@example.com\"," +
|
||||||
|
" \"Krista@gmail.com\"" +
|
||||||
|
" ]" +
|
||||||
|
"}";
|
||||||
|
HttpPatch updateRequest = new HttpPatch(baseURL+"/People('kristakemp')");
|
||||||
|
updateRequest.setEntity(new StringEntity(payload, ContentType.APPLICATION_JSON));
|
||||||
|
httpSend(updateRequest, 204);
|
||||||
|
|
||||||
|
HttpResponse response = httpGET(baseURL + "/People('kristakemp')", 200);
|
||||||
|
JsonNode node = getJSONNode(response);
|
||||||
|
assertEquals("$metadata#People/$entity", node.get("@odata.context").asText());
|
||||||
|
assertEquals("Krista@example.com", node.get("Emails").get(0).asText());
|
||||||
|
assertEquals("Krista@gmail.com", node.get("Emails").get(1).asText());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteEntity() throws Exception{
|
||||||
|
// fail because no key predicates supplied
|
||||||
|
HttpDelete deleteRequest = new HttpDelete(baseURL+"/People");
|
||||||
|
HttpResponse response = httpSend(deleteRequest, 405);
|
||||||
|
EntityUtils.consumeQuietly(response.getEntity());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateEntityWithLinkToRelatedEntities() throws Exception {
|
public void testCreateEntityWithLinkToRelatedEntities() throws Exception {
|
||||||
|
|
|
@ -195,6 +195,22 @@ public class ODataJsonDeserializer implements ODataDeserializer {
|
||||||
Map<String, Parameter> parameters = new LinkedHashMap<String, Parameter>();
|
Map<String, Parameter> parameters = new LinkedHashMap<String, Parameter>();
|
||||||
if (tree != null) {
|
if (tree != null) {
|
||||||
consumeParameters(edmAction, tree, parameters);
|
consumeParameters(edmAction, tree, parameters);
|
||||||
|
|
||||||
|
final List<String> toRemove = new ArrayList<String>();
|
||||||
|
Iterator<Entry<String, JsonNode>> fieldsIterator = tree.fields();
|
||||||
|
while (fieldsIterator.hasNext()) {
|
||||||
|
Map.Entry<String, JsonNode> field = fieldsIterator.next();
|
||||||
|
|
||||||
|
if (field.getKey().contains(ODATA_CONTROL_INFORMATION_PREFIX)) {
|
||||||
|
// Control Information is ignored for requests as per specification chapter "4.5 Control Information"
|
||||||
|
toRemove.add(field.getKey());
|
||||||
|
} else if (field.getKey().contains(ODATA_ANNOTATION_MARKER)) {
|
||||||
|
throw new DeserializerException("Custom annotation with field name: " + field.getKey() + " not supported",
|
||||||
|
DeserializerException.MessageKeys.NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// remove here to avoid iterator issues.
|
||||||
|
tree.remove(toRemove);
|
||||||
assertJsonNodeIsEmpty(tree);
|
assertJsonNodeIsEmpty(tree);
|
||||||
}
|
}
|
||||||
return DeserializerResultImpl.with().actionParameters(parameters).build();
|
return DeserializerResultImpl.with().actionParameters(parameters).build();
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.olingo.commons.api.data.ComplexValue;
|
||||||
import org.apache.olingo.commons.api.data.Entity;
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
import org.apache.olingo.commons.api.data.EntityCollection;
|
import org.apache.olingo.commons.api.data.EntityCollection;
|
||||||
import org.apache.olingo.commons.api.data.Parameter;
|
import org.apache.olingo.commons.api.data.Parameter;
|
||||||
|
@ -49,11 +50,17 @@ public class ActionData {
|
||||||
protected static Property primitiveCollectionAction(String name, Map<String, Parameter> parameters)
|
protected static Property primitiveCollectionAction(String name, Map<String, Parameter> parameters)
|
||||||
throws DataProviderException {
|
throws DataProviderException {
|
||||||
if ("UARTCollStringTwoParam".equals(name)) {
|
if ("UARTCollStringTwoParam".equals(name)) {
|
||||||
List<Object> collectionValues = new ArrayList<Object>();
|
Parameter paramInt16 = parameters.get("ParameterInt16");
|
||||||
int loopCount = (Integer) parameters.get("ParameterInt16").asPrimitive();
|
Parameter paramDuration = parameters.get("ParameterDuration");
|
||||||
|
if (paramInt16 == null || paramDuration == null) {
|
||||||
|
throw new DataProviderException("Missing parameters for action: UARTCollStringTwoParam",
|
||||||
|
HttpStatusCode.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
short loopCount = (Short) paramInt16.asPrimitive();
|
||||||
|
BigDecimal duration = (BigDecimal) paramDuration.asPrimitive();
|
||||||
EdmPrimitiveType primDuration = OData.newInstance().createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Duration);
|
EdmPrimitiveType primDuration = OData.newInstance().createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Duration);
|
||||||
BigDecimal duration = (BigDecimal) parameters.get("ParameterDuration").asPrimitive();
|
|
||||||
BigDecimal addValue = new BigDecimal(1);
|
BigDecimal addValue = new BigDecimal(1);
|
||||||
|
List<Object> collectionValues = new ArrayList<Object>();
|
||||||
for (int i = 0; i < loopCount; i++) {
|
for (int i = 0; i < loopCount; i++) {
|
||||||
try {
|
try {
|
||||||
String value = primDuration.valueToString(duration, false, null, null, null, null);
|
String value = primDuration.valueToString(duration, false, null, null, null, null);
|
||||||
|
@ -63,78 +70,92 @@ public class ActionData {
|
||||||
}
|
}
|
||||||
duration = duration.add(addValue);
|
duration = duration.add(addValue);
|
||||||
}
|
}
|
||||||
return DataCreator.createPrimitiveCollection(null, collectionValues);
|
return new Property(null, name, ValueType.COLLECTION_PRIMITIVE, collectionValues);
|
||||||
}
|
}
|
||||||
throw new DataProviderException("Action " + name + " is not yet implemented.");
|
throw new DataProviderException("Action " + name + " is not yet implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Property complexAction(String name, Map<String, Parameter> parameters) throws DataProviderException {
|
protected static Property complexAction(String name, Map<String, Parameter> parameters) throws DataProviderException {
|
||||||
if ("UARTCTTwoPrimParam".equals(name)) {
|
if ("UARTCTTwoPrimParam".equals(name)) {
|
||||||
Integer number = (Integer) parameters.get("ParameterInt16").asPrimitive();
|
Parameter paramInt16 = parameters.get("ParameterInt16");
|
||||||
if (number == null) {
|
Short number;
|
||||||
number = new Integer(32767);
|
if (paramInt16 == null) {
|
||||||
|
number = new Short((short) 32767);
|
||||||
|
} else {
|
||||||
|
number = (Short) paramInt16.asPrimitive();
|
||||||
}
|
}
|
||||||
Property complexProp = createCTTwoPrimComplexProperty(number, "UARTCTTwoPrimParam string value");
|
|
||||||
|
|
||||||
return complexProp;
|
return createCTTwoPrimComplexProperty(number, "UARTCTTwoPrimParam string value");
|
||||||
}
|
}
|
||||||
throw new DataProviderException("Action " + name + " is not yet implemented.");
|
throw new DataProviderException("Action " + name + " is not yet implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Property createCTTwoPrimComplexProperty(Integer number, String text) {
|
private static Property createCTTwoPrimComplexProperty(Short number, String text) {
|
||||||
List<Property> props = new ArrayList<Property>();
|
ComplexValue compValue = new ComplexValue();
|
||||||
Property propInt = new Property();
|
Property propInt = new Property();
|
||||||
propInt.setName("PropertyInt16");
|
propInt.setName("PropertyInt16");
|
||||||
propInt.setValue(ValueType.PRIMITIVE, number);
|
propInt.setValue(ValueType.PRIMITIVE, number);
|
||||||
props.add(propInt);
|
compValue.getValue().add(propInt);
|
||||||
Property propString = new Property();
|
Property propString = new Property();
|
||||||
propString.setName("PropertyString");
|
propString.setName("PropertyString");
|
||||||
propString.setValue(ValueType.PRIMITIVE, text);
|
propString.setValue(ValueType.PRIMITIVE, text);
|
||||||
props.add(propString);
|
compValue.getValue().add(propString);
|
||||||
|
|
||||||
Property complexProp = new Property();
|
Property complexProp = new Property();
|
||||||
complexProp.setValue(ValueType.COMPLEX, props);
|
complexProp.setValue(ValueType.COMPLEX, compValue);
|
||||||
return complexProp;
|
return complexProp;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Property complexCollectionAction(String name, Map<String, Parameter> parameters)
|
protected static Property complexCollectionAction(String name, Map<String, Parameter> parameters)
|
||||||
throws DataProviderException {
|
throws DataProviderException {
|
||||||
if ("UARTCollCTTwoPrimParam".equals(name)) {
|
if ("UARTCollCTTwoPrimParam".equals(name)) {
|
||||||
ArrayList<Property> complexCollection = new ArrayList<Property>();
|
List<ComplexValue> complexCollection = new ArrayList<ComplexValue>();
|
||||||
complexCollection.add(createCTTwoPrimComplexProperty(16, "Test123"));
|
complexCollection.add(createCTTwoPrimComplexProperty((short) 16, "Test123").asComplex());
|
||||||
complexCollection.add(createCTTwoPrimComplexProperty(17, "Test456"));
|
complexCollection.add(createCTTwoPrimComplexProperty((short) 17, "Test456").asComplex());
|
||||||
complexCollection.add(createCTTwoPrimComplexProperty(18, "Test678"));
|
complexCollection.add(createCTTwoPrimComplexProperty((short) 18, "Test678").asComplex());
|
||||||
|
|
||||||
Integer number = (Integer) parameters.get("ParameterInt16").asPrimitive();
|
Parameter paramInt16 = parameters.get("ParameterInt16");
|
||||||
if (number != null && number >= 0 && number < complexCollection.size()) {
|
if (paramInt16 != null) {
|
||||||
complexCollection.subList(number, complexCollection.size() - 1).clear();
|
Short number = (Short) paramInt16.asPrimitive();
|
||||||
|
if (number < 0) {
|
||||||
|
complexCollection.clear();
|
||||||
|
} else if (number >= 0 && number < complexCollection.size()) {
|
||||||
|
complexCollection = complexCollection.subList(0, number);
|
||||||
|
|
||||||
|
}
|
||||||
|
Property complexCollProperty = new Property();
|
||||||
|
complexCollProperty.setValue(ValueType.COLLECTION_COMPLEX, complexCollection);
|
||||||
|
return complexCollProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
Property complexCollProperty = new Property();
|
|
||||||
complexCollProperty.setValue(ValueType.COLLECTION_COMPLEX, complexCollection);
|
|
||||||
return complexCollProperty;
|
|
||||||
}
|
}
|
||||||
throw new DataProviderException("Action " + name + " is not yet implemented.");
|
throw new DataProviderException("Action " + name + " is not yet implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Entity entityAction(String name, Map<String, Parameter> parameters) throws DataProviderException {
|
protected static EntityActionResult entityAction(String name, Map<String, Parameter> parameters)
|
||||||
|
throws DataProviderException {
|
||||||
if ("UARTETTwoKeyTwoPrimParam".equals(name)) {
|
if ("UARTETTwoKeyTwoPrimParam".equals(name)) {
|
||||||
Integer number = (Integer) parameters.get("ParameterInt16").asPrimitive();
|
Parameter parameter = parameters.get("ParameterInt16");
|
||||||
if (number == null) {
|
Short number;
|
||||||
number = 0;
|
if (parameter != null) {
|
||||||
|
number = (Short) parameter.asPrimitive();
|
||||||
|
} else {
|
||||||
|
number = (short) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityCollection entityCollection = new DataCreator().getData().get("ESTwoKeyTwoPrim");
|
EntityCollection entityCollection = new DataCreator().getData().get("ESTwoKeyTwoPrim");
|
||||||
for (Entity entity : entityCollection.getEntities()) {
|
for (Entity entity : entityCollection.getEntities()) {
|
||||||
if (number.equals(entity.getProperty("PropertyInt16").asPrimitive())) {
|
Object asPrimitive = entity.getProperty("PropertyInt16").asPrimitive();
|
||||||
return entity;
|
if (number.equals(asPrimitive)) {
|
||||||
|
return new EntityActionResult().setEntity(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Entity Not found
|
// Entity Not found
|
||||||
throw new DataProviderException("Entity not found with key: " + number, HttpStatusCode.NOT_FOUND);
|
throw new DataProviderException("Entity not found with key: " + number, HttpStatusCode.NOT_FOUND);
|
||||||
} else if ("UARTETAllPrimParam".equals(name)) {
|
} else if ("UARTETAllPrimParam".equals(name)) {
|
||||||
Calendar date = (Calendar) parameters.get("ParameterDate").asPrimitive();
|
Parameter paramDate = parameters.get("ParameterDate");
|
||||||
EntityCollection entityCollection = new DataCreator().getData().get("ESAllPrim");
|
EntityCollection entityCollection = new DataCreator().getData().get("ESAllPrim");
|
||||||
if (date != null) {
|
if (paramDate != null) {
|
||||||
|
Calendar date = (Calendar) paramDate.asPrimitive();
|
||||||
boolean freeKey;
|
boolean freeKey;
|
||||||
Short key = 0;
|
Short key = 0;
|
||||||
do {
|
do {
|
||||||
|
@ -147,10 +168,10 @@ public class ActionData {
|
||||||
}
|
}
|
||||||
key++;
|
key++;
|
||||||
} while (!freeKey);
|
} while (!freeKey);
|
||||||
// TODO: Set create response code
|
return new EntityActionResult().setEntity(createAllPrimEntity(key, "UARTETAllPrimParam string value", date))
|
||||||
return createAllPrimEntity(key, "UARTETAllPrimParam string value", date);
|
.setCreated(true);
|
||||||
} else {
|
} else {
|
||||||
return entityCollection.getEntities().get(0);
|
return new EntityActionResult().setEntity(entityCollection.getEntities().get(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new DataProviderException("Action " + name + " is not yet implemented.");
|
throw new DataProviderException("Action " + name + " is not yet implemented.");
|
||||||
|
@ -178,26 +199,31 @@ public class ActionData {
|
||||||
protected static EntityCollection entityCollectionAction(String name, Map<String, Parameter> parameters)
|
protected static EntityCollection entityCollectionAction(String name, Map<String, Parameter> parameters)
|
||||||
throws DataProviderException {
|
throws DataProviderException {
|
||||||
if ("UARTCollETKeyNavParam".equals(name)) {
|
if ("UARTCollETKeyNavParam".equals(name)) {
|
||||||
Short number = (Short) parameters.get("ParameterInt16").asPrimitive();
|
Parameter paramInt16 = parameters.get("ParameterInt16");
|
||||||
EntityCollection collection = new EntityCollection();
|
Short number;
|
||||||
if (number != null && number > 0) {
|
if (paramInt16 == null) {
|
||||||
for (int i = 1; i <= number; i++) {
|
number = (short) 0;
|
||||||
collection.getEntities().add(createETKeyNavEntity(number));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return collection;
|
number = (Short) paramInt16.asPrimitive();
|
||||||
}
|
}
|
||||||
} else if ("UARTCollETAllPrimParam".equals(name)) {
|
|
||||||
Calendar timeOfDay = (Calendar) parameters.get("ParameterTimeOfDay").asPrimitive();
|
|
||||||
EntityCollection collection = new EntityCollection();
|
EntityCollection collection = new EntityCollection();
|
||||||
if (timeOfDay != null) {
|
if (number > 0) {
|
||||||
|
for (short i = 1; i <= number; i++) {
|
||||||
|
collection.getEntities().add(createETKeyNavEntity(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return collection;
|
||||||
|
} else if ("UARTCollETAllPrimParam".equals(name)) {
|
||||||
|
Parameter paramTimeOfDay = parameters.get("ParameterTimeOfDay");
|
||||||
|
EntityCollection collection = new EntityCollection();
|
||||||
|
if (paramTimeOfDay != null) {
|
||||||
|
Calendar timeOfDay = (Calendar) paramTimeOfDay.asPrimitive();
|
||||||
int count = timeOfDay.get(Calendar.HOUR_OF_DAY);
|
int count = timeOfDay.get(Calendar.HOUR_OF_DAY);
|
||||||
for (short i = 1; i <= count; i++) {
|
for (short i = 1; i <= count; i++) {
|
||||||
collection.getEntities().add(createAllPrimEntity(i, "UARTCollETAllPrimParam int16 value: " + i, null));
|
collection.getEntities().add(createAllPrimEntity(i, "UARTCollETAllPrimParam int16 value: " + i, null));
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
return collection;
|
return collection;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw new DataProviderException("Action " + name + " is not yet implemented.");
|
throw new DataProviderException("Action " + name + " is not yet implemented.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,13 +85,13 @@ public class DataCreator {
|
||||||
|
|
||||||
private EntityCollection createESTwoKeyTwoPrim() {
|
private EntityCollection createESTwoKeyTwoPrim() {
|
||||||
EntityCollection entitySet = new EntityCollection();
|
EntityCollection entitySet = new EntityCollection();
|
||||||
entitySet.getEntities().add(createETTwoKeyTwoPrimEntity(32767, "Test String1"));
|
entitySet.getEntities().add(createETTwoKeyTwoPrimEntity((short) 32767, "Test String1"));
|
||||||
entitySet.getEntities().add(createETKeyNavEntity(-365, "Test String2"));
|
entitySet.getEntities().add(createETTwoKeyTwoPrimEntity((short) -365, "Test String2"));
|
||||||
entitySet.getEntities().add(createETKeyNavEntity(-32766, "Test String3"));
|
entitySet.getEntities().add(createETTwoKeyTwoPrimEntity((short) -32766, "Test String3"));
|
||||||
return entitySet;
|
return entitySet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Entity createETTwoKeyTwoPrimEntity(int propertyInt16, String propertyString) {
|
private Entity createETTwoKeyTwoPrimEntity(short propertyInt16, String propertyString) {
|
||||||
return new Entity().addProperty(createPrimitive("PropertyInt16", propertyInt16))
|
return new Entity().addProperty(createPrimitive("PropertyInt16", propertyInt16))
|
||||||
.addProperty(createPrimitive("PropertyString", propertyString));
|
.addProperty(createPrimitive("PropertyString", propertyString));
|
||||||
}
|
}
|
||||||
|
@ -266,7 +266,7 @@ public class DataCreator {
|
||||||
.addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789dddfff")))
|
.addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789dddfff")))
|
||||||
.addProperty(createPrimitive("PropertyTimeOfDay", getTime(23, 49, 14))));
|
.addProperty(createPrimitive("PropertyTimeOfDay", getTime(23, 49, 14))));
|
||||||
|
|
||||||
entitySet.getEntities().add(new Entity().addProperty(createPrimitive("PropertyInt16", 0))
|
entitySet.getEntities().add(new Entity().addProperty(createPrimitive("PropertyInt16", (short) 0))
|
||||||
.addProperty(createPrimitive("PropertyString", "")).addProperty(createPrimitive("PropertyBoolean", false))
|
.addProperty(createPrimitive("PropertyString", "")).addProperty(createPrimitive("PropertyBoolean", false))
|
||||||
.addProperty(createPrimitive("PropertyByte", 0)).addProperty(createPrimitive("PropertySByte", 0))
|
.addProperty(createPrimitive("PropertyByte", 0)).addProperty(createPrimitive("PropertySByte", 0))
|
||||||
.addProperty(createPrimitive("PropertyInt32", 0)).addProperty(createPrimitive("PropertyInt64", 0))
|
.addProperty(createPrimitive("PropertyInt32", 0)).addProperty(createPrimitive("PropertyInt64", 0))
|
||||||
|
@ -600,7 +600,7 @@ public class DataCreator {
|
||||||
return new Property(null, name, ValueType.COLLECTION_COMPLEX, complexCollection);
|
return new Property(null, name, ValueType.COLLECTION_COMPLEX, complexCollection);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Calendar getDateTime(final int year, final int month, final int day,
|
protected static Calendar getDateTime(final int year, final int month, final int day,
|
||||||
final int hour, final int minute, final int second) {
|
final int hour, final int minute, final int second) {
|
||||||
Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
||||||
dateTime.clear();
|
dateTime.clear();
|
||||||
|
@ -608,7 +608,7 @@ public class DataCreator {
|
||||||
return dateTime;
|
return dateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Calendar getTime(final int hour, final int minute, final int second) {
|
protected static Calendar getTime(final int hour, final int minute, final int second) {
|
||||||
Calendar time = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
Calendar time = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
||||||
time.clear();
|
time.clear();
|
||||||
time.set(Calendar.HOUR_OF_DAY, hour);
|
time.set(Calendar.HOUR_OF_DAY, hour);
|
||||||
|
|
|
@ -495,11 +495,31 @@ public class DataProvider {
|
||||||
return ActionData.primitiveAction(name, actionParameters);
|
return ActionData.primitiveAction(name, actionParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Property processActionComplex(String name, Map<String, Parameter> actionParameters)
|
||||||
|
throws DataProviderException {
|
||||||
|
return ActionData.complexAction(name, actionParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Property processActionComplexCollection(String name, Map<String, Parameter> actionParameters)
|
||||||
|
throws DataProviderException {
|
||||||
|
return ActionData.complexCollectionAction(name, actionParameters);
|
||||||
|
}
|
||||||
|
|
||||||
public Property processActionPrimitiveCollection(String name, Map<String, Parameter> actionParameters)
|
public Property processActionPrimitiveCollection(String name, Map<String, Parameter> actionParameters)
|
||||||
throws DataProviderException {
|
throws DataProviderException {
|
||||||
return ActionData.primitiveCollectionAction(name, actionParameters);
|
return ActionData.primitiveCollectionAction(name, actionParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntityActionResult processActionEntity(String name, Map<String, Parameter> actionParameters)
|
||||||
|
throws DataProviderException {
|
||||||
|
return ActionData.entityAction(name, actionParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityCollection processActionEntityCollection(String name, Map<String, Parameter> actionParameters)
|
||||||
|
throws DataProviderException {
|
||||||
|
return ActionData.entityCollectionAction(name, actionParameters);
|
||||||
|
}
|
||||||
|
|
||||||
public void setEdm(final Edm edm) {
|
public void setEdm(final Edm edm) {
|
||||||
this.edm = edm;
|
this.edm = edm;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* 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.olingo.server.tecsvc.data;
|
||||||
|
|
||||||
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
|
|
||||||
|
public class EntityActionResult {
|
||||||
|
private Entity entity;
|
||||||
|
private boolean created = false;
|
||||||
|
|
||||||
|
public Entity getEntity() {
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
public EntityActionResult setEntity(Entity entity) {
|
||||||
|
this.entity = entity;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public boolean isCreated() {
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
public EntityActionResult setCreated(boolean created) {
|
||||||
|
this.created = created;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -6,9 +6,9 @@
|
||||||
* to you under the Apache License, Version 2.0 (the
|
* to you under the Apache License, Version 2.0 (the
|
||||||
* "License"); you may not use this file except in compliance
|
* "License"); you may not use this file except in compliance
|
||||||
* with the License. You may obtain a copy of the License at
|
* with the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing,
|
* Unless required by applicable law or agreed to in writing,
|
||||||
* software distributed under the License is distributed on an
|
* software distributed under the License is distributed on an
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
@ -52,6 +52,7 @@ import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions
|
||||||
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
|
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
|
||||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||||
|
import org.apache.olingo.server.api.serializer.SerializerResult;
|
||||||
import org.apache.olingo.server.api.uri.UriInfo;
|
import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceAction;
|
import org.apache.olingo.server.api.uri.UriResourceAction;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||||
|
@ -59,6 +60,7 @@ import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||||
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
||||||
|
import org.apache.olingo.server.tecsvc.data.EntityActionResult;
|
||||||
import org.apache.olingo.server.tecsvc.data.RequestValidator;
|
import org.apache.olingo.server.tecsvc.data.RequestValidator;
|
||||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.ExpandSystemQueryOptionHandler;
|
import org.apache.olingo.server.tecsvc.processor.queryoptions.ExpandSystemQueryOptionHandler;
|
||||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.CountHandler;
|
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.CountHandler;
|
||||||
|
@ -117,14 +119,14 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||||
ODataSerializer serializer = odata.createSerializer(format);
|
ODataSerializer serializer = odata.createSerializer(format);
|
||||||
final ExpandOption expand = uriInfo.getExpandOption();
|
final ExpandOption expand = uriInfo.getExpandOption();
|
||||||
final SelectOption select = uriInfo.getSelectOption();
|
final SelectOption select = uriInfo.getSelectOption();
|
||||||
|
|
||||||
// Transform the entity graph to a tree. The construction is controlled by the expand tree.
|
// Transform the entity graph to a tree. The construction is controlled by the expand tree.
|
||||||
// Apply all expand system query options to the tree.So the expanded navigation properties can be modified
|
// Apply all expand system query options to the tree.So the expanded navigation properties can be modified
|
||||||
// for serialization,without affecting the data stored in the database.
|
// for serialization,without affecting the data stored in the database.
|
||||||
final ExpandSystemQueryOptionHandler expandHandler = new ExpandSystemQueryOptionHandler();
|
final ExpandSystemQueryOptionHandler expandHandler = new ExpandSystemQueryOptionHandler();
|
||||||
final EntityCollection entitySetSerialization = expandHandler.transformEntitySetGraphToTree(entitySet,
|
final EntityCollection entitySetSerialization = expandHandler.transformEntitySetGraphToTree(entitySet,
|
||||||
edmEntitySet,
|
edmEntitySet,
|
||||||
expand);
|
expand);
|
||||||
expandHandler.applyExpandQueryOptions(entitySetSerialization, edmEntitySet, expand);
|
expandHandler.applyExpandQueryOptions(entitySetSerialization, edmEntitySet, expand);
|
||||||
|
|
||||||
// Serialize
|
// Serialize
|
||||||
|
@ -147,8 +149,32 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||||
public void processActionEntityCollection(final ODataRequest request, final ODataResponse response,
|
public void processActionEntityCollection(final ODataRequest request, final ODataResponse response,
|
||||||
final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat)
|
final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat)
|
||||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||||
throw new ODataApplicationException("Process entity collection is not supported yet.",
|
EdmAction action = checkBoundAndExtractAction(uriInfo);
|
||||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
DeserializerResult deserializerResult =
|
||||||
|
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||||
|
.actionParameters(request.getBody(), action);
|
||||||
|
|
||||||
|
EntityCollection collection =
|
||||||
|
dataProvider.processActionEntityCollection(action.getName(), deserializerResult.getActionParameters());
|
||||||
|
|
||||||
|
if (collection == null) {
|
||||||
|
// Collection Propertys must never be null
|
||||||
|
throw new ODataApplicationException("The action could no be executed", 500, Locale.ROOT);
|
||||||
|
} else if (collection.getEntities().contains(null) && !action.getReturnType().isNullable()) {
|
||||||
|
// Not nullable return type but array contains a null value
|
||||||
|
throw new ODataApplicationException("The action could no be executed", 500, Locale.ROOT);
|
||||||
|
}
|
||||||
|
EdmEntityType type = (EdmEntityType) action.getReturnType().getType();
|
||||||
|
ContextURL contextURL = ContextURL.with().type(type).asCollection().build();
|
||||||
|
EntityCollectionSerializerOptions options = EntityCollectionSerializerOptions.with().contextURL(contextURL).build();
|
||||||
|
|
||||||
|
SerializerResult result =
|
||||||
|
odata.createSerializer(ODataFormat.fromContentType(responseFormat))
|
||||||
|
.entityCollection(serviceMetadata, type, collection, options);
|
||||||
|
|
||||||
|
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||||
|
response.setContent(result.getContent());
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -230,7 +256,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||||
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
|
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
|
||||||
final EdmEntitySet edmEntitySet = resourceEntitySet.getEntitySet();
|
final EdmEntitySet edmEntitySet = resourceEntitySet.getEntitySet();
|
||||||
final EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
final EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||||
|
|
||||||
final Entity entity;
|
final Entity entity;
|
||||||
ExpandOption expand = null;
|
ExpandOption expand = null;
|
||||||
if (edmEntityType.hasStream()) { // called from createMediaEntity(...), not directly
|
if (edmEntityType.hasStream()) { // called from createMediaEntity(...), not directly
|
||||||
|
@ -238,14 +264,14 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||||
dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()),
|
dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()),
|
||||||
requestFormat.toContentTypeString());
|
requestFormat.toContentTypeString());
|
||||||
} else {
|
} else {
|
||||||
final DeserializerResult deserializerResult = odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
final DeserializerResult deserializerResult =
|
||||||
.entity(request.getBody(), edmEntityType);
|
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||||
new RequestValidator(dataProvider,
|
.entity(request.getBody(), edmEntityType);
|
||||||
odata.createUriHelper(),
|
new RequestValidator(dataProvider,
|
||||||
serviceMetadata.getEdm(),
|
odata.createUriHelper(),
|
||||||
request.getRawBaseUri()
|
serviceMetadata.getEdm(),
|
||||||
).validate(edmEntitySet, deserializerResult.getEntity());
|
request.getRawBaseUri()).validate(edmEntitySet, deserializerResult.getEntity());
|
||||||
|
|
||||||
entity = dataProvider.create(edmEntitySet);
|
entity = dataProvider.create(edmEntitySet);
|
||||||
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, deserializerResult.getEntity(), false, true);
|
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, deserializerResult.getEntity(), false, true);
|
||||||
expand = deserializerResult.getExpandTree();
|
expand = deserializerResult.getExpandTree();
|
||||||
|
@ -271,11 +297,11 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo);
|
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo);
|
||||||
Entity entity;
|
Entity entity;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
entity = readEntity(uriInfo);
|
entity = readEntity(uriInfo);
|
||||||
} catch(ODataApplicationException e) {
|
} catch (ODataApplicationException e) {
|
||||||
if(e.getStatusCode() == HttpStatusCode.NOT_FOUND.getStatusCode()) {
|
if (e.getStatusCode() == HttpStatusCode.NOT_FOUND.getStatusCode()) {
|
||||||
// Perform upsert
|
// Perform upsert
|
||||||
createEntity(request, response, uriInfo, requestFormat, responseFormat);
|
createEntity(request, response, uriInfo, requestFormat, responseFormat);
|
||||||
return;
|
return;
|
||||||
|
@ -286,15 +312,14 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||||
checkRequestFormat(requestFormat);
|
checkRequestFormat(requestFormat);
|
||||||
final ODataDeserializer deserializer = odata.createDeserializer(ODataFormat.fromContentType(requestFormat));
|
final ODataDeserializer deserializer = odata.createDeserializer(ODataFormat.fromContentType(requestFormat));
|
||||||
final Entity changedEntity = deserializer.entity(request.getBody(), edmEntitySet.getEntityType()).getEntity();
|
final Entity changedEntity = deserializer.entity(request.getBody(), edmEntitySet.getEntityType()).getEntity();
|
||||||
|
|
||||||
new RequestValidator(dataProvider,
|
new RequestValidator(dataProvider,
|
||||||
true, // Update
|
true, // Update
|
||||||
request.getMethod() == HttpMethod.PATCH,
|
request.getMethod() == HttpMethod.PATCH,
|
||||||
odata.createUriHelper(),
|
odata.createUriHelper(),
|
||||||
serviceMetadata.getEdm(),
|
serviceMetadata.getEdm(),
|
||||||
request.getRawBaseUri()
|
request.getRawBaseUri()).validate(edmEntitySet, changedEntity);
|
||||||
).validate(edmEntitySet, changedEntity);
|
|
||||||
|
|
||||||
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, changedEntity,
|
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, changedEntity,
|
||||||
request.getMethod() == HttpMethod.PATCH, false);
|
request.getMethod() == HttpMethod.PATCH, false);
|
||||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||||
|
@ -325,8 +350,36 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||||
public void processActionEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
public void processActionEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||||
final ContentType requestFormat, final ContentType responseFormat)
|
final ContentType requestFormat, final ContentType responseFormat)
|
||||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||||
throw new ODataApplicationException("Any action returning an entity is not supported yet.",
|
EdmAction action = checkBoundAndExtractAction(uriInfo);
|
||||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
DeserializerResult deserializerResult =
|
||||||
|
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||||
|
.actionParameters(request.getBody(), action);
|
||||||
|
|
||||||
|
EntityActionResult entityResult =
|
||||||
|
dataProvider.processActionEntity(action.getName(), deserializerResult.getActionParameters());
|
||||||
|
EdmEntityType type = (EdmEntityType) action.getReturnType().getType();
|
||||||
|
if (entityResult == null || entityResult.getEntity() == null) {
|
||||||
|
if (action.getReturnType().isNullable()) {
|
||||||
|
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||||
|
} else {
|
||||||
|
// Not nullable return type so we have to give back a 500
|
||||||
|
throw new ODataApplicationException("The action could no be executed", 500, Locale.ROOT);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ContextURL contextURL = ContextURL.with().type(type).build();
|
||||||
|
EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextURL).build();
|
||||||
|
|
||||||
|
SerializerResult result = odata.createSerializer(ODataFormat.fromContentType(responseFormat))
|
||||||
|
.entity(serviceMetadata, type, entityResult.getEntity(), options);
|
||||||
|
|
||||||
|
if(entityResult.isCreated()){
|
||||||
|
response.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
|
||||||
|
}else{
|
||||||
|
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||||
|
}
|
||||||
|
response.setContent(result.getContent());
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -68,7 +68,6 @@ import org.apache.olingo.server.api.uri.UriHelper;
|
||||||
import org.apache.olingo.server.api.uri.UriInfo;
|
import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
import org.apache.olingo.server.api.uri.UriInfoResource;
|
import org.apache.olingo.server.api.uri.UriInfoResource;
|
||||||
import org.apache.olingo.server.api.uri.UriResource;
|
import org.apache.olingo.server.api.uri.UriResource;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceAction;
|
|
||||||
import org.apache.olingo.server.api.uri.UriResourceFunction;
|
import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceKind;
|
import org.apache.olingo.server.api.uri.UriResourceKind;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceProperty;
|
import org.apache.olingo.server.api.uri.UriResourceProperty;
|
||||||
|
@ -121,7 +120,7 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
||||||
|
|
||||||
Property property = dataProvider.processActionPrimitive(action.getName(), deserializerResult.getActionParameters());
|
Property property = dataProvider.processActionPrimitive(action.getName(), deserializerResult.getActionParameters());
|
||||||
EdmPrimitiveType type = (EdmPrimitiveType) action.getReturnType().getType();
|
EdmPrimitiveType type = (EdmPrimitiveType) action.getReturnType().getType();
|
||||||
if (property.isNull()) {
|
if (property == null || property.isNull()) {
|
||||||
if (action.getReturnType().isNullable()) {
|
if (action.getReturnType().isNullable()) {
|
||||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||||
} else {
|
} else {
|
||||||
|
@ -141,18 +140,6 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private EdmAction checkBoundAndExtractAction(final UriInfo uriInfo) throws ODataApplicationException {
|
|
||||||
final UriInfoResource resource = uriInfo.asUriInfoResource();
|
|
||||||
List<UriResource> uriResourceParts = resource.getUriResourceParts();
|
|
||||||
if (uriResourceParts.size() > 1) {
|
|
||||||
throw new ODataApplicationException("Bound acctions not supported yet.",
|
|
||||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
|
||||||
}
|
|
||||||
UriResourceAction uriResourceAction = (UriResourceAction) uriResourceParts.get(0);
|
|
||||||
EdmAction action = uriResourceAction.getAction();
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readPrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
public void readPrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||||
|
@ -177,8 +164,32 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
||||||
public void processActionPrimitiveCollection(final ODataRequest request, final ODataResponse response,
|
public void processActionPrimitiveCollection(final ODataRequest request, final ODataResponse response,
|
||||||
final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat)
|
final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat)
|
||||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||||
throw new ODataApplicationException("Not supported yet.",
|
EdmAction action = checkBoundAndExtractAction(uriInfo);
|
||||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
DeserializerResult deserializerResult =
|
||||||
|
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||||
|
.actionParameters(request.getBody(), action);
|
||||||
|
|
||||||
|
Property property =
|
||||||
|
dataProvider.processActionPrimitiveCollection(action.getName(), deserializerResult.getActionParameters());
|
||||||
|
|
||||||
|
if (property == null || property.isNull()) {
|
||||||
|
// Collection Propertys must never be null
|
||||||
|
throw new ODataApplicationException("The action could no be executed", 500, Locale.ROOT);
|
||||||
|
} else if (property.asCollection().contains(null) && !action.getReturnType().isNullable()) {
|
||||||
|
// Not nullable return type but array contains a null value
|
||||||
|
throw new ODataApplicationException("The action could no be executed", 500, Locale.ROOT);
|
||||||
|
}
|
||||||
|
EdmPrimitiveType type = (EdmPrimitiveType) action.getReturnType().getType();
|
||||||
|
ContextURL contextURL = ContextURL.with().type(type).asCollection().build();
|
||||||
|
PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextURL).build();
|
||||||
|
|
||||||
|
SerializerResult result =
|
||||||
|
odata.createSerializer(ODataFormat.fromContentType(responseFormat))
|
||||||
|
.primitiveCollection(type, property, options);
|
||||||
|
|
||||||
|
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||||
|
response.setContent(result.getContent());
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -199,8 +210,32 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
||||||
public void processActionComplex(ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
public void processActionComplex(ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
||||||
ContentType requestFormat, ContentType responseFormat)
|
ContentType requestFormat, ContentType responseFormat)
|
||||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||||
throw new ODataApplicationException("Not supported yet.",
|
EdmAction action = checkBoundAndExtractAction(uriInfo);
|
||||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
DeserializerResult deserializerResult =
|
||||||
|
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||||
|
.actionParameters(request.getBody(), action);
|
||||||
|
|
||||||
|
Property property = dataProvider.processActionComplex(action.getName(), deserializerResult.getActionParameters());
|
||||||
|
EdmComplexType type = (EdmComplexType) action.getReturnType().getType();
|
||||||
|
if (property == null || property.isNull()) {
|
||||||
|
if (action.getReturnType().isNullable()) {
|
||||||
|
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||||
|
} else {
|
||||||
|
// Not nullable return type so we have to give back a 500
|
||||||
|
throw new ODataApplicationException("The action could no be executed", 500, Locale.ROOT);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ContextURL contextURL = ContextURL.with().type(type).build();
|
||||||
|
ComplexSerializerOptions options = ComplexSerializerOptions.with().contextURL(contextURL).build();
|
||||||
|
|
||||||
|
SerializerResult result =
|
||||||
|
odata.createSerializer(ODataFormat.fromContentType(responseFormat)).complex(serviceMetadata, type, property,
|
||||||
|
options);
|
||||||
|
|
||||||
|
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||||
|
response.setContent(result.getContent());
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -232,9 +267,10 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
||||||
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||||
.actionParameters(request.getBody(), action);
|
.actionParameters(request.getBody(), action);
|
||||||
|
|
||||||
Property property = dataProvider.processActionPrimitive(action.getName(), deserializerResult.getActionParameters());
|
Property property =
|
||||||
|
dataProvider.processActionComplexCollection(action.getName(), deserializerResult.getActionParameters());
|
||||||
|
|
||||||
if (property.isNull()) {
|
if (property == null || property.isNull()) {
|
||||||
// Collection Propertys must never be null
|
// Collection Propertys must never be null
|
||||||
throw new ODataApplicationException("The action could no be executed", 500, Locale.ROOT);
|
throw new ODataApplicationException("The action could no be executed", 500, Locale.ROOT);
|
||||||
} else if (property.asCollection().contains(null) && !action.getReturnType().isNullable()) {
|
} else if (property.asCollection().contains(null) && !action.getReturnType().isNullable()) {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Locale;
|
||||||
import org.apache.olingo.commons.api.data.Entity;
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
import org.apache.olingo.commons.api.data.EntityCollection;
|
import org.apache.olingo.commons.api.data.EntityCollection;
|
||||||
import org.apache.olingo.commons.api.data.Link;
|
import org.apache.olingo.commons.api.data.Link;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmAction;
|
||||||
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
|
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
|
||||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||||
|
@ -34,9 +35,11 @@ import org.apache.olingo.server.api.OData;
|
||||||
import org.apache.olingo.server.api.ODataApplicationException;
|
import org.apache.olingo.server.api.ODataApplicationException;
|
||||||
import org.apache.olingo.server.api.ServiceMetadata;
|
import org.apache.olingo.server.api.ServiceMetadata;
|
||||||
import org.apache.olingo.server.api.processor.Processor;
|
import org.apache.olingo.server.api.processor.Processor;
|
||||||
|
import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
import org.apache.olingo.server.api.uri.UriInfoResource;
|
import org.apache.olingo.server.api.uri.UriInfoResource;
|
||||||
import org.apache.olingo.server.api.uri.UriParameter;
|
import org.apache.olingo.server.api.uri.UriParameter;
|
||||||
import org.apache.olingo.server.api.uri.UriResource;
|
import org.apache.olingo.server.api.uri.UriResource;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResourceAction;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceFunction;
|
import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
||||||
|
@ -212,4 +215,16 @@ public abstract class TechnicalProcessor implements Processor {
|
||||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected EdmAction checkBoundAndExtractAction(final UriInfo uriInfo) throws ODataApplicationException {
|
||||||
|
final UriInfoResource resource = uriInfo.asUriInfoResource();
|
||||||
|
List<UriResource> uriResourceParts = resource.getUriResourceParts();
|
||||||
|
if (uriResourceParts.size() > 1) {
|
||||||
|
throw new ODataApplicationException("Bound acctions not supported yet.",
|
||||||
|
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||||
|
}
|
||||||
|
UriResourceAction uriResourceAction = (UriResourceAction) uriResourceParts.get(0);
|
||||||
|
EdmAction action = uriResourceAction.getAction();
|
||||||
|
return action;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,22 @@ public class ODataJsonDeserializerActionParametersTest extends AbstractODataDese
|
||||||
assertTrue(parameters.isEmpty());
|
assertTrue(parameters.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ignoreODataAnnotations() throws Exception {
|
||||||
|
final String input =
|
||||||
|
"{\"ParameterDuration@odata.type\":\"Edm.Duration\","
|
||||||
|
+ "\"ParameterDuration\":\"P42DT11H22M33S\",\"ParameterInt16\":42}";
|
||||||
|
final Map<String, Parameter> parameters = deserialize(input, "UARTTwoParam");
|
||||||
|
assertNotNull(parameters);
|
||||||
|
assertEquals(2, parameters.size());
|
||||||
|
Parameter parameter = parameters.get("ParameterInt16");
|
||||||
|
assertNotNull(parameter);
|
||||||
|
assertEquals((short) 42, parameter.getValue());
|
||||||
|
parameter = parameters.get("ParameterDuration");
|
||||||
|
assertNotNull(parameter);
|
||||||
|
assertEquals(BigDecimal.valueOf(3669753), parameter.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = DeserializerException.class)
|
@Test(expected = DeserializerException.class)
|
||||||
public void bindingParameter() throws Exception {
|
public void bindingParameter() throws Exception {
|
||||||
deserialize("{\"ParameterETAllPrim\":{\"PropertyInt16\":42}}", "BAETAllPrimRT", "ETAllPrim");
|
deserialize("{\"ParameterETAllPrim\":{\"PropertyInt16\":42}}", "BAETAllPrimRT", "ETAllPrim");
|
||||||
|
|
Loading…
Reference in New Issue