Implement nemo language style RPC.
[nemo.git] / nemo-impl / src / main / java / org / opendaylight / nemo / user / vnspacemanager / structurestyle / updateintent / UpdateOperation.java
1 /*\r
2  * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 package org.opendaylight.nemo.user.vnspacemanager.structurestyle.updateintent;\r
9 \r
10 import com.google.common.base.Optional;\r
11 import com.google.common.util.concurrent.*;\r
12 import com.google.common.base.Optional;\r
13 import com.google.common.util.concurrent.CheckedFuture;\r
14 import com.google.common.util.concurrent.FutureCallback;\r
15 import com.google.common.util.concurrent.Futures;\r
16 import com.google.common.util.concurrent.ListenableFuture;\r
17 import com.google.common.util.concurrent.SettableFuture;\r
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
19 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
21 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r
22 import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
23 import org.opendaylight.nemo.user.vnspacemanager.languagestyle.NEMOConstants;\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.ActionName;\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.ParameterName;\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Operations;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.OperationBuilder;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.OperationKey;\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.ActionDefinitions;\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.ConditionParameterDefinitions;\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.action.definitions.ActionDefinition;\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.action.instance.ParameterValues;\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.condition.instance.ConditionSegment;\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.condition.instance.condition.segment.ConditionParameterTargetValue;\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.condition.parameter.definitions.ConditionParameterDefinition;\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.condition.parameter.definitions.condition.parameter.definition.ParameterMatchPatterns;\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.operation.instance.Action;\r
46 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
47 import org.slf4j.Logger;\r
48 import org.slf4j.LoggerFactory;\r
49 \r
50 import java.util.HashMap;\r
51 import java.util.List;\r
52 import java.util.Map;\r
53 import java.util.concurrent.ExecutionException;\r
54 import java.util.concurrent.TimeUnit;\r
55 import java.util.concurrent.TimeoutException;\r
56 \r
57 /**\r
58  * Created by z00293636 on 2015/8/31.\r
59  */\r
60 public class UpdateOperation {\r
61 \r
62     private DataBroker dataBroker;\r
63     private TenantManage tenantManage;\r
64     private final SettableFuture<List<ActionDefinition>> actionDefinitionListFuture =  SettableFuture.create();\r
65     private final SettableFuture<List<ConditionParameterDefinition>> conditionParameterDefinitionListFuture = SettableFuture.create();\r
66     private ValueCheck valueCheck;\r
67     private static final Logger LOG = LoggerFactory.getLogger(UpdateOperation.class);\r
68 \r
69     public UpdateOperation(DataBroker dataBroker, TenantManage tenantManage){\r
70         this.dataBroker = dataBroker;\r
71         this.tenantManage = tenantManage;\r
72         valueCheck = new ValueCheck();\r
73     }\r
74 \r
75     public String OperationHandling(UserId userId, Operation operation){\r
76         String errorInfo = null;\r
77         errorInfo = checkDefinition(operation);\r
78         if (errorInfo!=null){\r
79             return errorInfo;\r
80         }\r
81         else {\r
82             errorInfo = checkInstance(userId,operation);\r
83             if (errorInfo!=null){\r
84                 return errorInfo;\r
85             }\r
86             else {\r
87                 WriteTransaction t = dataBroker.newWriteOnlyTransaction();\r
88                 if (userId != null && operation.getOperationId() != null)\r
89                 {\r
90                     Operation operation1 = new OperationBuilder(operation).build();\r
91                     OperationKey operationKey = new OperationKey(operation.getOperationId());\r
92 \r
93                     UserKey userKey = new UserKey(userId);\r
94 \r
95                     InstanceIdentifier<Operation> operationid = InstanceIdentifier.builder(Users.class).child(User.class, userKey).child(Operations.class).child(Operation.class,operationKey).build();\r
96                     t.put(LogicalDatastoreType.CONFIGURATION, operationid, operation1,true);\r
97                     CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();\r
98                     Futures.addCallback(f, new FutureCallback<Void>() {\r
99                         @Override\r
100                         public void onFailure(Throwable t) {\r
101                             LOG.error("Could not write endpoint base container", t);\r
102                         }\r
103 \r
104                         @Override\r
105                         public void onSuccess(Void result) {\r
106 \r
107                         }\r
108                     });\r
109                 }\r
110             }\r
111         }\r
112         return null;\r
113     }\r
114 \r
115     private String checkInstance(UserId userId, Operation operation){\r
116         String errorInfo = null;\r
117         tenantManage.fetchVNSpace(userId);\r
118         User user = tenantManage.getUser();\r
119 \r
120         if (operation.getPriority()==null){\r
121             errorInfo = "The priority should not be empty.";\r
122         }\r
123         if (operation.getTargetObject()==null){\r
124             errorInfo = "The target should not be empty.";\r
125         }\r
126         if (operation.getTargetObject()!=null){\r
127             if (user!=null){\r
128                 if (user.getObjects()!=null){\r
129                     Boolean targetExist = false;\r
130                     if (user.getObjects().getNode()!=null){\r
131                         List<Node> nodeList = user.getObjects().getNode();\r
132                         for (Node node : nodeList){\r
133                             if (node.getNodeId().getValue().equals(operation.getTargetObject().getValue())){\r
134                                 targetExist = true;\r
135                             }\r
136                         }\r
137                     }\r
138                     if (user.getObjects().getConnection()!=null){\r
139                         List<Connection> connectionList = user.getObjects().getConnection();\r
140                         for (Connection connection : connectionList){\r
141                             if (connection.getConnectionId().getValue().equals(operation.getTargetObject().getValue())){\r
142                                 targetExist = true;\r
143                             }\r
144                         }\r
145                     }\r
146                     if (user.getObjects().getFlow()!=null){\r
147                         List<Flow> flowList = user.getObjects().getFlow();\r
148                         for (Flow flow : flowList){\r
149                             if (flow.getFlowId().getValue().equals(operation.getTargetObject().getValue())){\r
150                                 targetExist = true;\r
151                             }\r
152                         }\r
153                     }\r
154                     if (!targetExist){\r
155                         errorInfo = "The target object is not exist.";\r
156                     }\r
157                 }\r
158                 else {\r
159                     errorInfo = "The target object is not exist.";\r
160                 }\r
161             }\r
162             else {\r
163                 errorInfo = "The target object is not exist.";\r
164             }\r
165         }\r
166         if (user!=null){\r
167             if (user.getOperations()!=null){\r
168                 if (user.getOperations().getOperation()!=null){\r
169                     List<Operation> operationList = user.getOperations().getOperation();\r
170                     for (Operation operation1 : operationList){\r
171                         if (operation.getOperationId().equals(operation1.getOperationId())){\r
172                             if (!operation.getOperationName().equals(operation1.getOperationName())){\r
173                                 errorInfo="The operation name should not be changed.";\r
174                                 return errorInfo;\r
175                             }\r
176                         }\r
177                     }\r
178                 }\r
179             }\r
180         }\r
181         return errorInfo;\r
182     }\r
183 \r
184     private String checkDefinition(Operation operation){\r
185         fetchActionDefinitions();\r
186         fetchConditionParaDefinitions();\r
187         String errorInfo = null;\r
188 \r
189         if (operation.getAction() != null )\r
190         {\r
191             errorInfo = checkAction(operation);\r
192         }\r
193         if (errorInfo == null && operation.getConditionSegment() != null)\r
194         {\r
195             errorInfo = checkCondition(operation);\r
196         }\r
197         return errorInfo;\r
198     }\r
199 \r
200     private String checkAction(Operation operation){\r
201         String errorInfo = null;\r
202 \r
203         fetchActionDefinitions();\r
204         Map<ActionName, ActionDefinition> actionDefinitionMap = getActionDefinition();\r
205         if (operation.getAction()!=null){\r
206             if (actionDefinitionMap.isEmpty()){\r
207                 return "The action type has not been defined.";\r
208             }\r
209             else {\r
210                 for (Action action : operation.getAction()){\r
211                     if (actionDefinitionMap.containsKey(action.getActionName())){\r
212                         ParameterValues parameterValues = action.getParameterValues();\r
213                         ActionDefinition.ParameterValueType parameterValueType = actionDefinitionMap.get(action.getActionName()).getParameterValueType();\r
214 \r
215                         if (parameterValues != null && parameterValueType != null)\r
216                         {\r
217                             if (parameterValueType.getIntValue() == 0 && !(parameterValues.getIntValue() == null && parameterValues.getStringValue() != null && parameterValues.getRangeValue() == null)) {\r
218                                 errorInfo = "The value type of" + action.getActionName().toString() + "should be string.";\r
219                                 break;\r
220                             }\r
221                             if (parameterValueType.getIntValue() == 1 && !(parameterValues.getIntValue() != null && parameterValues.getStringValue() == null && parameterValues.getRangeValue() == null)) {\r
222                                 errorInfo = "The value type of" + action.getActionName().toString() + "should be integer.";\r
223                                 break;\r
224                             }\r
225                             if (parameterValueType.getIntValue() == 2 && !(parameterValues.getIntValue() == null && parameterValues.getStringValue() == null && parameterValues.getRangeValue() != null)) {\r
226                                 errorInfo = "The value type of" + action.getActionName().toString() + "should be range.";\r
227                                 break;\r
228                             }\r
229                         }\r
230                     }\r
231                     else {\r
232                         return "The action type has not been defined.";\r
233                     }\r
234                 }\r
235             }\r
236         }\r
237         return errorInfo;\r
238     }\r
239 \r
240     private String checkCondition(Operation operation){\r
241         String errorInfo = null;\r
242         fetchConditionParaDefinitions();\r
243         Map<ParameterName, ConditionParameterDefinition> conditionParameterDefinitionMap = getParameterMatchPattern();\r
244         if (operation.getConditionSegment()!=null){\r
245             if (conditionParameterDefinitionMap.isEmpty()){\r
246                 return "This condition has not been defined in data store.";\r
247             }\r
248             else {\r
249                 for (ConditionSegment conditionSegment :operation.getConditionSegment()){\r
250                     if (conditionParameterDefinitionMap.containsKey(conditionSegment.getConditionParameterName())){\r
251                         ConditionParameterDefinition conditionParameterDefinition = conditionParameterDefinitionMap.get(conditionSegment.getConditionParameterName());\r
252 \r
253                         if (conditionSegment.getConditionParameterMatchPattern() != null)\r
254                         {\r
255                             if (conditionParameterDefinition.getParameterMatchPatterns() != null)\r
256                             {\r
257                                 List<ParameterMatchPatterns.ParameterMatchPattern> conditionParameterMatchPatterns = conditionParameterDefinition.getParameterMatchPatterns().getParameterMatchPattern();\r
258                                 if (conditionParameterMatchPatterns != null)\r
259                                 {\r
260                                     Boolean matchpatternexist = false;\r
261                                     for (ParameterMatchPatterns.ParameterMatchPattern parameterMatchPattern : conditionParameterMatchPatterns)\r
262                                     {\r
263                                         if (parameterMatchPattern.getIntValue() == conditionSegment.getConditionParameterMatchPattern().getIntValue())\r
264                                         {\r
265                                             matchpatternexist = true;\r
266                                             break;\r
267                                         }\r
268                                     }\r
269                                     if (!matchpatternexist)\r
270                                     {\r
271                                         errorInfo = "The match pattern has not defined in the condition.";\r
272                                     }\r
273                                 }\r
274                                 else\r
275                                 {\r
276                                     errorInfo = "There are no match pattern in match pattrn list.";\r
277                                     break;\r
278                                 }\r
279                             }\r
280                             else\r
281                             {\r
282                                 errorInfo = "No match patterns have been defined in data store.";\r
283                                 break;\r
284                             }\r
285                         }\r
286                         if (conditionSegment.getConditionParameterTargetValue() != null)\r
287                         {\r
288                             if (conditionParameterDefinition.getParameterValueType() != null)\r
289                             {\r
290                                 ConditionParameterTargetValue conditionParameterTargetValue = conditionSegment.getConditionParameterTargetValue();\r
291                                 ConditionParameterDefinition.ParameterValueType  parameterValueType = conditionParameterDefinition.getParameterValueType();\r
292 \r
293                                 if (parameterValueType.getIntValue() == 0 && !(conditionParameterTargetValue.getIntValue() == null && conditionParameterTargetValue.getStringValue() != null && conditionParameterTargetValue.getRangeValue() == null)) {\r
294                                     errorInfo = "The value type of " + conditionSegment.getConditionParameterName().getValue() + " should be string.";\r
295                                     break;\r
296                                 }\r
297                                 if (parameterValueType.getIntValue() == 1 && !(conditionParameterTargetValue.getIntValue() != null && conditionParameterTargetValue.getStringValue() == null && conditionParameterTargetValue.getRangeValue() == null)) {\r
298                                     errorInfo = "The value type of " + conditionSegment.getConditionParameterName().getValue() + " should be integer.";\r
299                                     break;\r
300                                 }\r
301                                 if (parameterValueType.getIntValue() == 2 && !(conditionParameterTargetValue.getIntValue() == null && conditionParameterTargetValue.getStringValue() == null && conditionParameterTargetValue.getRangeValue() != null)) {\r
302                                     errorInfo = "The value type of " + conditionSegment.getConditionParameterName().getValue() + " should be range.";\r
303                                     break;\r
304                                 }\r
305 \r
306                             }\r
307                         }\r
308                         if (conditionSegment.getConditionParameterName().getValue().equals(NEMOConstants.time)){\r
309                             Boolean legalValue = valueCheck.checkTime(conditionSegment.getConditionParameterTargetValue().getStringValue());\r
310                             if (!legalValue){\r
311                                 errorInfo = "The " + NEMOConstants.time + " is not legal.";\r
312                                 break;\r
313                             }\r
314                         }\r
315                     }\r
316                     else {\r
317                         return "This condition has not been defined in data store.";\r
318                     }\r
319                 }\r
320             }\r
321         }\r
322         return errorInfo;\r
323     }\r
324 \r
325     private void fetchActionDefinitions(){\r
326         InstanceIdentifier<ActionDefinitions> actiondefinitionId = InstanceIdentifier.builder(ActionDefinitions.class).build();\r
327         ListenableFuture<Optional<ActionDefinitions>> actiondefinitionFuture = dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, actiondefinitionId);\r
328         Futures.addCallback(actiondefinitionFuture, new FutureCallback<Optional<ActionDefinitions>>() {\r
329             @Override\r
330             public void onSuccess(Optional<ActionDefinitions> result) {\r
331                 setActionDefinitionListFuture( result.get().getActionDefinition());\r
332             }\r
333 \r
334             @Override\r
335             public void onFailure(Throwable t) {\r
336                 LOG.error("Can not read action definition information.", t);\r
337             }\r
338         });\r
339         return ;\r
340     }\r
341 \r
342     private void fetchConditionParaDefinitions(){\r
343         InstanceIdentifier<ConditionParameterDefinitions> conditionparadefinitionId = InstanceIdentifier.builder(ConditionParameterDefinitions.class).build();\r
344         ListenableFuture<Optional<ConditionParameterDefinitions>> conditionparadefinitionFuture = dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, conditionparadefinitionId);\r
345         Futures.addCallback(conditionparadefinitionFuture, new FutureCallback<Optional<ConditionParameterDefinitions>>() {\r
346             @Override\r
347             public void onSuccess(Optional<ConditionParameterDefinitions> result) {\r
348                setConditionParameterDefinitionListFuture(result.get().getConditionParameterDefinition());\r
349             }\r
350 \r
351             @Override\r
352             public void onFailure(Throwable t) {\r
353                 LOG.error("Can not read condition parameter definition information.", t);\r
354             }\r
355         });\r
356         return ;\r
357     }\r
358 \r
359     private void setConditionParameterDefinitionListFuture(List<ConditionParameterDefinition> conditionParameterDefinitions){\r
360         this.conditionParameterDefinitionListFuture.set(conditionParameterDefinitions);\r
361     }\r
362 \r
363     private void setActionDefinitionListFuture(List<ActionDefinition> actionDefinitions){\r
364         this.actionDefinitionListFuture.set(actionDefinitions);\r
365     }\r
366 \r
367     private List<ConditionParameterDefinition> getConditionParameterDefinitionList(){\r
368         try{\r
369             return conditionParameterDefinitionListFuture.get(1, TimeUnit.SECONDS);\r
370         }catch (InterruptedException | ExecutionException | TimeoutException e) {\r
371             LOG.error("Cannot read role information.", e);\r
372             return null;\r
373         }\r
374     }\r
375 \r
376     private List<ActionDefinition> getActionDefinitionList(){\r
377         try{\r
378             return actionDefinitionListFuture.get(1, TimeUnit.SECONDS);\r
379         }catch (InterruptedException | ExecutionException | TimeoutException e) {\r
380             LOG.error("Cannot read role information.", e);\r
381             return null;\r
382         }\r
383     }\r
384 \r
385     private Map<ParameterName, ConditionParameterDefinition> getParameterMatchPattern(){\r
386         List<ConditionParameterDefinition> conditionParameterDefinitions = getConditionParameterDefinitionList();\r
387         Map<ParameterName, ConditionParameterDefinition> conditionParameterDefinitionMap = new HashMap<ParameterName, ConditionParameterDefinition>();\r
388         if (conditionParameterDefinitions!=null){\r
389             for (ConditionParameterDefinition conditionParameterDefinition : conditionParameterDefinitions){\r
390                 conditionParameterDefinitionMap.put(conditionParameterDefinition.getParameterName(),conditionParameterDefinition);\r
391             }\r
392         }\r
393         return conditionParameterDefinitionMap;\r
394     }\r
395 \r
396     private Map<ActionName, ActionDefinition> getActionDefinition(){\r
397         List<ActionDefinition> actionDefinitions = getActionDefinitionList();\r
398         Map<ActionName,ActionDefinition> actionDefinitionMap = new HashMap<ActionName, ActionDefinition>();\r
399         if (actionDefinitionMap!=null){\r
400             for (ActionDefinition actionDefinition : actionDefinitions){\r
401                 actionDefinitionMap.put(actionDefinition.getActionName(),actionDefinition);\r
402             }\r
403         }\r
404         return actionDefinitionMap;\r
405     }\r
406 }\r