• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wistefan / tmforum-api / #68

24 Oct 2023 01:20PM UTC coverage: 67.773% (-0.4%) from 68.167%
#68

push

web-flow
Make dome working (#37)

* set defaults

* update mapping dep

* add redis as option

3287 of 4850 relevant lines covered (67.77%)

0.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/common/src/main/java/org/fiware/tmforum/common/repository/NgsiLdBaseRepository.java
1
package org.fiware.tmforum.common.repository;
2

3
import io.github.wistefan.mapping.EntityVOMapper;
4
import io.github.wistefan.mapping.JavaObjectMapper;
5
import io.micronaut.cache.annotation.CacheInvalidate;
6
import io.micronaut.cache.annotation.CachePut;
7
import io.micronaut.cache.annotation.Cacheable;
8
import io.micronaut.http.HttpStatus;
9
import io.micronaut.http.client.exceptions.HttpClientResponseException;
10
import lombok.RequiredArgsConstructor;
11
import org.fiware.ngsi.api.EntitiesApiClient;
12
import org.fiware.ngsi.model.EntityFragmentVO;
13
import org.fiware.ngsi.model.EntityVO;
14
import org.fiware.tmforum.common.CommonConstants;
15
import org.fiware.tmforum.common.caching.EntityIdKeyGenerator;
16
import org.fiware.tmforum.common.configuration.GeneralProperties;
17
import org.fiware.tmforum.common.exception.DeletionException;
18
import org.fiware.tmforum.common.exception.DeletionExceptionReason;
19
import org.fiware.tmforum.common.exception.NgsiLdRepositoryException;
20
import org.fiware.tmforum.common.mapping.NGSIMapper;
21
import reactor.core.publisher.Mono;
22

23
import java.net.URI;
24
import java.util.Arrays;
25
import java.util.List;
26
import java.util.Optional;
27
import java.util.stream.Stream;
28

29
/**
30
 * Base-Repository implementation for using the NGSI-LD API as a storage backend. Supports caching and asynchronous retrieval of entities.
31
 */
32
@RequiredArgsConstructor
×
33
public abstract class NgsiLdBaseRepository {
34

35
    protected final GeneralProperties generalProperties;
36
    protected final EntitiesApiClient entitiesApi;
37
    protected final JavaObjectMapper javaObjectMapper;
38
    protected final NGSIMapper ngsiMapper;
39
    protected final EntityVOMapper entityVOMapper;
40

41

42
    protected String getLinkHeader() {
43
        return String.format("<%s>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json", generalProperties.getContextUrl());
×
44
    }
45

46
    /**
47
     * Create an entity at the broker and cache it.
48
     *
49
     * @param entityVO     - the entity to be created
50
     * @param ngsiLDTenant - tenant the entity belongs to
51
     * @return completable with the result
52
     */
53
    @CachePut(value = CommonConstants.ENTITIES_CACHE_NAME, keyGenerator = EntityIdKeyGenerator.class)
54
    public Mono<Void> createEntity(EntityVO entityVO, String ngsiLDTenant) {
55
        return entitiesApi.createEntity(entityVO, ngsiLDTenant);
×
56
    }
57

58
    /**
59
     * Retrieve entity from the broker or from the cache if they are available there.
60
     *
61
     * @param entityId id of the entity
62
     * @return the entity
63
     */
64
    @Cacheable(CommonConstants.ENTITIES_CACHE_NAME)
65
    public Mono<EntityVO> retrieveEntityById(URI entityId) {
66
        return asyncRetrieveEntityById(entityId, generalProperties.getTenant(), null, null, null, getLinkHeader());
×
67
    }
68

69
    /**
70
     * Patch an entity, using the "overwrite" option.
71
     *
72
     * @param entityId         id of the entity
73
     * @param entityFragmentVO the entity elements to be updated
74
     * @return an empty mono
75
     */
76
    @CacheInvalidate(value = CommonConstants.ENTITIES_CACHE_NAME, keyGenerator = EntityIdKeyGenerator.class)
77
    public Mono<Void> patchEntity(URI entityId, EntityFragmentVO entityFragmentVO) {
78
        return entitiesApi.updateEntity(entityId, entityFragmentVO, generalProperties.getTenant(), null);
×
79
    }
80

81
    /**
82
     * Create a domain entity
83
     *
84
     * @param domainEntity the entity to be created
85
     * @param <T>          the type of the object
86
     * @return an empty mono
87
     */
88
    public <T> Mono<Void> createDomainEntity(T domainEntity) {
89
        return createEntity(javaObjectMapper.toEntityVO(domainEntity), generalProperties.getTenant());
×
90
    }
91

92
    /**
93
     * Update a domain entity
94
     *
95
     * @param id           id of the entity to be updated
96
     * @param domainEntity the entity to be created
97
     * @param <T>          the type of the object
98
     * @return an empty mono
99
     */
100
    public <T> Mono<Void> updateDomainEntity(String id, T domainEntity) {
101
        return patchEntity(URI.create(id), ngsiMapper.map(javaObjectMapper.toEntityVO(domainEntity)));
×
102
    }
103

104
    /**
105
     * Delete a domain entity
106
     *
107
     * @param id id of the entity to be deleted
108
     * @return an empty mono
109
     */
110
    @CacheInvalidate(value = CommonConstants.ENTITIES_CACHE_NAME, keyGenerator = EntityIdKeyGenerator.class)
111
    public Mono<Void> deleteDomainEntity(URI id) {
112
        return entitiesApi
×
113
            .removeEntityById(id, generalProperties.getTenant(), null)
×
114
            .onErrorResume(t -> {
×
115
                if (t instanceof HttpClientResponseException e && e.getStatus().equals(HttpStatus.NOT_FOUND)) {
×
116
                    throw new DeletionException(String.format("Was not able to delete %s, since it does not exist.", id),
×
117
                            DeletionExceptionReason.NOT_FOUND);
118
                }
119
                throw new DeletionException(String.format("Was not able to delete %s.", id),
×
120
                        t,
121
                        DeletionExceptionReason.UNKNOWN);
122
            });
123
    }
124

125
    /**
126
     * Helper method for combining a stream of entites to a single mono.
127
     *
128
     * @param entityVOStream stream of entites
129
     * @param targetClass    target class to map them
130
     * @param <T>            type of the target
131
     * @return a mono, emitting a list of mapped entities
132
     */
133
    protected <T> Mono<List<T>> zipToList(Stream<EntityVO> entityVOStream, Class<T> targetClass) {
134
        return Mono.zip(
×
135
                entityVOStream.map(entityVO -> entityVOMapper.fromEntityVO(entityVO, targetClass)).toList(),
×
136
                oList -> Arrays.stream(oList).map(targetClass::cast).toList()
×
137
        );
138
    }
139

140
    /**
141
     * Uncached call to the broker
142
     */
143
    private Mono<EntityVO> asyncRetrieveEntityById(URI entityId, String ngSILDTenant, String attrs, String type, String options, String link) {
144
        return entitiesApi
×
145
                .retrieveEntityById(entityId, ngSILDTenant, attrs, type, options, link)
×
146
                .onErrorResume(this::handleClientException);
×
147
    }
148

149
    private Mono<EntityVO> handleClientException(Throwable e) {
150
        if (e instanceof HttpClientResponseException httpException && httpException.getStatus().equals(HttpStatus.NOT_FOUND)) {
×
151
            return Mono.empty();
×
152
        }
153
        throw new NgsiLdRepositoryException("Was not able to successfully call the broker.", Optional.of(e));
×
154
    }
155

156
}
157

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc