+ // TODO bug 7699
+ // This works as a workaround for mountpoint registration in cluster. If application is registered on different
+ // node as netconf service, it obtains mountpoint registered by SlaveSalFacade (instead of MasterSalFacade). However
+ // this service registers mountpoint a moment later then connectionStatus is set to "Connected". If NodeManager hits
+ // state where device is connected but mountpoint is not yet available, try to get it again in a while
+ private Future<Optional<MountPoint>> getMountpointFromSal(final InstanceIdentifier<Node> iid) {
+ final ExecutorService executorService = Executors.newSingleThreadExecutor();
+ final Callable<Optional<MountPoint>> task = () -> {
+ byte attempt = 0;
+ do {
+ try {
+ final Optional<MountPoint> optionalMountpoint = mountService.getMountPoint(iid);
+ if (optionalMountpoint.isPresent()) {
+ return optionalMountpoint;
+ }
+ LOG.warn("Mountpoint {} is not registered yet", iid);
+ Thread.sleep(DURATION);
+ } catch (InterruptedException e) {
+ LOG.warn("Thread interrupted to ", e);
+ }
+ attempt ++;
+ } while (attempt <= 3);
+ return Optional.absent();
+ };
+ return executorService.submit(task);
+ }
+
+ private void syncPhysicalInterfacesInLocalDs(DataBroker mountPointDataBroker, InstanceIdentifier<Node> nodeIid) {
+ ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+ InstanceIdentifier.create(Interfaces.class);
+ ReadOnlyTransaction rTx = mountPointDataBroker.newReadOnlyTransaction();
+ Optional<Interfaces> readIfaces = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+ InstanceIdentifier.create(Interfaces.class), rTx);
+ if (readIfaces.isPresent()) {
+ InstanceIdentifier<RendererNode> rendererNodeIid = VppIidFactory.getRendererNodesIid()
+ .builder()
+ .child(RendererNode.class, new RendererNodeKey(nodeIid))
+ .build();
+ Optional<RendererNode> optRendNode = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+ rendererNodeIid, rwTx);
+ RendererNode rendNode = new RendererNodeBuilder(optRendNode.get()).addAugmentation(
+ VppInterfaceAugmentation.class, resolveTerminationPoints(readIfaces.get())).build();
+ rwTx.put(LogicalDatastoreType.OPERATIONAL, VppIidFactory.getRendererNodeIid(optRendNode.get()), rendNode,
+ true);
+ }
+ rTx.close();
+ DataStoreHelper.submitToDs(rwTx);
+ }
+
+ private VppInterfaceAugmentation resolveTerminationPoints(Interfaces interfaces) {
+ List<PhysicalInterface> phIfaces = new ArrayList<>();
+ PhysicalInterfaceBuilder phIface = new PhysicalInterfaceBuilder();
+ if (interfaces != null && interfaces.getInterface() != null) {
+ interfaces.getInterface()
+ .stream()
+ .filter(iface -> iface.getType().equals(EthernetCsmacd.class))
+ .filter(iface -> iface.getAugmentation(Interface1.class) != null)
+ .forEach(iface -> {
+ phIface.setInterfaceName(iface.getName());
+ phIface.setType(iface.getType());
+ phIface.setAddress(resolveIpAddress(iface.getAugmentation(Interface1.class)));
+ phIfaces.add(phIface.build());
+ });
+ }
+ return new VppInterfaceAugmentationBuilder().setPhysicalInterface(phIfaces).build();
+ }
+
+ private List<IpAddress> resolveIpAddress(Interface1 iface) {
+ if (iface.getIpv4() != null && iface.getIpv4().getAddress() != null) {
+ return iface.getIpv4().getAddress().stream().map(ipv4 -> {
+ return new IpAddress(new Ipv4Address(ipv4.getIp().getValue()));
+ }).collect(Collectors.toList());
+ } else if (iface.getIpv6() != null && iface.getIpv6().getAddress() != null) {
+ return iface.getIpv6().getAddress().stream().map(ipv6 -> {
+ return new IpAddress(new Ipv4Address(ipv6.getIp().getValue()));
+ }).collect(Collectors.toList());
+ }
+ return Lists.newArrayList();
+ }