Add mappingservice-netconf bundle
[lispflowmapping.git] / mappingservice / netconf / src / main / java / org / opendaylight / lispflowmapping / netconf / impl / LispDeviceNetconfConnector.java
1 /*
2  * Copyright (c) 2014 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.lispflowmapping.netconf.impl;
10
11
12 import java.util.concurrent.Callable;
13 import java.util.concurrent.ExecutionException;
14 import java.util.concurrent.ExecutorService;
15 import java.util.concurrent.Executors;
16 import java.util.concurrent.Future;
17
18 import javax.management.InstanceAlreadyExistsException;
19 import javax.management.InstanceNotFoundException;
20
21 import org.opendaylight.lispflowmapping.netconf.impl.LispNetconfConnector;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lispflowmapping.netconf.rev140706.BuildConnectorInput;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lispflowmapping.netconf.rev140706.LfmNetconfConnectorService;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lispflowmapping.netconf.rev140706.RemoveConnectorInput;
25 import org.opendaylight.yangtools.yang.common.RpcResult;
26 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
27 import org.opendaylight.controller.config.api.ConflictingVersionException;
28 import org.opendaylight.controller.config.api.ValidationException;
29 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
30 import org.slf4j.LoggerFactory;
31 import org.slf4j.Logger;
32
33 import com.google.common.util.concurrent.SettableFuture;
34
35
36 public class LispDeviceNetconfConnector implements AutoCloseable, LfmNetconfConnectorService {
37
38        private static final Logger logger = LoggerFactory.getLogger(LispDeviceNetconfConnector.class);
39
40        private final ExecutorService executor;
41        private LispNetconfConnector nconfConnector;
42
43        public static LispDeviceNetconfConnector createLispDeviceNetconfConnector() {
44            return new LispDeviceNetconfConnector(Executors.newFixedThreadPool(1), new LispNetconfConnector());
45        }
46
47        public LispDeviceNetconfConnector(ExecutorService executor, LispNetconfConnector nconfConnector) {
48            this.executor = executor;
49            this.nconfConnector = nconfConnector;
50            logger.info( "LispDeviceNetconfConnector constructed" );
51        }
52
53        /**
54         * Implemented from the AutoCloseable interface.
55         */
56        @Override
57        public void close() throws ExecutionException, InterruptedException {
58            executor.shutdown();
59        }
60
61
62         /**
63          * RestConf RPC call implemented from the LfmNetconfConnectorService interface.
64          */
65         @Override
66         public Future<RpcResult<Void>> buildConnector(final BuildConnectorInput input) {
67             SettableFuture<RpcResult<Void>> futureResult = SettableFuture.create();
68
69             logger.trace("Received RPC to buildConnector: " + input);
70
71             if (verifyBuildInput(input, futureResult) != true) {
72                 return futureResult;
73             }
74
75             return executor.submit(new MakeConnector(input));
76
77         }
78
79         @Override
80         public Future<RpcResult<Void>> removeConnector(final RemoveConnectorInput input) {
81             SettableFuture<RpcResult<Void>> futureResult = SettableFuture.create();
82
83             if (verifyRemoveInput(input, futureResult) != true) {
84                 return futureResult;
85             }
86
87             return executor.submit(new RemoveConnector(input) );
88
89         }
90
91         private boolean verifyBuildInput(final BuildConnectorInput req, SettableFuture<RpcResult<Void>> futureResult ) {
92             if (req.getInstance() == null) {
93                 logger.error("Instance name not initialized");
94                 futureResult.set(RpcResultBuilder.<Void> failed()
95                         .withError(ErrorType.APPLICATION, "exception", "Instance name not initialized")
96                         .build());
97                 return false;
98             }
99
100             if (req.getAddress() == null) {
101                 logger.error("IP address not initialized");
102                 futureResult.set(RpcResultBuilder.<Void> failed()
103                         .withError(ErrorType.APPLICATION, "exception", "IP address not initialized")
104                         .build());
105                 return false;
106             }
107
108             if (req.getPort() == null) {
109                 logger.error("Port not initialized");
110                 futureResult.set(RpcResultBuilder.<Void> failed()
111                         .withError(ErrorType.APPLICATION, "exception", "Port not initialized")
112                         .build());
113                 return false;
114             }
115
116             if (req.getUsername() == null) {
117                 logger.error("Username not initialized");
118                 futureResult.set(RpcResultBuilder.<Void> failed()
119                         .withError(ErrorType.APPLICATION, "exception", "Username not initialized")
120                         .build());
121                 return false;
122             }
123
124             if (req.getPassword() == null) {
125                 logger.error("Password not initialized");
126                 futureResult.set(RpcResultBuilder.<Void> failed()
127                         .withError(ErrorType.APPLICATION, "exception", "Password not initialized")
128                         .build());
129                 return false;
130             }
131
132             return true;
133         }
134
135         private boolean verifyRemoveInput(final RemoveConnectorInput conn, SettableFuture<RpcResult<Void>> futureResult) {
136             if (conn.getInstance() == null) {
137                 logger.error("Instance name not initialized");
138                 futureResult.set(RpcResultBuilder.<Void> failed()
139                         .withError(ErrorType.APPLICATION, "exception", "Instance name not initialized")
140                         .build());
141                 return false;
142             }
143
144             return true;
145         }
146
147
148         private class MakeConnector implements Callable<RpcResult<Void>> {
149
150             final BuildConnectorInput buildConnectorInput;
151
152             public MakeConnector(final BuildConnectorInput buildConnectorInput) {
153                 this.buildConnectorInput = buildConnectorInput;
154             }
155
156             @Override
157             public RpcResult<Void> call() {
158
159                 try {
160                     nconfConnector.createNetconfConnector(buildConnectorInput.getInstance(), buildConnectorInput.getAddress(),
161                             buildConnectorInput.getPort().getValue(), buildConnectorInput.getUsername(), buildConnectorInput.getPassword());
162                     logger.info("LispNetconfConnector {} built", buildConnectorInput.getInstance());
163                     return RpcResultBuilder.<Void>success().build();
164                 } catch( InstanceAlreadyExistsException e ) {
165                     logger.error("LispNetconfConnector {} already exists!", buildConnectorInput.getInstance());
166                     return RpcResultBuilder.<Void> failed()
167                             .withError(ErrorType.APPLICATION, "exists", "LispNetconfConnector exists")
168                             .build();
169                 } catch (ConflictingVersionException ex) {
170                     logger.error("LispNetconfConnector {} version exception", buildConnectorInput.getInstance());
171                     return RpcResultBuilder.<Void> failed()
172                             .withError(ErrorType.APPLICATION, "exception", "LispNetconfConnector version exception")
173                             .build();
174                 } catch ( ValidationException ex) {
175                     logger.error("LispNetconfConnector {} validation exception", buildConnectorInput.getInstance());
176                     return RpcResultBuilder.<Void> failed()
177                             .withError(ErrorType.APPLICATION, "exception", "LispNetconfConnector validation exception")
178                             .build();
179                 }
180
181             }
182
183         }
184
185         private class RemoveConnector implements Callable<RpcResult<Void>> {
186             final RemoveConnectorInput removeConnectorInput;
187
188             public RemoveConnector(final RemoveConnectorInput connectorInput) {
189                 this.removeConnectorInput = connectorInput;
190             }
191
192             @Override
193             public RpcResult<Void> call() {
194                 try {
195                     nconfConnector.removeNetconfConnector(removeConnectorInput.getInstance());
196                     logger.info("LispNetconfConnector {} removed!", removeConnectorInput.getInstance());
197                     return RpcResultBuilder.<Void> success().build();
198                 } catch( InstanceNotFoundException e ) {
199                     logger.info("LispNetconfConnector {} doesn't exists!", removeConnectorInput.getInstance());
200                     return RpcResultBuilder.<Void> failed()
201                             .withError(ErrorType.APPLICATION, "no-exist", "LispNetconfConnector doesn't exist")
202                             .build();
203                 } catch( ValidationException e ) {
204                     logger.info("LispNetconfConnector {}: Could not validate remove transactions!", removeConnectorInput.getInstance());
205                     return RpcResultBuilder.<Void> failed()
206                             .withError(ErrorType.APPLICATION, "fail", "LispNetconfConnector doesn't exist")
207                             .build();
208                 } catch (ConflictingVersionException e) {
209                     logger.error("LispNetconfConnector {}: Cannot remove due to conflicting version", removeConnectorInput.getInstance() );
210                     return RpcResultBuilder.<Void> failed()
211                             .withError(ErrorType.APPLICATION, "fail", "Conflicting version exception")
212                             .build();
213                 } catch (Exception e) {
214                     logger.error("LispNetconfConnector {} exception while removing: {}", removeConnectorInput.getInstance(), e.getClass());
215                     return RpcResultBuilder.<Void> failed()
216                             .withError(ErrorType.APPLICATION, "fail", "Cannot remove LispNetconfConnector: " + removeConnectorInput.getInstance())
217                             .build();
218                 }
219
220             }
221         }
222     }