blob: 86822a6ef79cf7fd6f2cf96745e697bce131c195 [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 */
16package org.onosproject.netconf.ctl;
17
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
27import java.util.ArrayList;
28import 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
38import org.apache.sshd.SshServer;
39import org.apache.sshd.common.NamedFactory;
40import org.apache.sshd.server.Command;
41import org.apache.sshd.server.PasswordAuthenticator;
42import org.apache.sshd.server.UserAuth;
43import org.apache.sshd.server.auth.UserAuthPassword;
44import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
45import org.apache.sshd.server.session.ServerSession;
46import org.junit.AfterClass;
47import org.junit.BeforeClass;
48import org.junit.Test;
49import org.onlab.junit.TestTools;
50import org.onlab.packet.Ip4Address;
Andrei Mihaescuac542ca2017-03-26 21:36:25 +030051import org.onosproject.netconf.TargetConfig;
Sean Condond2c8d472017-02-17 17:09:39 +000052import org.onosproject.netconf.NetconfDeviceInfo;
53import org.onosproject.netconf.NetconfException;
54import org.onosproject.netconf.NetconfSession;
55import org.slf4j.Logger;
56import org.slf4j.LoggerFactory;
57
Aaron Kruglikov72db6422017-02-13 12:16:51 -080058import com.google.common.collect.ImmutableList;
59
Sean Condond2c8d472017-02-17 17:09:39 +000060/**
61 * Unit tests for NetconfSession.
62 *
63 * Sets up an SSH Server with Apache SSHD and connects to it using 2 clients
64 * Truly verifies that the NETCONF flows are compliant with a NETCONF server.
65 */
66public class NetconfSessionImplTest {
67 private static final Logger log = LoggerFactory
68 .getLogger(NetconfStreamThread.class);
69
70 private static final int PORT_NUMBER = TestTools.findAvailablePort(50830);
71 private static final String TEST_USERNAME = "netconf";
72 private static final String TEST_PASSWORD = "netconf123";
73 private static final String TEST_HOSTNAME = "127.0.0.1";
Shivani Vaidya48df84e2017-04-13 13:48:17 -070074
Sean Condond2c8d472017-02-17 17:09:39 +000075 private static final String TEST_SERFILE =
76 System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + "testkey.ser";
77
78 private static final String SAMPLE_REQUEST =
79 "<some-yang-element xmlns=\"some-namespace\">"
80 + "<some-child-element/>"
81 + "</some-yang-element>";
82
Shivani Vaidya48df84e2017-04-13 13:48:17 -070083 private static final String EDIT_CONFIG_REQUEST =
84 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><rpc message-id=\"6\" "
85 + "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
86 + "<edit-config>\n"
87 + "<target><running/></target>\n"
88 + "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
89 + "<some-yang-element xmlns=\"some-namespace\">"
90 + "<some-child-element/></some-yang-element></config>\n"
91 + "</edit-config>\n"
92 + "</rpc>]]>]]>";
93
Aaron Kruglikov72db6422017-02-13 12:16:51 -080094 static final List<String> DEFAULT_CAPABILITIES = ImmutableList.<String>builder()
95 .add("urn:ietf:params:netconf:base:1.0")
96 .add("urn:ietf:params:netconf:base:1.1")
97 .add("urn:ietf:params:netconf:capability:writable-running:1.0")
98 .add("urn:ietf:params:netconf:capability:candidate:1.0")
99 .add("urn:ietf:params:netconf:capability:startup:1.0")
100 .add("urn:ietf:params:netconf:capability:rollback-on-error:1.0")
101 .add("urn:ietf:params:netconf:capability:interleave:1.0")
102 .add("urn:ietf:params:netconf:capability:notification:1.0")
103 .add("urn:ietf:params:netconf:capability:validate:1.0")
104 .add("urn:ietf:params:netconf:capability:validate:1.1")
105 .build();
106
107
Sean Condond2c8d472017-02-17 17:09:39 +0000108 private static NetconfSession session1;
109 private static NetconfSession session2;
110 private static SshServer sshServerNetconf;
111
112 @BeforeClass
113 public static void setUp() throws Exception {
114 sshServerNetconf = SshServer.setUpDefaultServer();
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800115 List<NamedFactory<UserAuth>> userAuthFactories = new ArrayList<>();
Sean Condond2c8d472017-02-17 17:09:39 +0000116 userAuthFactories.add(new UserAuthPassword.Factory());
117 sshServerNetconf.setUserAuthFactories(userAuthFactories);
118 sshServerNetconf.setPasswordAuthenticator(
119 new PasswordAuthenticator() {
120 @Override
121 public boolean authenticate(
122 String username,
123 String password,
124 ServerSession session) {
125 return TEST_USERNAME.equals(username) && TEST_PASSWORD.equals(password);
126 }
127 });
128 sshServerNetconf.setPort(PORT_NUMBER);
129 sshServerNetconf.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(TEST_SERFILE));
130 sshServerNetconf.setSubsystemFactories(
131 Arrays.<NamedFactory<Command>>asList(new NetconfSshdTestSubsystem.Factory()));
132 sshServerNetconf.open();
133 log.info("SSH Server opened on port {}", PORT_NUMBER);
134
135 NetconfDeviceInfo deviceInfo = new NetconfDeviceInfo(
136 TEST_USERNAME, TEST_PASSWORD, Ip4Address.valueOf(TEST_HOSTNAME), PORT_NUMBER);
137
138 session1 = new NetconfSessionImpl(deviceInfo);
139 log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session1.getSessionId());
140 assertTrue("Incorrect sessionId", !session1.getSessionId().equalsIgnoreCase("-1"));
141 assertTrue("Incorrect sessionId", !session1.getSessionId().equalsIgnoreCase("0"));
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800142 assertThat(session1.getDeviceCapabilitiesSet(), containsInAnyOrder(DEFAULT_CAPABILITIES.toArray()));
Sean Condond2c8d472017-02-17 17:09:39 +0000143
144 session2 = new NetconfSessionImpl(deviceInfo);
145 log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session2.getSessionId());
146 assertTrue("Incorrect sessionId", !session2.getSessionId().equalsIgnoreCase("-1"));
147 assertTrue("Incorrect sessionId", !session2.getSessionId().equalsIgnoreCase("0"));
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800148 assertThat(session2.getDeviceCapabilitiesSet(), containsInAnyOrder(DEFAULT_CAPABILITIES.toArray()));
Sean Condond2c8d472017-02-17 17:09:39 +0000149 }
150
151 @AfterClass
152 public static void tearDown() throws Exception {
153 if (session1 != null) {
154 session1.close();
155 }
156 if (session2 != null) {
157 session2.close();
158 }
159
160 sshServerNetconf.stop();
161 }
162
163 @Test
164 public void testEditConfigRequest() {
165 log.info("Starting edit-config async");
166 assertNotNull("Incorrect sessionId", session1.getSessionId());
167 try {
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700168 assertTrue("NETCONF edit-config command failed",
169 session1.editConfig(TargetConfig.RUNNING.toString(),
170 null, SAMPLE_REQUEST));
Sean Condond2c8d472017-02-17 17:09:39 +0000171 } catch (NetconfException e) {
172 e.printStackTrace();
173 fail("NETCONF edit-config test failed: " + e.getMessage());
174 }
175 log.info("Finishing edit-config async");
176 }
177
178 @Test
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700179 public void testEditConfigRequestWithOnlyNewConfiguration() {
180 log.info("Starting edit-config async");
181 assertNotNull("Incorrect sessionId", session1.getSessionId());
182 try {
183 assertTrue("NETCONF edit-config command failed",
184 session1.editConfig(EDIT_CONFIG_REQUEST));
185 } catch (NetconfException e) {
186 e.printStackTrace();
187 fail("NETCONF edit-config test failed: " + e.getMessage());
188 }
189 log.info("Finishing edit-config async");
190 }
191
192 @Test
193 public void testDeleteConfigRequestWithRunningTargetConfiguration() {
194 log.info("Starting delete-config async");
195 assertNotNull("Incorrect sessionId", session1.getSessionId());
196 try {
197 assertFalse("NETCONF delete-config command failed",
198 session1.deleteConfig(TargetConfig.RUNNING));
199 } catch (NetconfException e) {
200 e.printStackTrace();
201 fail("NETCONF delete-config test failed: " + e.getMessage());
202 }
203 log.info("Finishing delete-config async");
204 }
205
206 @Test
Sean Condond2c8d472017-02-17 17:09:39 +0000207 public void testCopyConfigRequest() {
208 log.info("Starting copy-config async");
209 assertNotNull("Incorrect sessionId", session1.getSessionId());
210 try {
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700211 assertTrue("NETCONF copy-config command failed",
212 session1.copyConfig(TargetConfig.RUNNING.toString(),
213 "candidate"));
Sean Condond2c8d472017-02-17 17:09:39 +0000214 } catch (NetconfException e) {
215 e.printStackTrace();
216 fail("NETCONF edit-config test failed: " + e.getMessage());
217 }
218 log.info("Finishing copy-config async");
219 }
220
221 @Test
222 public void testGetConfigRequest() {
223 log.info("Starting get-config async");
224 assertNotNull("Incorrect sessionId", session1.getSessionId());
225 try {
226 assertTrue("NETCONF get-config running command failed. ",
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300227 GET_REPLY_PATTERN.matcher(session1.getConfig(RUNNING, SAMPLE_REQUEST)).matches());
Sean Condond2c8d472017-02-17 17:09:39 +0000228
229 assertTrue("NETCONF get-config candidate command failed. ",
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300230 GET_REPLY_PATTERN.matcher(session1.getConfig(CANDIDATE, SAMPLE_REQUEST)).matches());
Sean Condond2c8d472017-02-17 17:09:39 +0000231
232 } catch (NetconfException e) {
233 e.printStackTrace();
234 fail("NETCONF get-config test failed: " + e.getMessage());
235 }
236 log.info("Finishing get-config async");
237 }
238
239 @Test
240 public void testGetRequest() {
241 log.info("Starting get async");
242 assertNotNull("Incorrect sessionId", session1.getSessionId());
243 try {
244 assertTrue("NETCONF get running command failed. ",
245 GET_REPLY_PATTERN.matcher(session1.get(SAMPLE_REQUEST, null)).matches());
246
247 } catch (NetconfException e) {
248 e.printStackTrace();
249 fail("NETCONF get test failed: " + e.getMessage());
250 }
251 log.info("Finishing get async");
252 }
253
254 @Test
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700255 public void testLockRequest() {
256 log.info("Starting lock async");
257 assertNotNull("Incorrect sessionId", session1.getSessionId());
258 try {
259 assertTrue("NETCONF lock request failed", session1.lock());
260 } catch (NetconfException e) {
261 e.printStackTrace();
262 fail("NETCONF lock test failed: " + e.getMessage());
263 }
264 log.info("Finishing lock async");
265 }
266
267 @Test
268 public void testUnLockRequest() {
269 log.info("Starting unlock async");
270 assertNotNull("Incorrect sessionId", session1.getSessionId());
271 try {
272 assertTrue("NETCONF unlock request failed", session1.unlock());
273 } catch (NetconfException e) {
274 e.printStackTrace();
275 fail("NETCONF unlock test failed: " + e.getMessage());
276 }
277 log.info("Finishing unlock async");
278 }
279
280
281 @Test
Sean Condond2c8d472017-02-17 17:09:39 +0000282 public void testConcurrentSameSessionAccess() throws InterruptedException {
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300283 NCCopyConfigCallable testCopyConfig1 = new NCCopyConfigCallable(session1, RUNNING, "candidate");
284 NCCopyConfigCallable testCopyConfig2 = new NCCopyConfigCallable(session1, RUNNING, "startup");
Sean Condond2c8d472017-02-17 17:09:39 +0000285
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800286 FutureTask<Boolean> futureCopyConfig1 = new FutureTask<>(testCopyConfig1);
287 FutureTask<Boolean> futureCopyConfig2 = new FutureTask<>(testCopyConfig2);
Sean Condond2c8d472017-02-17 17:09:39 +0000288
289 ExecutorService executor = Executors.newFixedThreadPool(2);
290 log.info("Starting concurrent execution of copy-config through same session");
291 executor.execute(futureCopyConfig1);
292 executor.execute(futureCopyConfig2);
293
294 int count = 0;
295 while (count < 10) {
296 if (futureCopyConfig1.isDone() && futureCopyConfig2.isDone()) {
297 executor.shutdown();
298 log.info("Finished concurrent same session execution");
299 return;
300 }
301 Thread.sleep(100L);
302 count++;
303 }
304 fail("NETCONF test failed to complete.");
305 }
306
307 @Test
308 public void test2SessionAccess() throws InterruptedException {
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300309 NCCopyConfigCallable testCopySession1 = new NCCopyConfigCallable(session1, RUNNING, "candidate");
310 NCCopyConfigCallable testCopySession2 = new NCCopyConfigCallable(session2, RUNNING, "candidate");
Sean Condond2c8d472017-02-17 17:09:39 +0000311
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800312 FutureTask<Boolean> futureCopySession1 = new FutureTask<>(testCopySession1);
313 FutureTask<Boolean> futureCopySession2 = new FutureTask<>(testCopySession2);
Sean Condond2c8d472017-02-17 17:09:39 +0000314
315 ExecutorService executor = Executors.newFixedThreadPool(2);
316 log.info("Starting concurrent execution of copy-config through 2 different sessions");
317 executor.execute(futureCopySession1);
318 executor.execute(futureCopySession2);
319
320 int count = 0;
321 while (count < 10) {
322 if (futureCopySession1.isDone() && futureCopySession2.isDone()) {
323 executor.shutdown();
324 log.info("Finished concurrent 2 session execution");
325 return;
326 }
327 Thread.sleep(100L);
328 count++;
329 }
330 fail("NETCONF test failed to complete.");
331 }
332
333
334 public static String getTestHelloReply(Optional<Long> sessionId) {
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800335 return getTestHelloReply(DEFAULT_CAPABILITIES, sessionId);
336 }
337
338 public static String getTestHelloReply(Collection<String> capabilities, Optional<Long> sessionId) {
Sean Condond2c8d472017-02-17 17:09:39 +0000339 StringBuffer sb = new StringBuffer();
340
341 sb.append("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">");
342 sb.append("<capabilities>");
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800343 capabilities.forEach(capability -> {
344 sb.append("<capability>").append(capability).append("</capability>");
345 });
Sean Condond2c8d472017-02-17 17:09:39 +0000346 sb.append("</capabilities>");
347 if (sessionId.isPresent()) {
348 sb.append("<session-id>");
349 sb.append(sessionId.get().toString());
350 sb.append("</session-id>");
351 }
352 sb.append("</hello>");
353
354 return sb.toString();
355 }
356
357 public static String getOkReply(Optional<Integer> messageId) {
358 StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
359 sb.append("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
360 if (messageId.isPresent()) {
361 sb.append("message-id=\"");
362 sb.append(String.valueOf(messageId.get()));
363 sb.append("\">");
364 }
365 sb.append("<ok/>");
366 sb.append("</rpc-reply>");
367 return sb.toString();
368 }
369
370 public static String getGetReply(Optional<Integer> messageId) {
371 StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
372 sb.append("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
373 if (messageId.isPresent()) {
374 sb.append("message-id=\"");
375 sb.append(String.valueOf(messageId.get()));
376 sb.append("\">");
377 }
378 sb.append("<data>\n");
379 sb.append(SAMPLE_REQUEST);
380 sb.append("</data>\n");
381 sb.append("</rpc-reply>");
382 return sb.toString();
383 }
384
385 public static final Pattern HELLO_REQ_PATTERN =
386 Pattern.compile("(<\\?xml).*"
387 + "(<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
388 + "( *)(<capabilities>)\\R?"
389 + "( *)(<capability>urn:ietf:params:netconf:base:1.0</capability>)\\R?"
390 + "( *)(</capabilities>)\\R?"
391 + "(</hello>)\\R? *",
392 Pattern.DOTALL);
393
394 public static final Pattern EDIT_CONFIG_REQ_PATTERN =
395 Pattern.compile("(<\\?xml).*"
396 + "(<rpc message-id=\")[0-9]*(\") *(xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
397 + "(<edit-config>)\\R?"
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700398 + "(<target>\\R?((<" + TargetConfig.CANDIDATE.toString() + "/>)|"
399 + "(<" + TargetConfig.RUNNING.toString() + "/>)|"
400 + "(<" + TargetConfig.STARTUP.toString() + "/>))\\R?</target>)\\R?"
Sean Condond2c8d472017-02-17 17:09:39 +0000401 + "(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
402 + ".*"
403 + "(</config>)\\R?(</edit-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
404
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700405
406 public static final Pattern LOCK_REQ_PATTERN =
407 Pattern.compile("(<\\?xml).*"
408 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
409 + "message-id=\")[0-9]*(\">)\\R?"
410 + "(<lock>)\\R?"
411 + "(<target>\\R?((<" + TargetConfig.CANDIDATE.toString() + "/>)|"
412 + "(<" + TargetConfig.RUNNING.toString() + "/>)|"
413 + "(<" + TargetConfig.STARTUP.toString() + "/>))\\R?</target>)\\R?"
414 + "(</lock>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
415
416 public static final Pattern UNLOCK_REQ_PATTERN =
417 Pattern.compile("(<\\?xml).*"
418 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
419 + "message-id=\")[0-9]*(\">)\\R?"
420 + "(<unlock>)\\R?"
421 + "(<target>\\R?((<" + TargetConfig.CANDIDATE.toString() + "/>)|"
422 + "(<" + TargetConfig.RUNNING.toString() + "/>)|"
423 + "(<" + TargetConfig.STARTUP.toString() + "/>))\\R?</target>)\\R?"
424 + "(</unlock>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
425
Sean Condond2c8d472017-02-17 17:09:39 +0000426 public static final Pattern COPY_CONFIG_REQ_PATTERN =
427 Pattern.compile("(<\\?xml).*"
428 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\")[0-9]*(\">)\\R?"
429 + "(<copy-config>)\\R?"
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700430 + "(<target>\\R?((<" + TargetConfig.CANDIDATE.toString() + "/>)|"
431 + "(<" + TargetConfig.RUNNING.toString() + "/>)|"
432 + "(<" + TargetConfig.STARTUP.toString() + "/>))\\R?</target>)\\R?"
433 + "(<source>)\\R?(<config>)(("
434 + TargetConfig.CANDIDATE.toString() + ")|("
435 + TargetConfig.RUNNING.toString() + ")|("
436 + TargetConfig.STARTUP.toString()
437 + "))(</config>)\\R?(</source>)\\R?"
438 + "(</copy-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
Sean Condond2c8d472017-02-17 17:09:39 +0000439
440 public static final Pattern GET_CONFIG_REQ_PATTERN =
441 Pattern.compile("(<\\?xml).*"
442 + "(<rpc message-id=\")[0-9]*(\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700443 + "(<get-config>)\\R?" + "(<source>)\\R?((<"
444 + TargetConfig.CANDIDATE.toString()
445 + "/>)|(<" + TargetConfig.RUNNING.toString()
446 + "/>)|(<" + TargetConfig.STARTUP.toString()
447 + "/>))\\R?(</source>)\\R?"
Sean Condond2c8d472017-02-17 17:09:39 +0000448 + "(<filter type=\"subtree\">).*(</filter>)\\R?"
449 + "(</get-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
450
451 public static final Pattern GET_REPLY_PATTERN =
452 Pattern.compile("(<\\?xml).*"
453 + "(<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\")[0-9]*(\">)\\R?"
454 + "(<data>).*(</data>)\\R?"
455 + "(</rpc-reply>)\\R?", Pattern.DOTALL);
456
457 public static final Pattern GET_REQ_PATTERN =
458 Pattern.compile("(<\\?xml).*"
459 + "(<rpc message-id=\")[0-9]*(\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
460 + "(<get>)\\R?"
461 + "(<filter type=\"subtree\">).*(</filter>)\\R?"
462 + "(</get>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
463
464 public class NCCopyConfigCallable implements Callable<Boolean> {
465 private NetconfSession session;
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300466 private TargetConfig target;
Sean Condond2c8d472017-02-17 17:09:39 +0000467 private String source;
468
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300469 public NCCopyConfigCallable(NetconfSession session, TargetConfig target, String source) {
Sean Condond2c8d472017-02-17 17:09:39 +0000470 this.session = session;
471 this.target = target;
472 this.source = source;
473 }
474
475 @Override
476 public Boolean call() throws Exception {
477 return session.copyConfig(target, source);
478 }
479 }
480}