blob: 8fdd5ff1152e4e839dc4705201af9be1f094aadc [file] [log] [blame]
Sean Condond2c8d472017-02-17 17:09:39 +00001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Sean Condond2c8d472017-02-17 17:09:39 +00003 *
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 */
Yuta HIGUCHIe3ae8212017-04-20 10:18:41 -070016package org.onosproject.netconf.ctl.impl;
Sean Condond2c8d472017-02-17 17:09:39 +000017
Aaron Kruglikov72db6422017-02-13 12:16:51 -080018import static org.hamcrest.Matchers.containsInAnyOrder;
Sean Condond2c8d472017-02-17 17:09:39 +000019import static org.junit.Assert.assertNotNull;
Aaron Kruglikov72db6422017-02-13 12:16:51 -080020import static org.junit.Assert.assertThat;
Sean Condond2c8d472017-02-17 17:09:39 +000021import static org.junit.Assert.assertTrue;
22import static org.junit.Assert.fail;
Shivani Vaidya48df84e2017-04-13 13:48:17 -070023import static org.junit.Assert.assertFalse;
Yuta HIGUCHI89111d92017-05-04 11:29:17 -070024import static org.onosproject.netconf.DatastoreId.CANDIDATE;
25import static org.onosproject.netconf.DatastoreId.RUNNING;
Sean Condond2c8d472017-02-17 17:09:39 +000026
Andrea Campanella7bbe7b12017-05-03 16:03:38 -070027import java.io.File;
Sean Condond2c8d472017-02-17 17:09:39 +000028import java.util.Arrays;
Aaron Kruglikov72db6422017-02-13 12:16:51 -080029import java.util.Collection;
Sean Condond2c8d472017-02-17 17:09:39 +000030import java.util.List;
31import java.util.Optional;
32import java.util.concurrent.Callable;
33import java.util.concurrent.ExecutorService;
34import java.util.concurrent.Executors;
35import java.util.concurrent.FutureTask;
36import java.util.regex.Pattern;
37
Sean Condond2c8d472017-02-17 17:09:39 +000038import org.apache.sshd.common.NamedFactory;
39import org.apache.sshd.server.Command;
Andrea Campanella7bbe7b12017-05-03 16:03:38 -070040import org.apache.sshd.server.SshServer;
41import org.apache.sshd.server.auth.password.PasswordAuthenticator;
Sean Condond2c8d472017-02-17 17:09:39 +000042import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
43import org.apache.sshd.server.session.ServerSession;
44import org.junit.AfterClass;
45import org.junit.BeforeClass;
46import org.junit.Test;
47import org.onlab.junit.TestTools;
48import org.onlab.packet.Ip4Address;
49import org.onosproject.netconf.NetconfDeviceInfo;
50import org.onosproject.netconf.NetconfException;
51import org.onosproject.netconf.NetconfSession;
Yuta HIGUCHI89111d92017-05-04 11:29:17 -070052import org.onosproject.netconf.DatastoreId;
Sean Condond2c8d472017-02-17 17:09:39 +000053import org.slf4j.Logger;
54import org.slf4j.LoggerFactory;
55
Aaron Kruglikov72db6422017-02-13 12:16:51 -080056import com.google.common.collect.ImmutableList;
57
Sean Condond2c8d472017-02-17 17:09:39 +000058/**
59 * Unit tests for NetconfSession.
Andrea Campanella7bbe7b12017-05-03 16:03:38 -070060 * <p>
Sean Condond2c8d472017-02-17 17:09:39 +000061 * Sets up an SSH Server with Apache SSHD and connects to it using 2 clients
62 * Truly verifies that the NETCONF flows are compliant with a NETCONF server.
63 */
64public class NetconfSessionImplTest {
65 private static final Logger log = LoggerFactory
66 .getLogger(NetconfStreamThread.class);
67
68 private static final int PORT_NUMBER = TestTools.findAvailablePort(50830);
69 private static final String TEST_USERNAME = "netconf";
70 private static final String TEST_PASSWORD = "netconf123";
71 private static final String TEST_HOSTNAME = "127.0.0.1";
Shivani Vaidya48df84e2017-04-13 13:48:17 -070072
Sean Condond2c8d472017-02-17 17:09:39 +000073 private static final String TEST_SERFILE =
74 System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + "testkey.ser";
75
76 private static final String SAMPLE_REQUEST =
77 "<some-yang-element xmlns=\"some-namespace\">"
Andrea Campanella7bbe7b12017-05-03 16:03:38 -070078 + "<some-child-element/>"
79 + "</some-yang-element>";
Sean Condond2c8d472017-02-17 17:09:39 +000080
Shivani Vaidya48df84e2017-04-13 13:48:17 -070081 private static final String EDIT_CONFIG_REQUEST =
82 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><rpc message-id=\"6\" "
83 + "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
84 + "<edit-config>\n"
85 + "<target><running/></target>\n"
86 + "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
87 + "<some-yang-element xmlns=\"some-namespace\">"
88 + "<some-child-element/></some-yang-element></config>\n"
89 + "</edit-config>\n"
90 + "</rpc>]]>]]>";
91
Aaron Kruglikov72db6422017-02-13 12:16:51 -080092 static final List<String> DEFAULT_CAPABILITIES = ImmutableList.<String>builder()
93 .add("urn:ietf:params:netconf:base:1.0")
94 .add("urn:ietf:params:netconf:base:1.1")
95 .add("urn:ietf:params:netconf:capability:writable-running:1.0")
96 .add("urn:ietf:params:netconf:capability:candidate:1.0")
97 .add("urn:ietf:params:netconf:capability:startup:1.0")
98 .add("urn:ietf:params:netconf:capability:rollback-on-error:1.0")
99 .add("urn:ietf:params:netconf:capability:interleave:1.0")
100 .add("urn:ietf:params:netconf:capability:notification:1.0")
101 .add("urn:ietf:params:netconf:capability:validate:1.0")
102 .add("urn:ietf:params:netconf:capability:validate:1.1")
103 .build();
104
105
Sean Condond2c8d472017-02-17 17:09:39 +0000106 private static NetconfSession session1;
107 private static NetconfSession session2;
108 private static SshServer sshServerNetconf;
109
110 @BeforeClass
111 public static void setUp() throws Exception {
112 sshServerNetconf = SshServer.setUpDefaultServer();
Sean Condond2c8d472017-02-17 17:09:39 +0000113 sshServerNetconf.setPasswordAuthenticator(
114 new PasswordAuthenticator() {
115 @Override
116 public boolean authenticate(
117 String username,
118 String password,
119 ServerSession session) {
120 return TEST_USERNAME.equals(username) && TEST_PASSWORD.equals(password);
121 }
122 });
123 sshServerNetconf.setPort(PORT_NUMBER);
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700124 SimpleGeneratorHostKeyProvider provider = new SimpleGeneratorHostKeyProvider();
125 provider.setFile(new File(TEST_SERFILE));
126 sshServerNetconf.setKeyPairProvider(provider);
Sean Condond2c8d472017-02-17 17:09:39 +0000127 sshServerNetconf.setSubsystemFactories(
128 Arrays.<NamedFactory<Command>>asList(new NetconfSshdTestSubsystem.Factory()));
129 sshServerNetconf.open();
130 log.info("SSH Server opened on port {}", PORT_NUMBER);
131
132 NetconfDeviceInfo deviceInfo = new NetconfDeviceInfo(
133 TEST_USERNAME, TEST_PASSWORD, Ip4Address.valueOf(TEST_HOSTNAME), PORT_NUMBER);
134
135 session1 = new NetconfSessionImpl(deviceInfo);
136 log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session1.getSessionId());
137 assertTrue("Incorrect sessionId", !session1.getSessionId().equalsIgnoreCase("-1"));
138 assertTrue("Incorrect sessionId", !session1.getSessionId().equalsIgnoreCase("0"));
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800139 assertThat(session1.getDeviceCapabilitiesSet(), containsInAnyOrder(DEFAULT_CAPABILITIES.toArray()));
Sean Condond2c8d472017-02-17 17:09:39 +0000140
141 session2 = new NetconfSessionImpl(deviceInfo);
142 log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session2.getSessionId());
143 assertTrue("Incorrect sessionId", !session2.getSessionId().equalsIgnoreCase("-1"));
144 assertTrue("Incorrect sessionId", !session2.getSessionId().equalsIgnoreCase("0"));
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800145 assertThat(session2.getDeviceCapabilitiesSet(), containsInAnyOrder(DEFAULT_CAPABILITIES.toArray()));
Sean Condond2c8d472017-02-17 17:09:39 +0000146 }
147
148 @AfterClass
149 public static void tearDown() throws Exception {
150 if (session1 != null) {
151 session1.close();
152 }
153 if (session2 != null) {
154 session2.close();
155 }
156
157 sshServerNetconf.stop();
158 }
159
160 @Test
161 public void testEditConfigRequest() {
162 log.info("Starting edit-config async");
163 assertNotNull("Incorrect sessionId", session1.getSessionId());
164 try {
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700165 assertTrue("NETCONF edit-config command failed",
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700166 session1.editConfig(DatastoreId.RUNNING,
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700167 null, SAMPLE_REQUEST));
Sean Condond2c8d472017-02-17 17:09:39 +0000168 } catch (NetconfException e) {
169 e.printStackTrace();
170 fail("NETCONF edit-config test failed: " + e.getMessage());
171 }
172 log.info("Finishing edit-config async");
173 }
174
175 @Test
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700176 public void testEditConfigRequestWithOnlyNewConfiguration() {
177 log.info("Starting edit-config async");
178 assertNotNull("Incorrect sessionId", session1.getSessionId());
179 try {
180 assertTrue("NETCONF edit-config command failed",
181 session1.editConfig(EDIT_CONFIG_REQUEST));
182 } catch (NetconfException e) {
183 e.printStackTrace();
184 fail("NETCONF edit-config test failed: " + e.getMessage());
185 }
186 log.info("Finishing edit-config async");
187 }
188
189 @Test
190 public void testDeleteConfigRequestWithRunningTargetConfiguration() {
191 log.info("Starting delete-config async");
192 assertNotNull("Incorrect sessionId", session1.getSessionId());
193 try {
194 assertFalse("NETCONF delete-config command failed",
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700195 session1.deleteConfig(DatastoreId.RUNNING));
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700196 } catch (NetconfException e) {
197 e.printStackTrace();
198 fail("NETCONF delete-config test failed: " + e.getMessage());
199 }
200 log.info("Finishing delete-config async");
201 }
202
203 @Test
Sean Condond2c8d472017-02-17 17:09:39 +0000204 public void testCopyConfigRequest() {
205 log.info("Starting copy-config async");
206 assertNotNull("Incorrect sessionId", session1.getSessionId());
207 try {
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700208 assertTrue("NETCONF copy-config command failed",
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700209 session1.copyConfig(DatastoreId.RUNNING,
210 DatastoreId.CANDIDATE));
Sean Condond2c8d472017-02-17 17:09:39 +0000211 } catch (NetconfException e) {
212 e.printStackTrace();
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700213 fail("NETCONF copy-config test failed: " + e.getMessage());
Sean Condond2c8d472017-02-17 17:09:39 +0000214 }
215 log.info("Finishing copy-config async");
216 }
217
218 @Test
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700219 public void testCopyConfigXml() {
220 log.info("Starting copy-config XML async");
221 assertNotNull("Incorrect sessionId", session1.getSessionId());
222 try {
223 assertTrue("NETCONF copy-config command failed",
224 session1.copyConfig(DatastoreId.RUNNING,
225 "<configuration><device-specific/></configuration>"));
226 } catch (NetconfException e) {
227 e.printStackTrace();
228 fail("NETCONF copy-config test failed: " + e.getMessage());
229 }
230 log.info("Finishing copy-config XML async");
231 }
232
233 // remove test when ready to dump bare XML String API.
234 @Test
235 public void testCopyConfigBareXml() {
236 log.info("Starting copy-config bare XML async");
237 assertNotNull("Incorrect sessionId", session1.getSessionId());
238 try {
239 assertTrue("NETCONF copy-config command failed",
240 session1.copyConfig(DatastoreId.RUNNING,
241 "<config>"
242 + "<configuration><device-specific/></configuration>"
243 + "</config>"));
244 } catch (NetconfException e) {
245 e.printStackTrace();
246 fail("NETCONF copy-config test failed: " + e.getMessage());
247 }
248 log.info("Finishing copy-config bare XML async");
249 }
250
251 @Test
Sean Condond2c8d472017-02-17 17:09:39 +0000252 public void testGetConfigRequest() {
253 log.info("Starting get-config async");
254 assertNotNull("Incorrect sessionId", session1.getSessionId());
255 try {
256 assertTrue("NETCONF get-config running command failed. ",
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700257 GET_REPLY_PATTERN.matcher(session1.getConfig(RUNNING, SAMPLE_REQUEST)).matches());
Sean Condond2c8d472017-02-17 17:09:39 +0000258
259 assertTrue("NETCONF get-config candidate command failed. ",
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700260 GET_REPLY_PATTERN.matcher(session1.getConfig(CANDIDATE, SAMPLE_REQUEST)).matches());
Sean Condond2c8d472017-02-17 17:09:39 +0000261
262 } catch (NetconfException e) {
263 e.printStackTrace();
264 fail("NETCONF get-config test failed: " + e.getMessage());
265 }
266 log.info("Finishing get-config async");
267 }
268
269 @Test
270 public void testGetRequest() {
271 log.info("Starting get async");
272 assertNotNull("Incorrect sessionId", session1.getSessionId());
273 try {
274 assertTrue("NETCONF get running command failed. ",
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700275 GET_REPLY_PATTERN.matcher(session1.get(SAMPLE_REQUEST, null)).matches());
Sean Condond2c8d472017-02-17 17:09:39 +0000276
277 } catch (NetconfException e) {
278 e.printStackTrace();
279 fail("NETCONF get test failed: " + e.getMessage());
280 }
281 log.info("Finishing get async");
282 }
283
284 @Test
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700285 public void testLockRequest() {
286 log.info("Starting lock async");
287 assertNotNull("Incorrect sessionId", session1.getSessionId());
288 try {
289 assertTrue("NETCONF lock request failed", session1.lock());
290 } catch (NetconfException e) {
291 e.printStackTrace();
292 fail("NETCONF lock test failed: " + e.getMessage());
293 }
294 log.info("Finishing lock async");
295 }
296
297 @Test
298 public void testUnLockRequest() {
299 log.info("Starting unlock async");
300 assertNotNull("Incorrect sessionId", session1.getSessionId());
301 try {
302 assertTrue("NETCONF unlock request failed", session1.unlock());
303 } catch (NetconfException e) {
304 e.printStackTrace();
305 fail("NETCONF unlock test failed: " + e.getMessage());
306 }
307 log.info("Finishing unlock async");
308 }
309
310
311 @Test
Sean Condond2c8d472017-02-17 17:09:39 +0000312 public void testConcurrentSameSessionAccess() throws InterruptedException {
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300313 NCCopyConfigCallable testCopyConfig1 = new NCCopyConfigCallable(session1, RUNNING, "candidate");
314 NCCopyConfigCallable testCopyConfig2 = new NCCopyConfigCallable(session1, RUNNING, "startup");
Sean Condond2c8d472017-02-17 17:09:39 +0000315
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800316 FutureTask<Boolean> futureCopyConfig1 = new FutureTask<>(testCopyConfig1);
317 FutureTask<Boolean> futureCopyConfig2 = new FutureTask<>(testCopyConfig2);
Sean Condond2c8d472017-02-17 17:09:39 +0000318
319 ExecutorService executor = Executors.newFixedThreadPool(2);
320 log.info("Starting concurrent execution of copy-config through same session");
321 executor.execute(futureCopyConfig1);
322 executor.execute(futureCopyConfig2);
323
324 int count = 0;
325 while (count < 10) {
326 if (futureCopyConfig1.isDone() && futureCopyConfig2.isDone()) {
327 executor.shutdown();
328 log.info("Finished concurrent same session execution");
329 return;
330 }
331 Thread.sleep(100L);
332 count++;
333 }
334 fail("NETCONF test failed to complete.");
335 }
336
337 @Test
338 public void test2SessionAccess() throws InterruptedException {
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300339 NCCopyConfigCallable testCopySession1 = new NCCopyConfigCallable(session1, RUNNING, "candidate");
340 NCCopyConfigCallable testCopySession2 = new NCCopyConfigCallable(session2, RUNNING, "candidate");
Sean Condond2c8d472017-02-17 17:09:39 +0000341
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800342 FutureTask<Boolean> futureCopySession1 = new FutureTask<>(testCopySession1);
343 FutureTask<Boolean> futureCopySession2 = new FutureTask<>(testCopySession2);
Sean Condond2c8d472017-02-17 17:09:39 +0000344
345 ExecutorService executor = Executors.newFixedThreadPool(2);
346 log.info("Starting concurrent execution of copy-config through 2 different sessions");
347 executor.execute(futureCopySession1);
348 executor.execute(futureCopySession2);
349
350 int count = 0;
351 while (count < 10) {
352 if (futureCopySession1.isDone() && futureCopySession2.isDone()) {
353 executor.shutdown();
354 log.info("Finished concurrent 2 session execution");
355 return;
356 }
357 Thread.sleep(100L);
358 count++;
359 }
360 fail("NETCONF test failed to complete.");
361 }
362
363
364 public static String getTestHelloReply(Optional<Long> sessionId) {
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800365 return getTestHelloReply(DEFAULT_CAPABILITIES, sessionId);
366 }
367
368 public static String getTestHelloReply(Collection<String> capabilities, Optional<Long> sessionId) {
Sean Condond2c8d472017-02-17 17:09:39 +0000369 StringBuffer sb = new StringBuffer();
370
371 sb.append("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">");
372 sb.append("<capabilities>");
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800373 capabilities.forEach(capability -> {
374 sb.append("<capability>").append(capability).append("</capability>");
375 });
Sean Condond2c8d472017-02-17 17:09:39 +0000376 sb.append("</capabilities>");
377 if (sessionId.isPresent()) {
378 sb.append("<session-id>");
379 sb.append(sessionId.get().toString());
380 sb.append("</session-id>");
381 }
382 sb.append("</hello>");
383
384 return sb.toString();
385 }
386
387 public static String getOkReply(Optional<Integer> messageId) {
388 StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
389 sb.append("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
390 if (messageId.isPresent()) {
391 sb.append("message-id=\"");
392 sb.append(String.valueOf(messageId.get()));
393 sb.append("\">");
394 }
395 sb.append("<ok/>");
396 sb.append("</rpc-reply>");
397 return sb.toString();
398 }
399
400 public static String getGetReply(Optional<Integer> messageId) {
401 StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
402 sb.append("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
403 if (messageId.isPresent()) {
404 sb.append("message-id=\"");
405 sb.append(String.valueOf(messageId.get()));
406 sb.append("\">");
407 }
408 sb.append("<data>\n");
409 sb.append(SAMPLE_REQUEST);
410 sb.append("</data>\n");
411 sb.append("</rpc-reply>");
412 return sb.toString();
413 }
414
415 public static final Pattern HELLO_REQ_PATTERN =
416 Pattern.compile("(<\\?xml).*"
417 + "(<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
418 + "( *)(<capabilities>)\\R?"
419 + "( *)(<capability>urn:ietf:params:netconf:base:1.0</capability>)\\R?"
420 + "( *)(</capabilities>)\\R?"
421 + "(</hello>)\\R? *",
422 Pattern.DOTALL);
423
424 public static final Pattern EDIT_CONFIG_REQ_PATTERN =
425 Pattern.compile("(<\\?xml).*"
426 + "(<rpc message-id=\")[0-9]*(\") *(xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
427 + "(<edit-config>)\\R?"
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700428 + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
429 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
430 + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
Sean Condond2c8d472017-02-17 17:09:39 +0000431 + "(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
432 + ".*"
433 + "(</config>)\\R?(</edit-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
434
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700435
436 public static final Pattern LOCK_REQ_PATTERN =
437 Pattern.compile("(<\\?xml).*"
438 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
439 + "message-id=\")[0-9]*(\">)\\R?"
440 + "(<lock>)\\R?"
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700441 + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
442 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
443 + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700444 + "(</lock>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
445
446 public static final Pattern UNLOCK_REQ_PATTERN =
447 Pattern.compile("(<\\?xml).*"
448 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
449 + "message-id=\")[0-9]*(\">)\\R?"
450 + "(<unlock>)\\R?"
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700451 + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
452 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
453 + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700454 + "(</unlock>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
455
Sean Condond2c8d472017-02-17 17:09:39 +0000456 public static final Pattern COPY_CONFIG_REQ_PATTERN =
457 Pattern.compile("(<\\?xml).*"
458 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\")[0-9]*(\">)\\R?"
459 + "(<copy-config>)\\R?"
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700460 + "(<target>\\R?"
461 + "("
462 + "(<" + DatastoreId.CANDIDATE.toString() + "/>)|"
463 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
464 + "(<" + DatastoreId.STARTUP.toString() + "/>)"
465 + ")\\R?"
466 + "</target>)\\R?"
467 + "(<source>)\\R?"
468 + "("
469 + "(<config>)(.*)(</config>)|"
470 + "(<" + DatastoreId.CANDIDATE.toString() + "/>)|"
471 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
472 + "(<" + DatastoreId.STARTUP.toString() + "/>)"
473 + ")\\R?"
474 + "(</source>)\\R?"
475 + "(</copy-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
Sean Condond2c8d472017-02-17 17:09:39 +0000476
477 public static final Pattern GET_CONFIG_REQ_PATTERN =
478 Pattern.compile("(<\\?xml).*"
479 + "(<rpc message-id=\")[0-9]*(\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700480 + "(<get-config>)\\R?" + "(<source>)\\R?((<"
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700481 + DatastoreId.CANDIDATE.toString()
482 + "/>)|(<" + DatastoreId.RUNNING.toString()
483 + "/>)|(<" + DatastoreId.STARTUP.toString()
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700484 + "/>))\\R?(</source>)\\R?"
Sean Condond2c8d472017-02-17 17:09:39 +0000485 + "(<filter type=\"subtree\">).*(</filter>)\\R?"
486 + "(</get-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
487
488 public static final Pattern GET_REPLY_PATTERN =
489 Pattern.compile("(<\\?xml).*"
490 + "(<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\")[0-9]*(\">)\\R?"
491 + "(<data>).*(</data>)\\R?"
492 + "(</rpc-reply>)\\R?", Pattern.DOTALL);
493
494 public static final Pattern GET_REQ_PATTERN =
495 Pattern.compile("(<\\?xml).*"
496 + "(<rpc message-id=\")[0-9]*(\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
497 + "(<get>)\\R?"
498 + "(<filter type=\"subtree\">).*(</filter>)\\R?"
499 + "(</get>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
500
501 public class NCCopyConfigCallable implements Callable<Boolean> {
502 private NetconfSession session;
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700503 private DatastoreId target;
Sean Condond2c8d472017-02-17 17:09:39 +0000504 private String source;
505
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700506 public NCCopyConfigCallable(NetconfSession session, DatastoreId target, String source) {
Sean Condond2c8d472017-02-17 17:09:39 +0000507 this.session = session;
508 this.target = target;
509 this.source = source;
510 }
511
512 @Override
513 public Boolean call() throws Exception {
514 return session.copyConfig(target, source);
515 }
516 }
517}