Skip to content

Commit

Permalink
eclipse-ditto#760 added test for mapping with policy in template
Browse files Browse the repository at this point in the history
Signed-off-by: Johannes Schneider <johannes.schneider@bosch.io>
  • Loading branch information
jokraehe committed Aug 26, 2020
1 parent 5f175df commit da8bddf
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 62 deletions.
Expand Up @@ -187,8 +187,8 @@ The created thing contains the values defined in the template, configured in the
```json
{
"thing": {
"thingId": "{{header:device_id}}",
"policyId": "{{header:entity.id}}",
"thingId": "{{ header:device_id }}",
"policyId": "{{ entity:policy_id }}",
"attributes": {
"CreatedBy": "ImplicitThingCreation"
}
Expand All @@ -197,7 +197,6 @@ The created thing contains the values defined in the template, configured in the
```



## Example connection with multiple mappers

The following example connection defines a `ConnectionStatus` mapping with the ID `status` and references it in a
Expand Down
Expand Up @@ -16,43 +16,71 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.fail;
import static org.eclipse.ditto.services.models.things.Permission.READ;
import static org.eclipse.ditto.services.models.things.Permission.WRITE;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Nullable;

import org.eclipse.ditto.json.JsonValue;
import org.eclipse.ditto.json.JsonObject;
import org.eclipse.ditto.model.connectivity.MessageMapperConfigurationInvalidException;
import org.eclipse.ditto.model.placeholders.UnresolvedPlaceholderException;
import org.eclipse.ditto.model.policies.PoliciesResourceType;
import org.eclipse.ditto.model.policies.Policy;
import org.eclipse.ditto.model.policies.SubjectIssuer;
import org.eclipse.ditto.model.things.Thing;
import org.eclipse.ditto.model.things.ThingsModelFactory;
import org.eclipse.ditto.protocoladapter.Adaptable;
import org.eclipse.ditto.protocoladapter.Payload;
import org.eclipse.ditto.protocoladapter.DittoProtocolAdapter;
import org.eclipse.ditto.services.models.connectivity.ExternalMessage;
import org.eclipse.ditto.services.models.connectivity.ExternalMessageFactory;
import org.eclipse.ditto.signals.base.Signal;
import org.eclipse.ditto.signals.commands.things.modify.CreateThing;
import org.junit.Before;
import org.junit.Test;

import com.typesafe.config.ConfigFactory;

public class ImplicitThingCreationMessageMapperTest {

private static final DittoProtocolAdapter DITTO_PROTOCOL_ADAPTER = DittoProtocolAdapter.newInstance();

private static final String HEADER_HONO_DEVICE_ID = "device_id";
private static final String HEADER_HONO_GATEWAY_ID = "gateway_id";
private static final String OPTIONAL_HEADER_HONO_ENTITY_ID = "entity_id";
private static final String HEADER_POLICY_ID = "policy_id";

private static final String THING_TEMPLATE = "{" +
private static final String THING_TEMPLATE_WITH_POLICY_ID = "{" +
"\"thingId\": \"{{ header:device_id }}\"," +
"\"policyId\": \"{{ header:entity_id }}\"," +
"\"policyId\": \"{{ header:policy_id }}\"," +
"\"attributes\": {" +
"\"info\": {" +
"\"gatewayId\": \"{{ header:gateway_id }}\"" +
"}" +
"}" +
"}";

private static final JsonObject INITIAL_POLICY = Policy.newBuilder()
.forLabel("DEFAULT")
.setSubject(SubjectIssuer.INTEGRATION, "solutionId:connectionId")
.setGrantedPermissions(PoliciesResourceType.policyResource("/"), READ, WRITE)
.setGrantedPermissions(PoliciesResourceType.thingResource("/"), READ, WRITE)
.setGrantedPermissions(PoliciesResourceType.messageResource("/"), READ, WRITE)
.build()
.toJson();

private static final String THING_TEMPLATE_WITH_POLICY = JsonObject.newBuilder()
.set("thingId", "{{ header:device_id }}")
.set("policyId", "{{ header:policy_id }}")
.set("_policy", INITIAL_POLICY)
.set("attributes", JsonObject.newBuilder()
.set("info", JsonObject.newBuilder()
.set("gatewayId", "{{ header:gateway_id }}")
.build())
.build())
.build()
.toString();

private static final String THING_TEMPLATE_WITHOUT_PLACEHOLDERS = "{" +
"\"thingId\": \"some:validThingId!\"," +
"\"policyId\": \"some:validPolicyId!\"," +
Expand All @@ -72,40 +100,67 @@ public void setUp() {
underTest = new ImplicitThingCreationMessageMapper();
}

//Validate mapping context options
@Test
public void doForwardMappingContextWithSubstitutedPlaceholders() {

public void doForwardMappingContextWithPolicyIdPlaceholder() {
final Map<String, String> headers = createValidHeaders();

underTest.configure(mappingConfig, createMapperConfig(null));
underTest.configure(mappingConfig, createMapperConfig(THING_TEMPLATE_WITH_POLICY_ID));

final ExternalMessage externalMessage = ExternalMessageFactory.newExternalMessageBuilder(headers).build();

final List<Adaptable> mappingResult = underTest.map(externalMessage);

final Signal<?> firstMappedSignal = getFirstMappedSignal(mappingResult);
assertThat(firstMappedSignal).isInstanceOf(CreateThing.class);
final CreateThing createThing = (CreateThing) firstMappedSignal;

final Thing expectedThing =
createExpectedThing("headerNamespace:headerDeviceId", "headerNamespace:headerEntityId",
createExpectedThing("headerNamespace:headerDeviceId", "headerNamespace:headerPolicyId",
"headerNamespace:headerGatewayId");
assertThat(createThing.getThing().getEntityId()).isEqualTo(expectedThing.getEntityId());
assertThat(createThing.getThing().getPolicyEntityId()).isEqualTo(expectedThing.getPolicyEntityId());
assertThat(createThing.getThing().getAttributes()).isEqualTo(expectedThing.getAttributes());
}

@Test
public void doForwardMappingContextWithPolicyPlaceholder() {
final Map<String, String> headers = createValidHeaders();
underTest.configure(mappingConfig, createMapperConfig(THING_TEMPLATE_WITH_POLICY));

assertThat(mappingResult.get(0).getPayload().getValue()).isPresent();
final ExternalMessage externalMessage = ExternalMessageFactory.newExternalMessageBuilder(headers).build();
final List<Adaptable> mappingResult = underTest.map(externalMessage);

final Thing mappedThing = getMappedThing(mappingResult);
final Signal<?> firstMappedSignal = getFirstMappedSignal(mappingResult);
assertThat(firstMappedSignal).isInstanceOf(CreateThing.class);
final CreateThing createThing = (CreateThing) firstMappedSignal;

assertThat(mappedThing.getEntityId())
.isEqualTo(expectedThing.getEntityId());
final Thing expectedThing =
createExpectedThing("headerNamespace:headerDeviceId", "headerNamespace:headerPolicyId",
"headerNamespace:headerGatewayId");
assertThat(createThing.getThing().getEntityId()).isEqualTo(expectedThing.getEntityId());
assertThat(createThing.getThing().getPolicyEntityId()).isEqualTo(expectedThing.getPolicyEntityId());
assertThat(createThing.getThing().getAttributes()).isEqualTo(expectedThing.getAttributes());
assertThat(createThing.getInitialPolicy()).contains(INITIAL_POLICY);
}

assertThat(mappedThing.getPolicyEntityId())
.isEqualTo(expectedThing.getPolicyEntityId());
@Test
public void doForwardWithoutPlaceholders() {
final Map<String, String> headers = createValidHeaders();
underTest.configure(mappingConfig, createMapperConfig(THING_TEMPLATE_WITHOUT_PLACEHOLDERS));

final ExternalMessage externalMessage = ExternalMessageFactory.newExternalMessageBuilder(headers).build();
final List<Adaptable> mappingResult = underTest.map(externalMessage);

assertThat(mappedThing.getAttributes())
.isEqualTo(expectedThing.getAttributes());
final Signal<?> firstMappedSignal = getFirstMappedSignal(mappingResult);
assertThat(firstMappedSignal).isInstanceOf(CreateThing.class);
final CreateThing createThing = (CreateThing) firstMappedSignal;

final Thing expectedThing =
createExpectedThing("some:validThingId!", "some:validPolicyId!", "some:validGatewayId!");
assertThat(createThing.getThing().getEntityId()).isEqualTo(expectedThing.getEntityId());
assertThat(createThing.getThing().getPolicyEntityId()).isEqualTo(expectedThing.getPolicyEntityId());
}

@Test
public void throwErrorIfMappingConfigIsMissing() {

final DefaultMessageMapperConfiguration invalidMapperConfig = createMapperConfig("{}");

assertThatExceptionOfType(MessageMapperConfigurationInvalidException.class)
Expand All @@ -114,9 +169,8 @@ public void throwErrorIfMappingConfigIsMissing() {

@Test
public void throwErrorIfThingIdIsMissingInConfig() {

final String thingMissing = "{" +
"\"policyId\": \"{{ header:entity_id }}\"" +
"\"policyId\": \"{{ header:policy_id }}\"" +
"}";

final DefaultMessageMapperConfiguration invalidMapperConfig = createMapperConfig(thingMissing);
Expand All @@ -127,7 +181,7 @@ public void throwErrorIfThingIdIsMissingInConfig() {

@Test
public void throwErrorIfHeaderForPlaceholderIsMissing() {
underTest.configure(mappingConfig, createMapperConfig(null));
underTest.configure(mappingConfig, createMapperConfig(THING_TEMPLATE_WITH_POLICY_ID));

final Map<String, String> missingEntityHeader = new HashMap<>();
missingEntityHeader.put(HEADER_HONO_DEVICE_ID, "headerNamespace:headerDeviceId");
Expand All @@ -139,42 +193,17 @@ public void throwErrorIfHeaderForPlaceholderIsMissing() {
.isThrownBy(() -> underTest.map(externalMessage));
}

@Test
public void doForwardEvenWithoutAnyPlaceholders() {
final Map<String, String> headers = createValidHeaders();

underTest.configure(mappingConfig, createMapperConfig(THING_TEMPLATE_WITHOUT_PLACEHOLDERS));

final ExternalMessage externalMessage = ExternalMessageFactory.newExternalMessageBuilder(headers).build();

final List<Adaptable> mappingResult = underTest.map(externalMessage);

final Thing expectedThing =
createExpectedThing("some:validThingId!", "some:validPolicyId!", "some:validGatewayId!");

final Thing mappedThing = getMappedThing(mappingResult);

assertThat(mappedThing.getEntityId())
.isEqualTo(expectedThing.getEntityId());

assertThat(mappedThing.getPolicyEntityId())
.isEqualTo(expectedThing.getPolicyEntityId());
}

private static Thing getMappedThing(final List<Adaptable> mappingResult) {
private static Signal<?> getFirstMappedSignal(final List<Adaptable> mappingResult) {
return mappingResult.stream().findFirst()
.map(Adaptable::getPayload)
.flatMap(Payload::getValue)
.map(JsonValue::asObject)
.map(ThingsModelFactory::newThing)
.orElseGet(() -> fail("Mapping Result did not contain a Thing."));
.map(DITTO_PROTOCOL_ADAPTER::fromAdaptable)
.orElseGet(() -> fail("Mapping Result did not contain a Signal."));
}

private Map<String, String> createValidHeaders() {
final Map<String, String> validHeader = new HashMap<>();
validHeader.put(HEADER_HONO_DEVICE_ID, "headerNamespace:headerDeviceId");
validHeader.put(HEADER_HONO_GATEWAY_ID, "headerNamespace:headerGatewayId");
validHeader.put(OPTIONAL_HEADER_HONO_ENTITY_ID, "headerNamespace:headerEntityId");
validHeader.put(HEADER_POLICY_ID, "headerNamespace:headerPolicyId");
return validHeader;
}

Expand All @@ -190,11 +219,9 @@ private Thing createExpectedThing(final String thingId, final String policyId, f
"}");
}

private DefaultMessageMapperConfiguration createMapperConfig(@Nullable String customTemplate) {
private DefaultMessageMapperConfiguration createMapperConfig(final String thingTemplate) {
final Map<String, String> configPropsWithoutPolicyId = new HashMap<>();

configPropsWithoutPolicyId.put("thing", customTemplate != null ? customTemplate : THING_TEMPLATE);

configPropsWithoutPolicyId.put("thing", thingTemplate);
return DefaultMessageMapperConfiguration.of("valid", configPropsWithoutPolicyId);
}

Expand Down

0 comments on commit da8bddf

Please sign in to comment.