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