dda5447d224863684e70d5c79a4fd7a734cc0f09
[vpnservice.git] / vpnintent / impl / src / main / java / org / opendaylight / vpnservice / impl / IntentServiceManager.java
1 /*
2  * Copyright (c) 2016 Inocybe Technologies 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.vpnservice.impl;
10
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.UUID;
14
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.nic.utils.MdsalUtils;
18 import org.opendaylight.vpnservice.utils.IidFactory;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.constraints.rev150122.FailoverType;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.Intents;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.IntentsBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.Actions;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.ActionsBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.Constraints;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.ConstraintsBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.Subjects;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.SubjectsBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.actions.action.allow.AllowBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.actions.action.block.BlockBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.constraints.constraints.failover.constraint.FailoverConstraintBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.constraints.constraints.protection.constraint.ProtectionConstraintBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.end.point.group.EndPointGroup;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.end.point.group.EndPointGroupBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intents.Intent;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intents.IntentBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intents.IntentKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.types.rev150122.Uuid;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 import com.google.common.base.Preconditions;
43
44
45 public class IntentServiceManager {
46
47     /**
48      * This class is used to build Intents object and
49      * write it to Network Intent Composition md-sal tree
50      * in order to create/delete intents between two endpoint groups.
51      */
52
53     private static final Logger LOG = LoggerFactory.getLogger(IntentServiceManager.class);
54     private static final short FIRST_SUBJECT = 1;
55     private static final short SECOND_SUBJECT = 2;
56     public static final String ACTION_ALLOW = "ALLOW";
57     public static final String ACTION_BLOCK = "BLOCK";
58     public static final String FAST_REROUTE = "fast-reroute";
59     public static final String SLOW_REROUTE = "slow-reroute";
60     private final DataBroker dataBroker;
61     private static final InstanceIdentifier<Intents> INTENTS_IID = IidFactory.getIntentsIid();
62     private MdsalUtils mdsal;
63
64     public IntentServiceManager(DataBroker dataBroker) {
65         this.dataBroker = dataBroker;
66         this.mdsal = new MdsalUtils(dataBroker);
67     }
68
69     /**
70      * Create Intents object and write to to config tree to trigger intents
71      * @param src :Source Site Name
72      * @param dst :Destination Site Name
73      * @param intentAction :Intent verb: ALLOW or BLOCK
74      * @param failOverType
75      */
76     public void addIntent(String src, String dst, String intentAction, String failOverType) {
77         Preconditions.checkNotNull(src);
78         Preconditions.checkNotNull(dst);
79         Preconditions.checkNotNull(intentAction);
80
81         List<Intent> intentList = null;
82         List<Subjects> subjects = createSubjects(dst, src);
83         List<Actions> intentActions = createActions(intentAction);
84         List<Constraints> intentConstraints = createConstraints(failOverType);
85
86         Intent intent  = new IntentBuilder().setId(new Uuid(UUID.randomUUID().toString()))
87                 .setSubjects(subjects).setActions(intentActions)
88                 .setConstraints(intentConstraints)
89                 .build();
90
91         Intents currentIntents = mdsal.read(LogicalDatastoreType.CONFIGURATION, INTENTS_IID);
92         if (currentIntents == null) {
93             intentList = new ArrayList<>();
94         } else {
95             intentList = currentIntents.getIntent();
96         }
97         intentList.add(intent);
98         Intents intents = new IntentsBuilder().setIntent(intentList).build();
99         mdsal.put(LogicalDatastoreType.CONFIGURATION, INTENTS_IID, intents);
100         LOG.info("AddIntent: config populated: {}", intents);
101     }
102
103     /**
104      * Delete an Intent
105      * @param id :Uuid of the Intent to be deleted
106      */
107     public void removeIntent(Uuid id) {
108         Preconditions.checkNotNull(id);
109         InstanceIdentifier<Intent> iid = InstanceIdentifier.create(Intents.class).child(Intent.class, new IntentKey(id));
110         mdsal.delete(LogicalDatastoreType.CONFIGURATION, iid);
111         LOG.info("RemoveIntent succeeded");
112     }
113
114     /**
115      * Remove all associated intents by endpointGroupName
116      * @param endpointGroupName
117      */
118     public void removeIntentsByEndpoint(String endpointGroupName) {
119         Preconditions.checkNotNull(endpointGroupName);
120
121         Intents intents = mdsal.read(LogicalDatastoreType.CONFIGURATION, INTENTS_IID);
122
123         if (intents != null && intents.getIntent() != null) {
124             for (Intent intent : intents.getIntent()) {
125                 if (intent.getSubjects() != null && intent.getSubjects().size() > 0) {
126                     String endpointValue = "";
127                     for (Subjects subject : intent.getSubjects()) {
128                         if (subject
129                                 .getSubject() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroup) {
130                             org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroup epg = (org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroup) subject
131                                     .getSubject();
132                             endpointValue = epg.getEndPointGroup().getName();
133                         } else if (subject
134                                 .getSubject() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointSelector) {
135                             org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointSelector epg = (org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointSelector) subject
136                                     .getSubject();
137                             endpointValue = epg.getEndPointSelector().getEndPointSelector();
138                         } else if (subject
139                                 .getSubject() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroupSelector) {
140                             org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroupSelector epg = (org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroupSelector) subject
141                                     .getSubject();
142                             endpointValue = epg.getEndPointGroupSelector().getEndPointGroupSelector();
143                         }
144                         if (endpointValue.equalsIgnoreCase(endpointGroupName)) {
145                             removeIntent(intent.getId());
146                             LOG.info("Deleted Intent ID : {} for endpoint: {}", intent.getId(), endpointGroupName);
147                         }
148                     }
149                 }
150             }
151         }
152     }
153
154     /**
155      * Create a list of Intent actions
156      * @param intentAction
157      * @return :a list of Actions
158      */
159     private List<Actions> createActions(String intentAction) {
160         List<Actions> actionsList = new ArrayList<Actions>();
161         short order = 1;
162         org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.actions.Action action = null;
163         if (intentAction.equalsIgnoreCase(ACTION_ALLOW)) {
164             action = new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.actions.action
165                     .AllowBuilder().setAllow(new AllowBuilder().build()).build();
166         } else if (intentAction.equalsIgnoreCase(ACTION_BLOCK)) {
167             action = new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.actions.action
168                     .BlockBuilder().setBlock(new BlockBuilder().build()).build();
169         }
170
171         Actions intentActions = new ActionsBuilder().setOrder(order).setAction(action).build();
172         actionsList.add(intentActions);
173         return actionsList;
174     }
175
176     /**
177      * Create a list of Intent subjects
178      * @param src :Source Site Name
179      * @param dst :Destination Site Name
180      * @return :a list of Subjects
181      */
182     private List<Subjects> createSubjects(String src, String dst) {
183         List<Subjects> subjectList = new ArrayList<Subjects>();
184
185         EndPointGroup endpointGroupFrom = new EndPointGroupBuilder().setName(src).build();
186         org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroup fromEPG =
187                 new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject
188                 .EndPointGroupBuilder().setEndPointGroup(endpointGroupFrom).build();
189         Subjects subjects1 = new SubjectsBuilder().setOrder(FIRST_SUBJECT).setSubject(fromEPG).build();
190
191         EndPointGroup endpointGroupTo = new EndPointGroupBuilder().setName(dst).build();
192         org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroup toEPG =
193                 new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject
194                 .EndPointGroupBuilder().setEndPointGroup(endpointGroupTo).build();
195         Subjects subjects2 = new SubjectsBuilder().setOrder(SECOND_SUBJECT).setSubject(toEPG).build();
196
197         subjectList.add(subjects1);
198         subjectList.add(subjects2);
199         return subjectList;
200     }
201
202     /**
203      * Create a list of Intent constraints
204      * @param failOverType :Type of failover, fast-reroute or slow-reroute
205      * @return
206      */
207     private List<Constraints> createConstraints(String failOverType) {
208         List<Constraints> intentConstraints = new ArrayList<Constraints>();
209         if (failOverType==null) {
210             return intentConstraints;
211         }
212         short order = 1;
213         org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.constraints.Constraints
214             protectionConstraint = null;
215         org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.constraints.Constraints
216             failoverConstraint = null;
217         if (failOverType.equals(FAST_REROUTE)) {
218             protectionConstraint = new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent
219                     .constraints.constraints.ProtectionConstraintBuilder()
220                     .setProtectionConstraint(new ProtectionConstraintBuilder().setIsProtected(true).build()).build();
221             failoverConstraint = new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.constraints
222                     .constraints.FailoverConstraintBuilder()
223                     .setFailoverConstraint(new FailoverConstraintBuilder().setFailoverSelector(FailoverType.FastReroute).build())
224                     .build();
225         } else if (failOverType.equals(SLOW_REROUTE)) {
226             protectionConstraint = new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent
227                     .constraints.constraints.ProtectionConstraintBuilder()
228                     .setProtectionConstraint(new ProtectionConstraintBuilder().setIsProtected(true).build()).build();
229             failoverConstraint = new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.constraints
230                     .constraints.FailoverConstraintBuilder()
231                     .setFailoverConstraint(new FailoverConstraintBuilder().setFailoverSelector(FailoverType.SlowReroute).build())
232                     .build();
233         }
234         Constraints constraint1 = new ConstraintsBuilder().setOrder(order).setConstraints(protectionConstraint).build();
235         Constraints constraint2 = new ConstraintsBuilder().setOrder(++order).setConstraints(failoverConstraint).build();
236         intentConstraints.add(constraint1);
237         intentConstraints.add(constraint2);
238         return intentConstraints;
239     }
240 }