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 java.util.Collection;
17 import java.util.Collections;
18 import javax.annotation.Nonnull;
19 import javax.annotation.Nullable;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPPolicyTemplateDaoFacade;
24 import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPPolicyTemplateProvider;
25 import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SgtGeneratorImpl;
26 import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SimpleCachedDao;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.SxpEpMapper;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.TemplateGenerated;
29 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;
30 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;
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.EndpointPolicyTemplateBySgtKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
38 * Purpose: add template provider fallback to {@link EPPolicyTemplateDaoImpl}
40 public class EPPolicyTemplateDaoFacadeImpl implements EPPolicyTemplateDaoFacade {
42 private static final Logger LOG = LoggerFactory.getLogger(EPPolicyTemplateDaoFacadeImpl.class);
44 private final EPPolicyTemplateDaoImpl epPolicyTemplateDao;
45 private final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateCachedDao;
46 private final SgtGeneratorImpl sgtGenerator;
47 private final DataBroker dataBroker;
49 private EPPolicyTemplateProvider templateProvider;
51 public EPPolicyTemplateDaoFacadeImpl(final DataBroker dataBroker, final EPPolicyTemplateDaoImpl epPolicyTemplateDao,
52 final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateCachedDao,
53 final SgtGeneratorImpl sgtGenerator) {
54 this.dataBroker = dataBroker;
55 this.epPolicyTemplateDao = epPolicyTemplateDao;
56 this.epPolicyTemplateCachedDao = epPolicyTemplateCachedDao;
57 this.sgtGenerator = sgtGenerator;
61 public void setTemplateProvider(final EPPolicyTemplateProvider templateProvider) {
62 this.templateProvider = templateProvider;
67 public ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> read(@Nonnull final Sgt key) {
69 final ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> templateFu = epPolicyTemplateDao.read(key);
71 // involve fallback if template is absent
72 return Futures.transformAsync(templateFu, new AsyncFunction<Optional<EndpointPolicyTemplateBySgt>, Optional<EndpointPolicyTemplateBySgt>>() {
74 public ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> apply(
75 @Nonnull final Optional<EndpointPolicyTemplateBySgt> templateOpt) throws Exception {
77 return templateOpt.transform(template -> Futures.immediateFuture(templateOpt))
78 // failed to read template -> invoke fallback if available
79 .or(() -> java.util.Optional.ofNullable(templateProvider)
80 .map(provider -> templateProvider.provideTemplate(key))
81 .map(template -> rewrapOptionalToGuavaOptional(template))
82 .orElse(Futures.immediateFuture(Optional.absent()))
88 private <T> ListenableFuture<Optional<T>> rewrapOptionalToGuavaOptional(final ListenableFuture<java.util.Optional<T>> templateFu) {
89 return Futures.transform(templateFu, new Function<java.util.Optional<T>, Optional<T>>() {
92 public Optional<T> apply(@Nullable final java.util.Optional<T> input) {
93 return java.util.Optional.ofNullable(input)
94 .map(origNonnullInput -> Optional.fromNullable(origNonnullInput.orElse(null)))
95 .orElse(Optional.absent());
102 private Function<Void, Collection<EndpointPolicyTemplateBySgt>> createStoreOutcomeHandlerToCollection(final EndpointPolicyTemplateBySgt template) {
103 return new Function<Void, Collection<EndpointPolicyTemplateBySgt>>() {
106 public Collection<EndpointPolicyTemplateBySgt> apply(@Nullable final Void aVoid) {
107 return Collections.singletonList(template);
113 public ListenableFuture<Collection<EndpointPolicyTemplateBySgt>> readBy(@Nonnull final EpPolicyTemplateValueKey templateLookupKey) {
114 //TODO: expose to ios-xe renderer,
115 final Collection<EndpointPolicyTemplateBySgt> templatesFromDao = epPolicyTemplateDao.readBy(templateLookupKey);
116 final ListenableFuture<Collection<EndpointPolicyTemplateBySgt>> result;
117 if (!templatesFromDao.isEmpty()) {
118 result = Futures.immediateFuture(templatesFromDao);
121 result = sgtGenerator.generateNextSgt(epPolicyTemplateCachedDao)
122 // build ep-policy-template
123 .map(sgt -> buildEpPolicyTemplate(templateLookupKey, sgt))
124 // store the template
125 .map(this::storeTemplate)
126 .orElse(Futures.immediateFuture(Collections.emptyList()));
131 private ListenableFuture<Collection<EndpointPolicyTemplateBySgt>> storeTemplate(final EndpointPolicyTemplateBySgt template) {
132 final WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
133 // store ep-policy-template
134 final Sgt sgt = template.getSgt();
135 LOG.trace("storing generated epPolicyTemplate: {}", sgt.getValue());
136 final InstanceIdentifier<EndpointPolicyTemplateBySgt> epPolicyTemplatePath = InstanceIdentifier
137 .create(SxpEpMapper.class)
138 .child(EndpointPolicyTemplateBySgt.class, new EndpointPolicyTemplateBySgtKey(sgt));
139 wTx.put(LogicalDatastoreType.CONFIGURATION, epPolicyTemplatePath, template, true);
141 return Futures.transform(wTx.submit(), createStoreOutcomeHandlerToCollection(template));
144 private EndpointPolicyTemplateBySgt buildEpPolicyTemplate(final EpPolicyTemplateValueKey templateLookupKey, final Sgt sgt) {
145 return new EndpointPolicyTemplateBySgtBuilder()
146 .setOrigin(TemplateGenerated.class)
147 .setTenant(templateLookupKey.getTenantId())
149 .setEndpointGroups(templateLookupKey.getEpgId())
150 .setConditions(templateLookupKey.getConditionName())