/* * Copyright (c) 2015 Inocybe Technologies and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.groupbasedpolicy.renderer.iovisor.endpoint; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.groupbasedpolicy.api.EpRendererAugmentationRegistry; import org.opendaylight.groupbasedpolicy.renderer.iovisor.module.IovisorModuleListener; import org.opendaylight.groupbasedpolicy.renderer.iovisor.module.IovisorModuleManager; import org.opendaylight.groupbasedpolicy.renderer.iovisor.utils.IovisorIidFactory; import org.opendaylight.groupbasedpolicy.util.DataStoreHelper; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.IovisorModuleAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.IovisorModuleId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.IovisorResolvedEndpoints; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.iovisor.module.instances.IovisorModuleInstance; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.iovisor.module.instances.IovisorModuleInstanceBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.iovisor.modules.by.tenant.by.endpointgroup.id.IovisorModuleByTenantByEndpointgroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.iovisor.modules.by.tenant.by.endpointgroup.id.IovisorModuleByTenantByEndpointgroupIdBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.iovisor.modules.by.tenant.by.endpointgroup.id.iovisor.module.by.tenant.by.endpointgroup.id.IovisorModuleInstanceId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.iovisor.modules.by.tenant.by.endpointgroup.id.iovisor.module.by.tenant.by.endpointgroup.id.IovisorModuleInstanceIdBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.iovisor.resolved.endpoints.IovisorResolvedEndpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.iovisor.resolved.endpoints.IovisorResolvedEndpointBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.iovisor.resolved.endpoints.by.tenant.by.endpointgroup.id.IovisorResolvedEndpointByTenantByEndpointgroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.iovisor.resolved.endpoints.by.tenant.by.endpointgroup.id.IovisorResolvedEndpointByTenantByEndpointgroupIdBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.iovisor.resolved.endpoints.by.tenant.by.endpointgroup.id.iovisor.resolved.endpoint.by.tenant.by.endpointgroup.id.IovisorEndpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.iovisor.rev151030.iovisor.resolved.endpoints.by.tenant.by.endpointgroup.id.iovisor.resolved.endpoint.by.tenant.by.endpointgroup.id.IovisorEndpointBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; public class EndpointManager implements AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(EndpointManager.class); private final DataBroker dataBroker; private EndpointListener endpointListener; private final IovisorEndpointAug iovisorEndpointAug; private IovisorModuleManager iovisorModuleManager; private IovisorModuleListener iovisorModuleListener; public EndpointManager(DataBroker passedDataBroker, EpRendererAugmentationRegistry epRendererAugmentationRegistry) { Preconditions.checkNotNull(passedDataBroker, "DataBroker instance must not be null"); dataBroker = passedDataBroker; iovisorEndpointAug = new IovisorEndpointAug(epRendererAugmentationRegistry); iovisorModuleManager = new IovisorModuleManager(dataBroker); iovisorModuleListener = new IovisorModuleListener(dataBroker); LOG.info("Initialized IOVisor EndpointManager"); } public IovisorModuleManager getIovisorModuleManager() { return iovisorModuleManager; } public void processEndpoint(EndpointL3 endpoint) { IovisorModuleAugmentation iomAug = endpoint.getAugmentation(IovisorModuleAugmentation.class); IovisorModuleId iovisorModuleId = new IovisorModuleId(iomAug.getUri().getValue()); // See if IovisorModule already exists in OPERATIONAL datastore. If not, for now we will // register it. IovisorModuleInstance iovisorModuleInstance = iovisorModuleManager.getActiveIovisorModule(iovisorModuleId); if (iovisorModuleInstance == null) { // In this iteration we will provision the IovisorModule (ie add it to CONF) then // activate it (add it to OPER) iovisorModuleInstance = new IovisorModuleInstanceBuilder().setId(iovisorModuleId).setUri(iomAug.getUri()).build(); if (iovisorModuleManager.addProvisionedIovisorModule(iovisorModuleInstance)) { LOG.info("Provisioned IovisorModule {}}", iovisorModuleInstance.getId()); } else { LOG.error( "Error provisioning IovisorModule {} as part of processing Endpoint Tenant: {} L3C: {} IPAddress: {}", iovisorModuleInstance.getId(), endpoint.getTenant(), endpoint.getL3Context(), endpoint.getIpAddress()); return; } // This could be under the successful if test above but end goal with remote Agent is // that it registers so top test should go away if (iovisorModuleManager.addActiveIovisorModule(iovisorModuleInstance.getId())) { LOG.info("Activated IovisorModule {} as part of processing Endpoint Tenant: {} L3C: {} IPAddress: {}", iovisorModuleInstance.getId().getValue(), endpoint.getTenant().getValue(), endpoint.getL3Context().getValue(), endpoint.getIpAddress().getValue()); } else { LOG.error( "Error provisioning IovisorModule {} as part of processing Endpoint Tenant: {} L3C: {} IPAddress: {}", iovisorModuleInstance.getId().getValue(), endpoint.getTenant().getValue(), endpoint.getL3Context().getValue(), endpoint.getIpAddress().getValue()); return; } } if (addIovisorResolvedEndpoint(endpoint)) { LOG.info("Processed Endpoint Tenant {} L3Context: {} 1st IP Address: {}", endpoint.getTenant().getValue(), endpoint.getL3Context().getValue(), endpoint.getIpAddress().getValue()); return; } else { LOG.error( "Could not add to IovisorResolvedEndpoint store following Endpoint Tenant {} L3Context: {} 1st IP Address: {}", endpoint.getTenant().getValue(), endpoint.getL3Context().getValue(), endpoint.getIpAddress().getValue()); return; } } @VisibleForTesting boolean addIovisorResolvedEndpoint(EndpointL3 endpoint) { WriteTransaction wTx = dataBroker.newWriteOnlyTransaction(); wTx = addToIovisorResolvedEndpointDatastore(endpoint, wTx); wTx = addToIovisorResolvedEndpointByTenantByEndpointgroupId(endpoint, wTx); wTx = addToIovisorModulesByTenantByEndpointgroupId(endpoint, wTx); return DataStoreHelper.submitToDs(wTx); } @VisibleForTesting WriteTransaction addToIovisorModulesByTenantByEndpointgroupId(EndpointL3 endpoint, WriteTransaction wTx) { Set<EndpointGroupId> epgIds = new HashSet<>(); if (endpoint.getEndpointGroup() != null) epgIds.add(endpoint.getEndpointGroup()); if (endpoint.getEndpointGroups() != null) epgIds.addAll(endpoint.getEndpointGroups()); IovisorModuleInstanceId iomId = new IovisorModuleInstanceIdBuilder() .setId(new IovisorModuleId(endpoint.getAugmentation(IovisorModuleAugmentation.class).getUri().getValue())) .build(); List<IovisorModuleInstanceId> iomIds = ImmutableList.of(iomId); for (EndpointGroupId epg : epgIds) { IovisorModuleByTenantByEndpointgroupId data = new IovisorModuleByTenantByEndpointgroupIdBuilder() .setTenantId(endpoint.getTenant()).setEndpointgroupId(epg).setIovisorModuleInstanceId(iomIds).build(); wTx.merge(LogicalDatastoreType.OPERATIONAL, IovisorIidFactory.iovisorModuleByTenantIdByEndpointGroupIdIid(endpoint.getTenant(), epg), data, true); } return wTx; } @VisibleForTesting WriteTransaction addToIovisorResolvedEndpointByTenantByEndpointgroupId(EndpointL3 endpoint, WriteTransaction wTx) { Set<EndpointGroupId> epgIds = new HashSet<>(); if (endpoint.getEndpointGroup() != null) epgIds.add(endpoint.getEndpointGroup()); if (endpoint.getEndpointGroups() != null) epgIds.addAll(endpoint.getEndpointGroups()); IovisorEndpoint iovisorEndpoint = new IovisorEndpointBuilder().setIpAddress(endpoint.getIpAddress()) .setL3Context(endpoint.getL3Context()) .build(); List<IovisorEndpoint> iovisorEndpoints = ImmutableList.of(iovisorEndpoint); for (EndpointGroupId epg : epgIds) { IovisorResolvedEndpointByTenantByEndpointgroupId iovisorResolvedEndpointbyTenantByEndpointgroupId = new IovisorResolvedEndpointByTenantByEndpointgroupIdBuilder().setTenantId(endpoint.getTenant()) .setEndpointgroupId(epg) .setIovisorEndpoint(iovisorEndpoints) .build(); wTx.merge(LogicalDatastoreType.OPERATIONAL, IovisorIidFactory.iovisorResolvedEndpointByTenantIdByEndpointGroupIdIid(endpoint.getTenant(), epg), iovisorResolvedEndpointbyTenantByEndpointgroupId, true); LOG.trace("Added endpoint via endpoingGroups() to ResolvedEndpoints for {} {}", endpoint.getTenant().getValue(), epg.getValue()); } return wTx; } @VisibleForTesting WriteTransaction addToIovisorResolvedEndpointDatastore(EndpointL3 endpoint, WriteTransaction wTx) { IovisorResolvedEndpoint iovisorResolvedEndpoint = new IovisorResolvedEndpointBuilder() .setIpAddress(endpoint.getIpAddress()).setL3Context(endpoint.getL3Context()).build(); wTx.put(LogicalDatastoreType.OPERATIONAL, IovisorIidFactory.iovisorResolvedEndpointIid(endpoint.getL3Context(), endpoint.getIpAddress()), iovisorResolvedEndpoint, true); LOG.trace("Added endpoint to ResolvedEndpoints for {} {}", endpoint.getL3Context().getValue(), endpoint.getIpAddress().getValue()); return wTx; } @VisibleForTesting boolean isResolvedEndpointByTenantByEpg(final L3ContextId l3ContextId, final IpAddress ipAddr, TenantId tenantId, EndpointGroupId epgId) { Collection<IovisorEndpoint> filter = Collections2.filter(getResolvedEndpointsByTenantByEpg(tenantId, epgId), new Predicate<IovisorEndpoint>() { @Override public boolean apply(IovisorEndpoint input) { return (input.getL3Context().equals(l3ContextId) && input.getIpAddress().equals(ipAddr)); } }); if (filter.isEmpty()) return false; return true; } @VisibleForTesting Collection<IovisorEndpoint> getResolvedEndpointsByTenantByEpg(TenantId tenantId, EndpointGroupId epgId) { Optional<IovisorResolvedEndpointByTenantByEndpointgroupId> returnFromDs = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, IovisorIidFactory.iovisorResolvedEndpointByTenantIdByEndpointGroupIdIid(tenantId, epgId), dataBroker.newReadOnlyTransaction()); if (returnFromDs.isPresent()) return returnFromDs.get().getIovisorEndpoint(); return null; } @VisibleForTesting boolean isResolvedEndpoint(final L3ContextId l3ContextId, final IpAddress ipAddr) { Collection<IovisorResolvedEndpoint> filter = Collections2.filter(getResolvedEndpoints(), new Predicate<IovisorResolvedEndpoint>() { @Override public boolean apply(IovisorResolvedEndpoint input) { return (input.getL3Context().equals(l3ContextId) && input.getIpAddress().equals(ipAddr)); } }); if (filter.isEmpty()) return false; return true; } @VisibleForTesting Collection<IovisorResolvedEndpoint> getResolvedEndpoints() { Optional<IovisorResolvedEndpoints> returnFromDs = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, IovisorIidFactory.iovisorResolvedEndpointWildcardIid(), dataBroker.newReadOnlyTransaction()); if (returnFromDs.isPresent()) return returnFromDs.get().getIovisorResolvedEndpoint(); return null; } @Override public void close() throws Exception { if (iovisorEndpointAug != null) iovisorEndpointAug.close(); if (iovisorModuleListener != null) iovisorModuleListener.close(); if (endpointListener != null) endpointListener.close(); } }