2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao;
11 import com.google.common.base.Function;
12 import com.google.common.base.Optional;
13 import com.google.common.util.concurrent.AsyncFunction;
14 import com.google.common.util.concurrent.Futures;
15 import com.google.common.util.concurrent.ListenableFuture;
16 import com.google.common.util.concurrent.MoreExecutors;
18 import java.util.Collection;
19 import java.util.Collections;
20 import javax.annotation.Nonnull;
21 import javax.annotation.Nullable;
22 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
23 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPPolicyTemplateDaoFacade;
26 import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPPolicyTemplateProvider;
27 import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SgtGeneratorImpl;
28 import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SimpleCachedDao;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.SxpEpMapper;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.TemplateGenerated;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgtBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgtKey;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * Purpose: add template provider fallback to {@link EPPolicyTemplateDaoImpl}
42 public class EPPolicyTemplateDaoFacadeImpl implements EPPolicyTemplateDaoFacade {
44 private static final Logger LOG = LoggerFactory.getLogger(EPPolicyTemplateDaoFacadeImpl.class);
46 private final EPPolicyTemplateDaoImpl epPolicyTemplateDao;
47 private final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateCachedDao;
48 private final SgtGeneratorImpl sgtGenerator;
49 private final DataBroker dataBroker;
51 private EPPolicyTemplateProvider templateProvider;
53 public EPPolicyTemplateDaoFacadeImpl(final DataBroker dataBroker, final EPPolicyTemplateDaoImpl epPolicyTemplateDao,
54 final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateCachedDao,
55 final SgtGeneratorImpl sgtGenerator) {
56 this.dataBroker = dataBroker;
57 this.epPolicyTemplateDao = epPolicyTemplateDao;
58 this.epPolicyTemplateCachedDao = epPolicyTemplateCachedDao;
59 this.sgtGenerator = sgtGenerator;
63 public void setTemplateProvider(final EPPolicyTemplateProvider templateProvider) {
64 this.templateProvider = templateProvider;
69 public ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> read(@Nonnull final Sgt key) {
71 final ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> templateFu = epPolicyTemplateDao.read(key);
73 // involve fallback if template is absent
74 return Futures.transformAsync(templateFu, new AsyncFunction<Optional<EndpointPolicyTemplateBySgt>, Optional<EndpointPolicyTemplateBySgt>>() {
76 public ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> apply(
77 @Nonnull final Optional<EndpointPolicyTemplateBySgt> templateOpt) throws Exception {
79 return templateOpt.transform(template -> Futures.immediateFuture(templateOpt))
80 // failed to read template -> invoke fallback if available
81 .or(() -> java.util.Optional.ofNullable(templateProvider)
82 .map(provider -> templateProvider.provideTemplate(key))
83 .map(template -> rewrapOptionalToGuavaOptional(template))
84 .orElse(Futures.immediateFuture(Optional.absent()))
87 }, MoreExecutors.directExecutor());
90 private <T> ListenableFuture<Optional<T>> rewrapOptionalToGuavaOptional(final ListenableFuture<java.util.Optional<T>> templateFu) {
91 return Futures.transform(templateFu, new Function<java.util.Optional<T>, Optional<T>>() {
94 public Optional<T> apply(@Nullable final java.util.Optional<T> input) {
95 return java.util.Optional.ofNullable(input)
96 .map(origNonnullInput -> Optional.fromNullable(origNonnullInput.orElse(null)))
97 .orElse(Optional.absent());
100 MoreExecutors.directExecutor());
104 private Function<Void, Collection<EndpointPolicyTemplateBySgt>> createStoreOutcomeHandlerToCollection(final EndpointPolicyTemplateBySgt template) {
105 return new Function<Void, Collection<EndpointPolicyTemplateBySgt>>() {
108 public Collection<EndpointPolicyTemplateBySgt> apply(@Nullable final Void aVoid) {
109 return Collections.singletonList(template);
115 public ListenableFuture<Collection<EndpointPolicyTemplateBySgt>> readBy(@Nonnull final EpPolicyTemplateValueKey templateLookupKey) {
116 //TODO: expose to ios-xe renderer,
117 final Collection<EndpointPolicyTemplateBySgt> templatesFromDao = epPolicyTemplateDao.readBy(templateLookupKey);
118 final ListenableFuture<Collection<EndpointPolicyTemplateBySgt>> result;
119 if (!templatesFromDao.isEmpty()) {
120 result = Futures.immediateFuture(templatesFromDao);
123 result = sgtGenerator.generateNextSgt(epPolicyTemplateCachedDao)
124 // build ep-policy-template
125 .map(sgt -> buildEpPolicyTemplate(templateLookupKey, sgt))
126 // store the template
127 .map(this::storeTemplate)
128 .orElse(Futures.immediateFuture(Collections.emptyList()));
133 private ListenableFuture<Collection<EndpointPolicyTemplateBySgt>> storeTemplate(final EndpointPolicyTemplateBySgt template) {
134 final WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
135 // store ep-policy-template
136 final Sgt sgt = template.getSgt();
137 LOG.trace("storing generated epPolicyTemplate: {}", sgt.getValue());
138 final InstanceIdentifier<EndpointPolicyTemplateBySgt> epPolicyTemplatePath = InstanceIdentifier
139 .create(SxpEpMapper.class)
140 .child(EndpointPolicyTemplateBySgt.class, new EndpointPolicyTemplateBySgtKey(sgt));
141 wTx.put(LogicalDatastoreType.CONFIGURATION, epPolicyTemplatePath, template, true);
143 return Futures.transform(wTx.submit(), createStoreOutcomeHandlerToCollection(template),
144 MoreExecutors.directExecutor());
147 private EndpointPolicyTemplateBySgt buildEpPolicyTemplate(final EpPolicyTemplateValueKey templateLookupKey, final Sgt sgt) {
148 return new EndpointPolicyTemplateBySgtBuilder()
149 .setOrigin(TemplateGenerated.class)
150 .setTenant(templateLookupKey.getTenantId())
152 .setEndpointGroups(templateLookupKey.getEpgId())
153 .setConditions(templateLookupKey.getConditionName())