blob: 846642cd1918be29a6184f91ba3f7b61716bf094 [file] [log] [blame]
Sean Condond2c8d472017-02-17 17:09:39 +00001/*
2 * Copyright 2017-present Open Networking Laboratory
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 */
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;
24import static org.onosproject.netconf.TargetConfig.RUNNING;
25import static org.onosproject.netconf.TargetConfig.CANDIDATE;
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;
Andrei Mihaescuac542ca2017-03-26 21:36:25 +030049import org.onosproject.netconf.TargetConfig;
Sean Condond2c8d472017-02-17 17:09:39 +000050import org.onosproject.netconf.NetconfDeviceInfo;
51import org.onosproject.netconf.NetconfException;
52import org.onosproject.netconf.NetconfSession;
53import 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",
166 session1.editConfig(TargetConfig.RUNNING.toString(),
167 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",
195 session1.deleteConfig(TargetConfig.RUNNING));
196 } 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",
209 session1.copyConfig(TargetConfig.RUNNING.toString(),
210 "candidate"));
Sean Condond2c8d472017-02-17 17:09:39 +0000211 } catch (NetconfException e) {
212 e.printStackTrace();
213 fail("NETCONF edit-config test failed: " + e.getMessage());
214 }
215 log.info("Finishing copy-config async");
216 }
217
218 @Test
219 public void testGetConfigRequest() {
220 log.info("Starting get-config async");
221 assertNotNull("Incorrect sessionId", session1.getSessionId());
222 try {
223 assertTrue("NETCONF get-config running command failed. ",
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700224 GET_REPLY_PATTERN.matcher(session1.getConfig(RUNNING, SAMPLE_REQUEST)).matches());
Sean Condond2c8d472017-02-17 17:09:39 +0000225
226 assertTrue("NETCONF get-config candidate command failed. ",
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700227 GET_REPLY_PATTERN.matcher(session1.getConfig(CANDIDATE, SAMPLE_REQUEST)).matches());
Sean Condond2c8d472017-02-17 17:09:39 +0000228
229 } catch (NetconfException e) {
230 e.printStackTrace();
231 fail("NETCONF get-config test failed: " + e.getMessage());
232 }
233 log.info("Finishing get-config async");
234 }
235
236 @Test
237 public void testGetRequest() {
238 log.info("Starting get async");
239 assertNotNull("Incorrect sessionId", session1.getSessionId());
240 try {
241 assertTrue("NETCONF get running command failed. ",
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700242 GET_REPLY_PATTERN.matcher(session1.get(SAMPLE_REQUEST, null)).matches());
Sean Condond2c8d472017-02-17 17:09:39 +0000243
244 } catch (NetconfException e) {
245 e.printStackTrace();
246 fail("NETCONF get test failed: " + e.getMessage());
247 }
248 log.info("Finishing get async");
249 }
250
251 @Test
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700252 public void testLockRequest() {
253 log.info("Starting lock async");
254 assertNotNull("Incorrect sessionId", session1.getSessionId());
255 try {
256 assertTrue("NETCONF lock request failed", session1.lock());
257 } catch (NetconfException e) {
258 e.printStackTrace();
259 fail("NETCONF lock test failed: " + e.getMessage());
260 }
261 log.info("Finishing lock async");
262 }
263
264 @Test
265 public void testUnLockRequest() {
266 log.info("Starting unlock async");
267 assertNotNull("Incorrect sessionId", session1.getSessionId());
268 try {
269 assertTrue("NETCONF unlock request failed", session1.unlock());
270 } catch (NetconfException e) {
271 e.printStackTrace();
272 fail("NETCONF unlock test failed: " + e.getMessage());
273 }
274 log.info("Finishing unlock async");
275 }
276
277
278 @Test
Sean Condond2c8d472017-02-17 17:09:39 +0000279 public void testConcurrentSameSessionAccess() throws InterruptedException {
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300280 NCCopyConfigCallable testCopyConfig1 = new NCCopyConfigCallable(session1, RUNNING, "candidate");
281 NCCopyConfigCallable testCopyConfig2 = new NCCopyConfigCallable(session1, RUNNING, "startup");
Sean Condond2c8d472017-02-17 17:09:39 +0000282
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800283 FutureTask<Boolean> futureCopyConfig1 = new FutureTask<>(testCopyConfig1);
284 FutureTask<Boolean> futureCopyConfig2 = new FutureTask<>(testCopyConfig2);
Sean Condond2c8d472017-02-17 17:09:39 +0000285
286 ExecutorService executor = Executors.newFixedThreadPool(2);
287 log.info("Starting concurrent execution of copy-config through same session");
288 executor.execute(futureCopyConfig1);
289 executor.execute(futureCopyConfig2);
290
291 int count = 0;
292 while (count < 10) {
293 if (futureCopyConfig1.isDone() && futureCopyConfig2.isDone()) {
294 executor.shutdown();
295 log.info("Finished concurrent same session execution");
296 return;
297 }
298 Thread.sleep(100L);
299 count++;
300 }
301 fail("NETCONF test failed to complete.");
302 }
303
304 @Test
305 public void test2SessionAccess() throws InterruptedException {
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300306 NCCopyConfigCallable testCopySession1 = new NCCopyConfigCallable(session1, RUNNING, "candidate");
307 NCCopyConfigCallable testCopySession2 = new NCCopyConfigCallable(session2, RUNNING, "candidate");
Sean Condond2c8d472017-02-17 17:09:39 +0000308
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800309 FutureTask<Boolean> futureCopySession1 = new FutureTask<>(testCopySession1);
310 FutureTask<Boolean> futureCopySession2 = new FutureTask<>(testCopySession2);
Sean Condond2c8d472017-02-17 17:09:39 +0000311
312 ExecutorService executor = Executors.newFixedThreadPool(2);
313 log.info("Starting concurrent execution of copy-config through 2 different sessions");
314 executor.execute(futureCopySession1);
315 executor.execute(futureCopySession2);
316
317 int count = 0;
318 while (count < 10) {
319 if (futureCopySession1.isDone() && futureCopySession2.isDone()) {
320 executor.shutdown();
321 log.info("Finished concurrent 2 session execution");
322 return;
323 }
324 Thread.sleep(100L);
325 count++;
326 }
327 fail("NETCONF test failed to complete.");
328 }
329
330
331 public static String getTestHelloReply(Optional<Long> sessionId) {
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800332 return getTestHelloReply(DEFAULT_CAPABILITIES, sessionId);
333 }
334
335 public static String getTestHelloReply(Collection<String> capabilities, Optional<Long> sessionId) {
Sean Condond2c8d472017-02-17 17:09:39 +0000336 StringBuffer sb = new StringBuffer();
337
338 sb.append("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">");
339 sb.append("<capabilities>");
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800340 capabilities.forEach(capability -> {
341 sb.append("<capability>").append(capability).append("</capability>");
342 });
Sean Condond2c8d472017-02-17 17:09:39 +0000343 sb.append("</capabilities>");
344 if (sessionId.isPresent()) {
345 sb.append("<session-id>");
346 sb.append(sessionId.get().toString());
347 sb.append("</session-id>");
348 }
349 sb.append("</hello>");
350
351 return sb.toString();
352 }
353
354 public static String getOkReply(Optional<Integer> messageId) {
355 StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
356 sb.append("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
357 if (messageId.isPresent()) {
358 sb.append("message-id=\"");
359 sb.append(String.valueOf(messageId.get()));
360 sb.append("\">");
361 }
362 sb.append("<ok/>");
363 sb.append("</rpc-reply>");
364 return sb.toString();
365 }
366
367 public static String getGetReply(Optional<Integer> messageId) {
368 StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
369 sb.append("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
370 if (messageId.isPresent()) {
371 sb.append("message-id=\"");
372 sb.append(String.valueOf(messageId.get()));
373 sb.append("\">");
374 }
375 sb.append("<data>\n");
376 sb.append(SAMPLE_REQUEST);
377 sb.append("</data>\n");
378 sb.append("</rpc-reply>");
379 return sb.toString();
380 }
381
382 public static final Pattern HELLO_REQ_PATTERN =
383 Pattern.compile("(<\\?xml).*"
384 + "(<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
385 + "( *)(<capabilities>)\\R?"
386 + "( *)(<capability>urn:ietf:params:netconf:base:1.0</capability>)\\R?"
387 + "( *)(</capabilities>)\\R?"
388 + "(</hello>)\\R? *",
389 Pattern.DOTALL);
390
391 public static final Pattern EDIT_CONFIG_REQ_PATTERN =
392 Pattern.compile("(<\\?xml).*"
393 + "(<rpc message-id=\")[0-9]*(\") *(xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
394 + "(<edit-config>)\\R?"
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700395 + "(<target>\\R?((<" + TargetConfig.CANDIDATE.toString() + "/>)|"
396 + "(<" + TargetConfig.RUNNING.toString() + "/>)|"
397 + "(<" + TargetConfig.STARTUP.toString() + "/>))\\R?</target>)\\R?"
Sean Condond2c8d472017-02-17 17:09:39 +0000398 + "(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
399 + ".*"
400 + "(</config>)\\R?(</edit-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
401
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700402
403 public static final Pattern LOCK_REQ_PATTERN =
404 Pattern.compile("(<\\?xml).*"
405 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
406 + "message-id=\")[0-9]*(\">)\\R?"
407 + "(<lock>)\\R?"
408 + "(<target>\\R?((<" + TargetConfig.CANDIDATE.toString() + "/>)|"
409 + "(<" + TargetConfig.RUNNING.toString() + "/>)|"
410 + "(<" + TargetConfig.STARTUP.toString() + "/>))\\R?</target>)\\R?"
411 + "(</lock>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
412
413 public static final Pattern UNLOCK_REQ_PATTERN =
414 Pattern.compile("(<\\?xml).*"
415 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
416 + "message-id=\")[0-9]*(\">)\\R?"
417 + "(<unlock>)\\R?"
418 + "(<target>\\R?((<" + TargetConfig.CANDIDATE.toString() + "/>)|"
419 + "(<" + TargetConfig.RUNNING.toString() + "/>)|"
420 + "(<" + TargetConfig.STARTUP.toString() + "/>))\\R?</target>)\\R?"
421 + "(</unlock>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
422
Sean Condond2c8d472017-02-17 17:09:39 +0000423 public static final Pattern COPY_CONFIG_REQ_PATTERN =
424 Pattern.compile("(<\\?xml).*"
425 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\")[0-9]*(\">)\\R?"
426 + "(<copy-config>)\\R?"
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700427 + "(<target>\\R?((<" + TargetConfig.CANDIDATE.toString() + "/>)|"
428 + "(<" + TargetConfig.RUNNING.toString() + "/>)|"
429 + "(<" + TargetConfig.STARTUP.toString() + "/>))\\R?</target>)\\R?"
430 + "(<source>)\\R?(<config>)(("
431 + TargetConfig.CANDIDATE.toString() + ")|("
432 + TargetConfig.RUNNING.toString() + ")|("
433 + TargetConfig.STARTUP.toString()
434 + "))(</config>)\\R?(</source>)\\R?"
435 + "(</copy-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
Sean Condond2c8d472017-02-17 17:09:39 +0000436
437 public static final Pattern GET_CONFIG_REQ_PATTERN =
438 Pattern.compile("(<\\?xml).*"
439 + "(<rpc message-id=\")[0-9]*(\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700440 + "(<get-config>)\\R?" + "(<source>)\\R?((<"
441 + TargetConfig.CANDIDATE.toString()
442 + "/>)|(<" + TargetConfig.RUNNING.toString()
443 + "/>)|(<" + TargetConfig.STARTUP.toString()
444 + "/>))\\R?(</source>)\\R?"
Sean Condond2c8d472017-02-17 17:09:39 +0000445 + "(<filter type=\"subtree\">).*(</filter>)\\R?"
446 + "(</get-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
447
448 public static final Pattern GET_REPLY_PATTERN =
449 Pattern.compile("(<\\?xml).*"
450 + "(<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\")[0-9]*(\">)\\R?"
451 + "(<data>).*(</data>)\\R?"
452 + "(</rpc-reply>)\\R?", Pattern.DOTALL);
453
454 public static final Pattern GET_REQ_PATTERN =
455 Pattern.compile("(<\\?xml).*"
456 + "(<rpc message-id=\")[0-9]*(\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
457 + "(<get>)\\R?"
458 + "(<filter type=\"subtree\">).*(</filter>)\\R?"
459 + "(</get>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
460
461 public class NCCopyConfigCallable implements Callable<Boolean> {
462 private NetconfSession session;
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300463 private TargetConfig target;
Sean Condond2c8d472017-02-17 17:09:39 +0000464 private String source;
465
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300466 public NCCopyConfigCallable(NetconfSession session, TargetConfig target, String source) {
Sean Condond2c8d472017-02-17 17:09:39 +0000467 this.session = session;
468 this.target = target;
469 this.source = source;
470 }
471
472 @Override
473 public Boolean call() throws Exception {
474 return session.copyConfig(target, source);
475 }
476 }
477}