BUG-6650: ep-ip/sgt, implement and wire template provider
[groupbasedpolicy.git] / sxp-integration / sxp-ise-adapter / src / main / java / org / opendaylight / groupbasedpolicy / sxp_ise_adapter / impl / EPPolicyTemplateProviderIseImpl.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.groupbasedpolicy.sxp_ise_adapter.impl;
10
11 import com.google.common.collect.Range;
12 import com.sun.jersey.api.client.Client;
13 import com.sun.jersey.api.client.WebResource;
14 import java.util.Collections;
15 import java.util.Optional;
16 import javax.annotation.Nonnull;
17 import javax.annotation.Nullable;
18 import javax.xml.xpath.XPath;
19 import javax.xml.xpath.XPathConstants;
20 import org.opendaylight.groupbasedpolicy.sxp_ise_adapter.impl.util.IseReplyUtil;
21 import org.opendaylight.groupbasedpolicy.sxp_ise_adapter.impl.util.RestClientFactory;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.sxp.ise.adapter.model.rev160630.gbp.sxp.ise.adapter.IseSourceConfig;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.sxp.ise.adapter.model.rev160630.gbp.sxp.ise.adapter.ise.source.config.ConnectionConfig;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.TemplateGenerated;
27 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;
28 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;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32 import org.w3c.dom.Node;
33
34 /**
35  * Purpose: query ise in order to get name of sgt for given tenant and build {@link EndpointPolicyTemplateBySgt}
36  */
37 public class EPPolicyTemplateProviderIseImpl implements EPPolicyTemplateProviderFacade {
38
39     private static final Logger LOG = LoggerFactory.getLogger(EPPolicyTemplateProviderIseImpl.class);
40
41     private Optional<IseSourceConfig> iseSourceConfig = Optional.empty();
42
43     @Override
44     public Optional<EndpointPolicyTemplateBySgt> provideTemplate(@Nonnull final Sgt sgt) {
45         return findIseSourceConfigBySgt(sgt)
46                 .flatMap(iseSourceConfig -> queryIseOnSgt(iseSourceConfig.getConnectionConfig(), sgt)
47                         .map(sgtName -> buildTemplate(sgt, iseSourceConfig.getTenant(), sgtName)));
48     }
49
50     private EndpointPolicyTemplateBySgt buildTemplate(final @Nonnull Sgt sgt, final @Nonnull TenantId tenantId,
51                                                       final @Nonnull String sgtName) {
52         return new EndpointPolicyTemplateBySgtBuilder()
53                 .setSgt(sgt)
54                 .setEndpointGroups(Collections.singletonList(new EndpointGroupId(sgtName)))
55                 .setTenant(tenantId)
56                 // no conditions
57                 .setOrigin(TemplateGenerated.class)
58                 .build();
59     }
60
61     private Optional<String> queryIseOnSgt(final ConnectionConfig connectionConfig, final Sgt sgt) {
62         String sgtName = null;
63         try {
64             final Client iseClient = RestClientFactory.createIseClient(connectionConfig);
65             final WebResource baseWebResource = iseClient.resource(connectionConfig.getIseRestUrl().getValue());
66
67             final String pathToSgtDetail = String.format("%s/%d", RestClientFactory.PATH_ERS_CONFIG_SGT, sgt.getValue());
68             final WebResource.Builder requestBuilder = RestClientFactory.createRequestBuilder(baseWebResource,
69                     connectionConfig.getHeader(), pathToSgtDetail);
70             final String rawSgtDetail = IseReplyUtil.deliverResponse(requestBuilder);
71
72             final XPath xpath = IseReplyUtil.setupXpath();
73             final Node sgtNameNode = (Node) xpath.evaluate(
74                     IseReplyUtil.EXPRESSION_SGT_NAME_ATTR, IseReplyUtil.createInputSource(rawSgtDetail),
75                     XPathConstants.NODE);
76             sgtName = sgtNameNode.getNodeValue();
77             LOG.debug("obtained sgt/name: {}/{}", sgt.getValue(), sgtName);
78         } catch (Exception e) {
79             LOG.debug("failed to read sgt detail on ISE", e);
80         }
81         return Optional.ofNullable(sgtName);
82     }
83
84     private Optional<IseSourceConfig> findIseSourceConfigBySgt(final Sgt sgt) {
85         //TODO: cover multiple sources / tenants .. lookup (option: multiple servers per tenant?)
86         return iseSourceConfig
87                 .filter(config ->
88                         Range.closed(config.getSgtRangeMin().getValue(), config.getSgtRangeMax().getValue())
89                                 .contains(sgt.getValue()));
90     }
91
92     @Override
93     public void assignIseSourceConfig(final @Nullable IseSourceConfig iseSourceConfig) {
94         this.iseSourceConfig = Optional.ofNullable(iseSourceConfig);
95     }
96 }