fb612640955e6bd1efec0b9658ca84804fa91f73
[honeycomb.git] / lisp / lisp2vpp / src / main / java / io / fd / honeycomb / lisp / translate / write / LocatorSetCustomizer.java
1 /*
2  * Copyright (c) 2015 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.write;
18
19 import static com.google.common.base.Preconditions.checkNotNull;
20 import static com.google.common.base.Preconditions.checkState;
21 import static java.nio.charset.StandardCharsets.UTF_8;
22
23 import com.google.common.base.Optional;
24 import io.fd.honeycomb.lisp.translate.read.dump.executor.LocatorSetsDumpExecutor;
25 import io.fd.honeycomb.translate.ModificationCache;
26 import io.fd.honeycomb.translate.read.ReadFailedException;
27 import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
28 import io.fd.honeycomb.translate.util.RWUtils;
29 import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
30 import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor;
31 import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator;
32 import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer;
33 import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer;
34 import io.fd.honeycomb.translate.vpp.util.NamingContext;
35 import io.fd.honeycomb.translate.write.WriteContext;
36 import io.fd.honeycomb.translate.write.WriteFailedException;
37 import io.fd.vpp.jvpp.VppBaseCallException;
38 import io.fd.vpp.jvpp.core.dto.LispAddDelLocatorSet;
39 import io.fd.vpp.jvpp.core.dto.LispLocatorSetDetailsReplyDump;
40 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
41 import java.io.UnsupportedEncodingException;
42 import java.util.List;
43 import java.util.concurrent.TimeoutException;
44 import javax.annotation.Nonnull;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSet;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSetKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.locator.set.Interface;
48 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
49
50
51 /**
52  * Customizer for {@link LocatorSet} entity.
53  *
54  * @see LocatorSet
55  */
56 public class LocatorSetCustomizer extends FutureJVppCustomizer
57         implements ListWriterCustomizer<LocatorSet, LocatorSetKey>, ByteDataTranslator,
58         JvppReplyConsumer {
59
60     private final NamingContext locatorSetContext;
61     private final DumpCacheManager<LispLocatorSetDetailsReplyDump, Void> dumpManager;
62
63     public LocatorSetCustomizer(@Nonnull final FutureJVppCore futureJvpp,
64                                 @Nonnull final NamingContext locatorSetContext) {
65         super(futureJvpp);
66         this.locatorSetContext = checkNotNull(locatorSetContext, "Locator set context cannot be null");
67         this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<LispLocatorSetDetailsReplyDump, Void>()
68                 .withExecutor(new LocatorSetsDumpExecutor(futureJvpp))
69                 .build();
70     }
71
72     @Override
73     public void writeCurrentAttributes(@Nonnull InstanceIdentifier<LocatorSet> id,
74                                        @Nonnull LocatorSet dataAfter,
75                                        @Nonnull WriteContext writeContext) throws WriteFailedException {
76
77         checkNotNull(dataAfter, "LocatorSet is null");
78
79         final String locatorSetName = dataAfter.getName();
80         checkNotNull(locatorSetName, "LocatorSet name is null");
81         checkState(isNonEmptyLocatorSet(writeContext.readAfter(id).get()),
82                 "Creating empty locator-sets is not allowed");
83         // TODO VPP-323 check and fill mapping when api returns index of created locator set
84         // checkState(!locatorSetContext.containsIndex(locatorSetName, writeContext.getMappingContext()),
85         //         "Locator set with name %s already defined", locatorSetName);
86
87         try {
88             addDelLocatorSetAndReply(true, dataAfter.getName());
89         } catch (VppBaseCallException | TimeoutException | UnsupportedEncodingException e) {
90             throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
91         }
92
93         //TODO - REMOVE FROM MASTER AFTER VPP-323
94         try {
95             locatorSetContext
96                     .addName(getLocatorSetIndex(id, locatorSetName, writeContext.getModificationCache()),
97                             locatorSetName, writeContext.getMappingContext());
98         } catch (ReadFailedException e) {
99             throw new WriteFailedException(id,
100                     new IllegalStateException("Unable to create mapping for locator set " + locatorSetName, e));
101         }
102     }
103
104     private boolean isNonEmptyLocatorSet(final LocatorSet locatorSet) {
105         final List<Interface> locators = locatorSet.getInterface();
106         return locators != null && !locators.isEmpty();
107     }
108
109     @Override
110     public void updateCurrentAttributes(@Nonnull InstanceIdentifier<LocatorSet> id,
111                                         @Nonnull LocatorSet dataBefore,
112                                         @Nonnull LocatorSet dataAfter,
113                                         @Nonnull WriteContext writeContext) throws WriteFailedException {
114         throw new UnsupportedOperationException("Operation not supported");
115     }
116
117     @Override
118     public void deleteCurrentAttributes(@Nonnull InstanceIdentifier<LocatorSet> id,
119                                         @Nonnull LocatorSet dataBefore,
120                                         @Nonnull WriteContext writeContext) throws WriteFailedException {
121
122         checkNotNull(dataBefore, "LocatorSet is null");
123
124         final String locatorSetName = dataBefore.getName();
125         checkNotNull(locatorSetName, "LocatorSet name is null");
126
127         try {
128             addDelLocatorSetAndReply(false, dataBefore.getName());
129         } catch (VppBaseCallException | TimeoutException | UnsupportedEncodingException e) {
130             throw new WriteFailedException.DeleteFailedException(id, e);
131         }
132
133         //removes mapping after successful delete
134         locatorSetContext.removeName(locatorSetName, writeContext.getMappingContext());
135     }
136
137     private void addDelLocatorSetAndReply(boolean add, String name)
138             throws VppBaseCallException, TimeoutException, UnsupportedEncodingException {
139
140         LispAddDelLocatorSet addDelSet = new LispAddDelLocatorSet();
141
142         addDelSet.isAdd = booleanToByte(add);
143         addDelSet.locatorSetName = name.getBytes(UTF_8);
144
145
146         getReply(getFutureJVpp().lispAddDelLocatorSet(addDelSet).toCompletableFuture());
147     }
148
149     //TODO - REMOVE FROM MASTER AFTER VPP-323
150     // total hack
151     public int getLocatorSetIndex(final InstanceIdentifier<LocatorSet> identifier, final String name,
152                                   final ModificationCache cache)
153             throws ReadFailedException {
154
155         Optional<LispLocatorSetDetailsReplyDump> reply = dumpManager
156                 .getDump(identifier, io.fd.honeycomb.lisp.translate.read.LocatorSetCustomizer.LOCATOR_SETS_CACHE_ID,
157                         cache,
158                         EntityDumpExecutor.NO_PARAMS);
159
160         if (reply.isPresent()) {
161             return reply.get().lispLocatorSetDetails.stream()
162                     .filter(a -> name.equals(toString(a.lsName)))
163                     .collect(RWUtils.singleItemCollector())
164                     .lsIndex;
165         } else {
166             throw new IllegalStateException("Unable to find index of locator set " + name);
167         }
168     }
169
170
171 }