HONEYCOMB-58 - Routing Api
[honeycomb.git] / lisp / lisp2vpp / src / main / java / io / fd / honeycomb / lisp / translate / read / AdjacencyCustomizer.java
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package io.fd.honeycomb.lisp.translate.read;
18
19
20 import static com.google.common.base.Preconditions.checkNotNull;
21
22 import com.google.common.base.Optional;
23 import io.fd.honeycomb.lisp.context.util.AdjacenciesMappingContext;
24 import io.fd.honeycomb.lisp.context.util.EidMappingContext;
25 import io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams;
26 import io.fd.honeycomb.lisp.translate.util.EidTranslator;
27 import io.fd.honeycomb.translate.MappingContext;
28 import io.fd.honeycomb.translate.read.ReadContext;
29 import io.fd.honeycomb.translate.read.ReadFailedException;
30 import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer;
31 import io.fd.honeycomb.translate.util.RWUtils;
32 import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
33 import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor;
34 import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer;
35 import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer;
36 import io.fd.vpp.jvpp.core.dto.LispAdjacenciesGet;
37 import io.fd.vpp.jvpp.core.dto.LispAdjacenciesGetReply;
38 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
39 import io.fd.vpp.jvpp.core.types.LispAdjacency;
40 import java.util.Arrays;
41 import java.util.Collections;
42 import java.util.List;
43 import java.util.Objects;
44 import java.util.stream.Collectors;
45 import javax.annotation.Nonnull;
46 import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.mapping.EidIdentificatorPair;
47 import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.mapping.EidIdentificatorPairBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.MappingId;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.AdjacenciesBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.Adjacency;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.AdjacencyBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.AdjacencyKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable;
54 import org.opendaylight.yangtools.concepts.Builder;
55 import org.opendaylight.yangtools.yang.binding.DataObject;
56 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
57
58 public class AdjacencyCustomizer extends FutureJVppCustomizer
59         implements ListReaderCustomizer<Adjacency, AdjacencyKey, AdjacencyBuilder>, JvppReplyConsumer, EidTranslator {
60
61     private final DumpCacheManager<LispAdjacenciesGetReply, AdjacencyDumpParams> dumpCacheManager;
62     private final AdjacenciesMappingContext adjacenciesMappingContext;
63     private final EidPairProducer eidPairProducer;
64
65
66     public AdjacencyCustomizer(@Nonnull final FutureJVppCore futureJvpp,
67                                @Nonnull final EidMappingContext localMappingContext,
68                                @Nonnull final EidMappingContext remoteMappingContext,
69                                @Nonnull final AdjacenciesMappingContext adjacenciesMappingContext) {
70         super(futureJvpp);
71         dumpCacheManager = new DumpCacheManager.DumpCacheManagerBuilder<LispAdjacenciesGetReply, AdjacencyDumpParams>()
72                 .withExecutor(createExecutor())
73                 .build();
74
75         this.adjacenciesMappingContext =
76                 checkNotNull(adjacenciesMappingContext, "Adjacencies mapping context cannot be null");
77         this.eidPairProducer = new EidPairProducer(localMappingContext, remoteMappingContext);
78     }
79
80     @Nonnull
81     @Override
82     public List<AdjacencyKey> getAllIds(@Nonnull final InstanceIdentifier<Adjacency> id,
83                                         @Nonnull final ReadContext context) throws ReadFailedException {
84
85         final int vni = id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier().intValue();
86
87         final Optional<LispAdjacenciesGetReply> optionalDump =
88                 dumpCacheManager.getDump(id, context.getModificationCache(), new AdjacencyDumpParams(vni));
89
90
91         if (optionalDump.isPresent()) {
92             return Arrays.stream(optionalDump.get().adjacencies)
93                     .map(lispAdjacency -> eidPairProducer.createPair(lispAdjacency, vni, context.getMappingContext()))
94                     .map(pair -> adjacenciesMappingContext
95                             .getAdjacencyId(pair.getLocalEidId().getValue(), pair.getRemoteEidId().getValue(),
96                                     context.getMappingContext()))
97                     .map(AdjacencyKey::new)
98                     .collect(Collectors.toList());
99         }
100
101         //does not throw exception to not disturb lisp state reading
102         return Collections.emptyList();
103     }
104
105     @Override
106     public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<Adjacency> readData) {
107         ((AdjacenciesBuilder) builder).setAdjacency(readData);
108     }
109
110     @Nonnull
111     @Override
112     public AdjacencyBuilder getBuilder(@Nonnull final InstanceIdentifier<Adjacency> id) {
113         return new AdjacencyBuilder();
114     }
115
116     @Override
117     public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Adjacency> id,
118                                       @Nonnull final AdjacencyBuilder builder, @Nonnull final ReadContext ctx)
119             throws ReadFailedException {
120
121         final int vni = id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier().intValue();
122
123         final Optional<LispAdjacenciesGetReply> optionalDump = dumpCacheManager
124                 .getDump(id, ctx.getModificationCache(), new AdjacencyDumpParams(vni));
125
126         if (!optionalDump.isPresent() || optionalDump.get().adjacencies.length == 0) {
127             return;
128         }
129
130         final String currentAdjacencyId = id.firstKeyOf(Adjacency.class).getId();
131         final EidIdentificatorPair currentAdjacencyIdentificationPair =
132                 adjacenciesMappingContext.getEidPair(currentAdjacencyId, ctx.getMappingContext());
133
134         final LispAdjacency currentAdjacency = Arrays.stream(optionalDump.get().adjacencies)
135                 .filter(lispAdjacency -> Objects.equals(currentAdjacencyIdentificationPair,
136                         eidPairProducer.createPair(lispAdjacency, vni, ctx.getMappingContext())))
137                 .collect(RWUtils.singleItemCollector());
138
139         builder.setId(currentAdjacencyId)
140                 .setKey(new AdjacencyKey(currentAdjacencyId))
141                 .setLocalEid(getArrayAsLocalEid(
142                         MappingsDumpParams.EidType.valueOf(currentAdjacency.eidType), currentAdjacency.leid, vni))
143                 .setRemoteEid(getArrayAsRemoteEid(
144                         MappingsDumpParams.EidType.valueOf(currentAdjacency.eidType), currentAdjacency.reid, vni));
145     }
146
147     private EntityDumpExecutor<LispAdjacenciesGetReply, AdjacencyDumpParams> createExecutor() {
148         return (final InstanceIdentifier<?> identifier, final AdjacencyDumpParams params) -> {
149             checkNotNull(params, "Dump parameters cannot be null");
150
151             final LispAdjacenciesGet request = new LispAdjacenciesGet();
152             request.vni = params.getVni();
153
154             return getReplyForRead(getFutureJVpp().lispAdjacenciesGet(request).toCompletableFuture(), identifier);
155         };
156     }
157
158     private class EidPairProducer implements EidTranslator {
159
160         private final EidMappingContext localMappingContext;
161         private final EidMappingContext remoteMappingContext;
162
163         public EidPairProducer(final EidMappingContext localMappingContext,
164                                final EidMappingContext remoteMappingContext) {
165             this.localMappingContext = checkNotNull(localMappingContext, "Local mapping context cannot be null");
166             this.remoteMappingContext = checkNotNull(remoteMappingContext, "Remote mapping context cannot be null");
167         }
168
169         public EidIdentificatorPair createPair(final LispAdjacency data, final int vni,
170                                                final MappingContext mappingContext) {
171             return new EidIdentificatorPairBuilder()
172                     .setLocalEidId(new MappingId(localMappingContext.getId(getArrayAsEidLocal(
173                             MappingsDumpParams.EidType.valueOf(data.eidType), data.leid, vni), mappingContext)))
174                     .setRemoteEidId(new MappingId(remoteMappingContext.getId(getArrayAsEidLocal(
175                             MappingsDumpParams.EidType.valueOf(data.eidType), data.reid, vni), mappingContext)))
176                     .build();
177         }
178     }
179
180     private static final class AdjacencyDumpParams {
181
182         private final int vni;
183
184         AdjacencyDumpParams(final int vni) {
185             this.vni = vni;
186         }
187
188         public int getVni() {
189             return this.vni;
190         }
191     }
192 }