blob: 86eccfad343709cec1a55da75d154b14d373e146 [file] [log] [blame]
jaegonkim6a7b5242018-09-12 23:09:42 +09001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.workflow.impl;
17
18import org.onosproject.core.ApplicationId;
19import org.onosproject.net.config.ConfigFactory;
20import org.onosproject.net.config.NetworkConfigEvent;
21import org.onosproject.net.config.NetworkConfigListener;
22import org.onosproject.net.config.basics.SubjectFactories;
23import org.onosproject.workflow.api.DefaultWorkflowDescription;
24import org.onosproject.workflow.api.RpcDescription;
25import org.onosproject.workflow.api.WorkflowService;
26import org.onosproject.workflow.api.WorkflowException;
27import org.onosproject.workflow.api.DefaultWorkplaceDescription;
28import org.slf4j.Logger;
29import org.slf4j.LoggerFactory;
30
31import java.util.Collection;
32import java.util.HashMap;
33import java.util.Map;
34import java.util.concurrent.ScheduledExecutorService;
35
36import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
37import static org.onlab.util.Tools.groupedThreads;
38
39public class WorkflowNetConfigListener implements NetworkConfigListener {
40
41 private static final Logger log = LoggerFactory.getLogger(WorkflowNetConfigListener.class);
42
43 public static final String CONFIG_KEY = "workflow";
44 public static final String EXECUTOR_GROUPNAME = "onos/workflow-netcfg";
45 public static final String EXECUTOR_PATTERN = "netcfg-event-handler";
46
gyewan.anecb32692019-07-10 14:36:58 +090047 public static final String WORKPLACE_CREATE = "workplace.create";
48 public static final String WORKPLACE_REMOVE = "workplace.remove";
49 public static final String WORKFLOW_INVOKE = "workflow.invoke";
50 public static final String WORKFLOW_TERMINATE = " workflow.terminate";
51
jaegonkim6a7b5242018-09-12 23:09:42 +090052 private final ConfigFactory<ApplicationId, WorkflowNetConfig> configFactory =
53 new ConfigFactory<ApplicationId, WorkflowNetConfig>(
54 SubjectFactories.APP_SUBJECT_FACTORY, WorkflowNetConfig.class, CONFIG_KEY) {
55 @Override
56 public WorkflowNetConfig createConfig() {
57 return new WorkflowNetConfig();
58 }
59 };
60
61 private final WorkflowService workflowService;
62
63 private final ScheduledExecutorService executor =
64 newSingleThreadScheduledExecutor(groupedThreads(EXECUTOR_GROUPNAME, EXECUTOR_PATTERN));
65
66 public WorkflowNetConfigListener(WorkflowService workflowService) {
67 this.workflowService = workflowService;
68 }
69
70 public ConfigFactory<ApplicationId, WorkflowNetConfig> getConfigFactory() {
71 return configFactory;
72 }
73
74 @Override
75 public boolean isRelevant(NetworkConfigEvent event) {
jaegonkime0f45b52018-10-09 20:23:26 +090076 return event.config().isPresent() && event.config().get() instanceof WorkflowNetConfig;
jaegonkim6a7b5242018-09-12 23:09:42 +090077 }
78
79 @Override
80 public void event(NetworkConfigEvent event) {
81 log.info("Configuration event: {}", event);
82 switch (event.type()) {
83 case CONFIG_ADDED:
84 case CONFIG_UPDATED:
85 if (!event.config().isPresent()) {
86 log.error("No configuration found");
87 return;
88 }
89 WorkflowNetConfig config = (WorkflowNetConfig) event.config().get();
90
91 //Single thread executor(locking is not required)
92 executor.execute(new Handler(workflowService, config));
93 break;
94 default:
95 break;
96 }
97 }
98
99 public static class Handler implements Runnable {
100
101 private WorkflowService workflowService;
102 private WorkflowNetConfig config;
103
104 public Handler(WorkflowService workflowService, WorkflowNetConfig config) {
105 this.workflowService = workflowService;
106 this.config = config;
107 }
108
109 @Override
110 public void run() {
111
112 try {
113 Collection<RpcDescription> rpcs = config.getRpcDescriptions();
114 log.info("" + rpcs);
115 for (RpcDescription rpc : rpcs) {
116 if (!rpcMap.containsKey(rpc.op())) {
117 log.error("Invalid RPC: {}", rpc);
118 continue;
119 }
120
121 rpcMap.get(rpc.op()).apply(this.workflowService, rpc);
122 }
123 } catch (WorkflowException e) {
jaegonkime0f45b52018-10-09 20:23:26 +0900124 log.error("Exception: ", e);
jaegonkim6a7b5242018-09-12 23:09:42 +0900125 }
126 }
127 }
128
129 @FunctionalInterface
130 public interface RpcCall {
131 void apply(WorkflowService workflowService, RpcDescription rpcDesc) throws WorkflowException;
132 }
133
134 private static Map<String, RpcCall> rpcMap = new HashMap<>();
135 static {
gyewan.anecb32692019-07-10 14:36:58 +0900136 rpcMap.put(WORKPLACE_CREATE,
jaegonkim6a7b5242018-09-12 23:09:42 +0900137 (service, desc) -> service.createWorkplace(DefaultWorkplaceDescription.valueOf(desc.params())));
gyewan.anecb32692019-07-10 14:36:58 +0900138 rpcMap.put(WORKPLACE_REMOVE,
jaegonkim6a7b5242018-09-12 23:09:42 +0900139 (service, desc) -> service.removeWorkplace(DefaultWorkplaceDescription.valueOf(desc.params())));
gyewan.anecb32692019-07-10 14:36:58 +0900140 rpcMap.put(WORKFLOW_INVOKE,
jaegonkim6a7b5242018-09-12 23:09:42 +0900141 (service, desc) -> service.invokeWorkflow(desc.params()));
gyewan.anecb32692019-07-10 14:36:58 +0900142 rpcMap.put(WORKFLOW_TERMINATE,
jaegonkim6a7b5242018-09-12 23:09:42 +0900143 (service, desc) -> service.terminateWorkflow(DefaultWorkflowDescription.valueOf(desc.params())));
144 }
145}