list4 = Arrays.asList("system-information","host-name");
42 |
43 | String val1= rpc_reply.findValue(list1);
44 | String val2= rpc_reply.findValue(list2);
45 | String val3= rpc_reply.findValue(list3);
46 | String val4= rpc_reply.findValue(list4);
47 |
48 | System.out.println(val1);
49 | System.out.println(val2);
50 | System.out.println(val3);
51 | System.out.println(val4);
52 |
53 | device.close();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/examples/snmp_config.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 Juniper Networks, Inc.
3 | * All Rights Reserved
4 | *
5 | * Use is subject to license terms.
6 | *
7 | */
8 |
9 |
10 | //code to load snmp configuration
11 |
12 | import net.juniper.netconf.CommitException;
13 | import net.juniper.netconf.Device;
14 | import net.juniper.netconf.LoadException;
15 | import net.juniper.netconf.XML;
16 | import net.juniper.netconf.XMLBuilder;
17 | import org.xml.sax.SAXException;
18 |
19 | import javax.xml.parsers.ParserConfigurationException;
20 | import java.io.IOException;
21 |
22 |
23 | /*Build the XML configuration. The XML configuration required is:
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | new-trap-receiver
41 |
42 |
43 |
44 |
45 | 162
46 |
47 | 10.0.0.1
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | XMLBuilder builder = new XMLBuilder();
57 | XML ftp_config = builder.createNewConfig("system", "services", "ftp");
58 |
59 | */
60 |
61 | public class snmp_config {
62 | public static void main(String[] args) throws IOException,
63 | ParserConfigurationException, SAXException {
64 |
65 | XMLBuilder builder = new XMLBuilder();
66 | XML trapGroupConfig = builder.createNewConfig("snmp");
67 | XML trapGroup = trapGroupConfig.addPath("trap-group");
68 | trapGroup.append("group-name", "new-trap-receiver");
69 | XML categories = trapGroup.append("categories");
70 | categories.append("chassis");
71 | categories.append("link");
72 | trapGroup.append("destination-port", "162");
73 | XML targets = trapGroup.append("targets");
74 | targets.append("name", "10.0.0.1");
75 |
76 | Device device = CreateDevice.createDevice();
77 | device.connect();
78 |
79 | //Lock the configuration first
80 | boolean isLocked = device.lockConfig();
81 | if (!isLocked) {
82 | System.out.println("Could not lock configuration. Exit now.");
83 | return;
84 | }
85 |
86 | //Load and commit the configuration
87 | try {
88 | device.loadXMLConfiguration(trapGroupConfig.toString(), "merge");
89 | device.commit();
90 | } catch (LoadException | CommitException e) {
91 | System.out.println(e.getMessage());
92 | return;
93 | }
94 |
95 | //Unlock the configuration and close the device.
96 | device.unlockConfig();
97 | device.close();
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/javadoc/allclasses-frame.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | All Classes (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 | All Classes
14 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/javadoc/allclasses-noframe.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | All Classes (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 | All Classes
14 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/javadoc/constant-values.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Constant Field Values (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
70 |
71 |
78 |
79 |
80 |
81 |
net.juniper.*
82 |
83 |
84 |
108 |
109 |
110 |
141 |
142 |
143 |
144 |
145 |
161 |
162 |
163 | Prev
164 | Next
165 |
166 |
170 |
173 |
174 |
184 |
185 |
186 |
187 |
188 |
189 | Copyright 2018, Juniper Networks, Inc.
190 |
191 |
192 |
--------------------------------------------------------------------------------
/javadoc/deprecated-list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Deprecated List (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
70 |
71 |
75 |
76 |
92 |
119 |
120 | Copyright 2018, Juniper Networks, Inc.
121 |
122 |
123 |
--------------------------------------------------------------------------------
/javadoc/help-doc.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | API Help
8 |
9 |
10 |
11 |
12 |
13 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | PREV
52 | NEXT
53 |
54 | FRAMES
55 | NO FRAMES
56 |
63 |
64 | All Classes
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | How This API Document Is Organized
77 |
78 | This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
79 | Overview
80 |
81 |
82 |
83 | The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.
84 |
85 | Package
86 |
87 |
88 |
89 | Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:
90 | Interfaces (italic) Classes Exceptions Errors
91 |
92 |
93 | Class/Interface
94 |
95 |
96 |
97 | Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:
98 | Class inheritance diagram Direct Subclasses All Known Subinterfaces All Known Implementing Classes Class/interface declaration Class/interface description
99 |
100 |
Nested Class Summary Field Summary Constructor Summary Method Summary
101 |
102 |
Field Detail Constructor Detail Method Detail
103 | Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
104 |
105 | Tree (Class Hierarchy)
106 |
107 | There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object
. The interfaces do not inherit from java.lang.Object
.
108 | When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages. When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
109 |
110 |
111 | Deprecated API
112 |
113 | The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
114 |
115 | Index
116 |
117 | The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
118 |
119 | Prev/Next
120 | These links take you to the next or previous class, interface, package, or related page.
121 | Frames/No Frames
122 | These links show and hide the HTML frames. All pages are available with or without frames.
123 |
124 |
125 | Serialized Form
126 | Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
127 |
128 |
129 |
130 | This help file applies to API documentation generated using the standard doclet.
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 | PREV
163 | NEXT
164 |
165 | FRAMES
166 | NO FRAMES
167 |
174 |
175 | All Classes
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
--------------------------------------------------------------------------------
/javadoc/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | netconf-java 2.0.0 API
8 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | JavaScript is disabled on your browser.
67 |
68 | Frame Alert
69 | This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to Non-frame version .
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/javadoc/net/juniper/netconf/class-use/CommitException.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Uses of Class net.juniper.netconf.CommitException (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
70 |
71 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | Methods in net.juniper.netconf that throw CommitException
84 |
85 | Modifier and Type
86 | Method and Description
87 |
88 |
89 |
90 | void
91 | Device. commit ()
92 | Commit the candidate configuration.
93 |
94 |
95 |
96 | void
97 | Device. commitConfirm (long seconds)
98 | Commit the candidate configuration, temporarily.
99 |
100 |
101 |
102 | void
103 | NetconfSession. commitFull ()
104 | Commit the candidate configuration and rebuild the config database.
105 |
106 |
107 |
108 | void
109 | Device. commitFull ()
110 | Commit full is an unsupported Juniper command that will commit the config and then signal all processes to
111 | check the configuration for changes.
112 |
113 |
114 |
115 | void
116 | Device. commitThisConfiguration (String configFile,
117 | String loadType)
118 | Loads and commits the candidate configuration, Configuration can be in
119 | text/xml format.
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
146 |
147 |
148 | Prev
149 | Next
150 |
151 |
155 |
158 |
159 |
169 |
170 |
171 |
172 |
173 |
174 | Copyright 2018, Juniper Networks, Inc.
175 |
176 |
177 |
--------------------------------------------------------------------------------
/javadoc/net/juniper/netconf/class-use/Device.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Uses of Class net.juniper.netconf.Device (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
70 |
71 |
74 | No usage of net.juniper.netconf.Device
75 |
76 |
92 |
119 |
120 | Copyright 2018, Juniper Networks, Inc.
121 |
122 |
123 |
--------------------------------------------------------------------------------
/javadoc/net/juniper/netconf/class-use/LoadException.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Uses of Class net.juniper.netconf.LoadException (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
70 |
71 |
74 | No usage of net.juniper.netconf.LoadException
75 |
76 |
92 |
119 |
120 | Copyright 2018, Juniper Networks, Inc.
121 |
122 |
123 |
--------------------------------------------------------------------------------
/javadoc/net/juniper/netconf/class-use/NetconfSession.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Uses of Class net.juniper.netconf.NetconfSession (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
70 |
71 |
74 |
115 |
116 |
132 |
133 |
134 | Prev
135 | Next
136 |
137 |
141 |
144 |
145 |
155 |
156 |
157 |
158 |
159 |
160 | Copyright 2018, Juniper Networks, Inc.
161 |
162 |
163 |
--------------------------------------------------------------------------------
/javadoc/net/juniper/netconf/class-use/XMLBuilder.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Uses of Class net.juniper.netconf.XMLBuilder (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
70 |
71 |
74 | No usage of net.juniper.netconf.XMLBuilder
75 |
76 |
92 |
119 |
120 | Copyright 2018, Juniper Networks, Inc.
121 |
122 |
123 |
--------------------------------------------------------------------------------
/javadoc/net/juniper/netconf/package-frame.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | net.juniper.netconf (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
Classes
16 |
22 |
Exceptions
23 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/javadoc/net/juniper/netconf/package-summary.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | net.juniper.netconf (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
44 |
45 | Prev Package
46 | Next Package
47 |
48 |
52 |
55 |
56 |
66 |
67 |
68 |
69 |
70 |
71 |
74 |
75 |
76 |
77 |
78 | Class Summary
79 |
80 | Class
81 | Description
82 |
83 |
84 |
85 | Device
86 |
87 | A Device
is used to define a Netconf server.
88 |
89 |
90 |
91 | NetconfSession
92 |
93 | A NetconfSession
object is used to call the Netconf driver
94 | methods.
95 |
96 |
97 |
98 | XML
99 |
100 | An XML
object represents XML content and provides methods to
101 | manipulate it.
102 |
103 |
104 |
105 | XMLBuilder
106 |
107 | An XMLBuilder
is used to create an XML object.This is useful to
108 | create XML RPC's and configurations.
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 | Exception Summary
117 |
118 | Exception
119 | Description
120 |
121 |
122 |
123 | CommitException
124 |
125 | Describes exceptions related to commit operation
126 |
127 |
128 |
129 | LoadException
130 |
131 | Describes exceptions related to load operation
132 |
133 |
134 |
135 | NetconfException
136 |
137 | Describes exceptions related to establishing Netconf session.
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
162 |
163 |
164 | Prev Package
165 | Next Package
166 |
167 |
171 |
174 |
175 |
185 |
186 |
187 |
188 |
189 |
190 | Copyright 2018, Juniper Networks, Inc.
191 |
192 |
193 |
--------------------------------------------------------------------------------
/javadoc/net/juniper/netconf/package-tree.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | net.juniper.netconf Class Hierarchy (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
70 |
71 |
74 |
75 |
Class Hierarchy
76 |
77 | java.lang.Object
78 |
99 |
100 |
101 |
102 |
103 |
119 |
120 |
121 | Prev
122 | Next
123 |
124 |
128 |
131 |
132 |
142 |
143 |
144 |
145 |
146 |
147 | Copyright 2018, Juniper Networks, Inc.
148 |
149 |
150 |
--------------------------------------------------------------------------------
/javadoc/net/juniper/netconf/package-use.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Uses of Package net.juniper.netconf (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
70 |
71 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | Classes in net.juniper.netconf used by net.juniper.netconf
81 |
82 | Class and Description
83 |
84 |
85 |
86 | CommitException
87 | Describes exceptions related to commit operation
88 |
89 |
90 |
91 | NetconfException
92 | Describes exceptions related to establishing Netconf session.
93 |
94 |
95 |
96 | NetconfSession
97 | A NetconfSession
object is used to call the Netconf driver
98 | methods.
99 |
100 |
101 |
102 | XML
103 | An XML
object represents XML content and provides methods to
104 | manipulate it.
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
129 |
130 |
131 | Prev
132 | Next
133 |
134 |
138 |
141 |
142 |
152 |
153 |
154 |
155 |
156 |
157 | Copyright 2018, Juniper Networks, Inc.
158 |
159 |
160 |
--------------------------------------------------------------------------------
/javadoc/overview-frame.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Overview
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
25 |
26 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/javadoc/overview-summary.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Overview
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | PREV
53 | NEXT
54 |
55 | FRAMES
56 | NO FRAMES
57 |
64 |
65 | All Classes
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 | PREV
170 | NEXT
171 |
172 | FRAMES
173 | NO FRAMES
174 |
181 |
182 | All Classes
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
--------------------------------------------------------------------------------
/javadoc/overview-tree.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Class Hierarchy (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
70 |
71 |
78 |
79 |
Class Hierarchy
80 |
81 | java.lang.Object
82 |
103 |
104 |
105 |
106 |
107 |
123 |
124 |
125 | Prev
126 | Next
127 |
128 |
132 |
135 |
136 |
146 |
147 |
148 |
149 |
150 |
151 | Copyright 2018, Juniper Networks, Inc.
152 |
153 |
154 |
--------------------------------------------------------------------------------
/javadoc/package-list:
--------------------------------------------------------------------------------
1 | net.juniper.netconf
2 |
--------------------------------------------------------------------------------
/javadoc/packages.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | The front page has been relocated.Please see:
25 |
26 | Frame version
27 |
28 | Non-frame version.
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/javadoc/resources/inherit.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Juniper/netconf-java/39debf944b1fca1a83d1b5b64612d304c3e71e85/javadoc/resources/inherit.gif
--------------------------------------------------------------------------------
/javadoc/script.js:
--------------------------------------------------------------------------------
1 | function show(type)
2 | {
3 | count = 0;
4 | for (var key in methods) {
5 | var row = document.getElementById(key);
6 | if ((methods[key] & type) != 0) {
7 | row.style.display = '';
8 | row.className = (count++ % 2) ? rowColor : altColor;
9 | }
10 | else
11 | row.style.display = 'none';
12 | }
13 | updateTabs(type);
14 | }
15 |
16 | function updateTabs(type)
17 | {
18 | for (var value in tabs) {
19 | var sNode = document.getElementById(tabs[value][0]);
20 | var spanNode = sNode.firstChild;
21 | if (value == type) {
22 | sNode.className = activeTableTab;
23 | spanNode.innerHTML = tabs[value][1];
24 | }
25 | else {
26 | sNode.className = tableTab;
27 | spanNode.innerHTML = "" + tabs[value][1] + " ";
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/javadoc/serialized-form.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Serialized Form (netconf-java 2.0.0 API)
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
70 |
71 |
74 |
98 |
99 |
115 |
116 |
117 | Prev
118 | Next
119 |
120 |
124 |
127 |
128 |
138 |
139 |
140 |
141 |
142 |
143 | Copyright 2018, Juniper Networks, Inc.
144 |
145 |
146 |
--------------------------------------------------------------------------------
/javadoc/stylesheet.css:
--------------------------------------------------------------------------------
1 | /* Javadoc style sheet */
2 |
3 | /* Define colors, fonts and other style attributes here to override the defaults */
4 |
5 | /* Page background color */
6 | body { background-color: #FFFFFF }
7 |
8 | /* Headings */
9 | h1 { font-size: 145% }
10 |
11 | /* Table colors */
12 | .TableHeadingColor { background: #CCCCFF } /* Dark mauve */
13 | .TableSubHeadingColor { background: #EEEEFF } /* Light mauve */
14 | .TableRowColor { background: #FFFFFF } /* White */
15 |
16 | /* Font used in left-hand frame lists */
17 | .FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif }
18 | .FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif }
19 | .FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif }
20 |
21 | /* Navigation bar fonts and colors */
22 | .NavBarCell1 { background-color:#EEEEFF;} /* Light mauve */
23 | .NavBarCell1Rev { background-color:#00008B;} /* Dark Blue */
24 | .NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;}
25 | .NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;}
26 |
27 | .NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
28 | .NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
29 |
30 |
--------------------------------------------------------------------------------
/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # https://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Mingw, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | # TODO classpath?
118 | fi
119 |
120 | if [ -z "$JAVA_HOME" ]; then
121 | javaExecutable="`which javac`"
122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
123 | # readlink(1) is not available as standard on Solaris 10.
124 | readLink=`which readlink`
125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
126 | if $darwin ; then
127 | javaHome="`dirname \"$javaExecutable\"`"
128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
129 | else
130 | javaExecutable="`readlink -f \"$javaExecutable\"`"
131 | fi
132 | javaHome="`dirname \"$javaExecutable\"`"
133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
134 | JAVA_HOME="$javaHome"
135 | export JAVA_HOME
136 | fi
137 | fi
138 | fi
139 |
140 | if [ -z "$JAVACMD" ] ; then
141 | if [ -n "$JAVA_HOME" ] ; then
142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
143 | # IBM's JDK on AIX uses strange locations for the executables
144 | JAVACMD="$JAVA_HOME/jre/sh/java"
145 | else
146 | JAVACMD="$JAVA_HOME/bin/java"
147 | fi
148 | else
149 | JAVACMD="`which java`"
150 | fi
151 | fi
152 |
153 | if [ ! -x "$JAVACMD" ] ; then
154 | echo "Error: JAVA_HOME is not defined correctly." >&2
155 | echo " We cannot execute $JAVACMD" >&2
156 | exit 1
157 | fi
158 |
159 | if [ -z "$JAVA_HOME" ] ; then
160 | echo "Warning: JAVA_HOME environment variable is not set."
161 | fi
162 |
163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
164 |
165 | # traverses directory structure from process work directory to filesystem root
166 | # first directory with .mvn subdirectory is considered project base directory
167 | find_maven_basedir() {
168 |
169 | if [ -z "$1" ]
170 | then
171 | echo "Path not specified to find_maven_basedir"
172 | return 1
173 | fi
174 |
175 | basedir="$1"
176 | wdir="$1"
177 | while [ "$wdir" != '/' ] ; do
178 | if [ -d "$wdir"/.mvn ] ; then
179 | basedir=$wdir
180 | break
181 | fi
182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
183 | if [ -d "${wdir}" ]; then
184 | wdir=`cd "$wdir/.."; pwd`
185 | fi
186 | # end of workaround
187 | done
188 | echo "${basedir}"
189 | }
190 |
191 | # concatenates all lines of a file
192 | concat_lines() {
193 | if [ -f "$1" ]; then
194 | echo "$(tr -s '\n' ' ' < "$1")"
195 | fi
196 | }
197 |
198 | BASE_DIR=`find_maven_basedir "$(pwd)"`
199 | if [ -z "$BASE_DIR" ]; then
200 | exit 1;
201 | fi
202 |
203 | ##########################################################################################
204 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
205 | # This allows using the maven wrapper in projects that prohibit checking in binary data.
206 | ##########################################################################################
207 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
208 | if [ "$MVNW_VERBOSE" = true ]; then
209 | echo "Found .mvn/wrapper/maven-wrapper.jar"
210 | fi
211 | else
212 | if [ "$MVNW_VERBOSE" = true ]; then
213 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
214 | fi
215 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
216 | while IFS="=" read key value; do
217 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
218 | esac
219 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
220 | if [ "$MVNW_VERBOSE" = true ]; then
221 | echo "Downloading from: $jarUrl"
222 | fi
223 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
224 |
225 | if command -v wget > /dev/null; then
226 | if [ "$MVNW_VERBOSE" = true ]; then
227 | echo "Found wget ... using wget"
228 | fi
229 | wget "$jarUrl" -O "$wrapperJarPath"
230 | elif command -v curl > /dev/null; then
231 | if [ "$MVNW_VERBOSE" = true ]; then
232 | echo "Found curl ... using curl"
233 | fi
234 | curl -o "$wrapperJarPath" "$jarUrl"
235 | else
236 | if [ "$MVNW_VERBOSE" = true ]; then
237 | echo "Falling back to using Java to download"
238 | fi
239 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
240 | if [ -e "$javaClass" ]; then
241 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
242 | if [ "$MVNW_VERBOSE" = true ]; then
243 | echo " - Compiling MavenWrapperDownloader.java ..."
244 | fi
245 | # Compiling the Java class
246 | ("$JAVA_HOME/bin/javac" "$javaClass")
247 | fi
248 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
249 | # Running the downloader
250 | if [ "$MVNW_VERBOSE" = true ]; then
251 | echo " - Running MavenWrapperDownloader.java ..."
252 | fi
253 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
254 | fi
255 | fi
256 | fi
257 | fi
258 | ##########################################################################################
259 | # End of extension
260 | ##########################################################################################
261 |
262 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
263 | if [ "$MVNW_VERBOSE" = true ]; then
264 | echo $MAVEN_PROJECTBASEDIR
265 | fi
266 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
267 |
268 | # For Cygwin, switch paths to Windows format before running java
269 | if $cygwin; then
270 | [ -n "$M2_HOME" ] &&
271 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
272 | [ -n "$JAVA_HOME" ] &&
273 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
274 | [ -n "$CLASSPATH" ] &&
275 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
276 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
277 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
278 | fi
279 |
280 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
281 |
282 | exec "$JAVACMD" \
283 | $MAVEN_OPTS \
284 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
285 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
286 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
287 |
--------------------------------------------------------------------------------
/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM https://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM set title of command window
39 | title %0
40 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
42 |
43 | @REM set %HOME% to equivalent of $HOME
44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
45 |
46 | @REM Execute a user defined script before this one
47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
51 | :skipRcPre
52 |
53 | @setlocal
54 |
55 | set ERROR_CODE=0
56 |
57 | @REM To isolate internal variables from possible post scripts, we use another setlocal
58 | @setlocal
59 |
60 | @REM ==== START VALIDATION ====
61 | if not "%JAVA_HOME%" == "" goto OkJHome
62 |
63 | echo.
64 | echo Error: JAVA_HOME not found in your environment. >&2
65 | echo Please set the JAVA_HOME variable in your environment to match the >&2
66 | echo location of your Java installation. >&2
67 | echo.
68 | goto error
69 |
70 | :OkJHome
71 | if exist "%JAVA_HOME%\bin\java.exe" goto init
72 |
73 | echo.
74 | echo Error: JAVA_HOME is set to an invalid directory. >&2
75 | echo JAVA_HOME = "%JAVA_HOME%" >&2
76 | echo Please set the JAVA_HOME variable in your environment to match the >&2
77 | echo location of your Java installation. >&2
78 | echo.
79 | goto error
80 |
81 | @REM ==== END VALIDATION ====
82 |
83 | :init
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
122 |
123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
126 | )
127 |
128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data.
130 | if exist %WRAPPER_JAR% (
131 | echo Found %WRAPPER_JAR%
132 | ) else (
133 | echo Couldn't find %WRAPPER_JAR%, downloading it ...
134 | echo Downloading from: %DOWNLOAD_URL%
135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
136 | echo Finished downloading %WRAPPER_JAR%
137 | )
138 | @REM End of extension
139 |
140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
141 | if ERRORLEVEL 1 goto error
142 | goto end
143 |
144 | :error
145 | set ERROR_CODE=1
146 |
147 | :end
148 | @endlocal & set ERROR_CODE=%ERROR_CODE%
149 |
150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
154 | :skipRcPost
155 |
156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
158 |
159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
160 |
161 | exit /B %ERROR_CODE%
162 |
--------------------------------------------------------------------------------
/src/main/java/net/juniper/netconf/CommitException.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2013 Juniper Networks, Inc.
3 | All Rights Reserved
4 |
5 | Use is subject to license terms.
6 |
7 | */
8 |
9 | package net.juniper.netconf;
10 |
11 | import java.io.IOException;
12 |
13 | /**
14 | * Describes exceptions related to commit operation
15 | */
16 | public class CommitException extends IOException {
17 | CommitException(String msg) {
18 | super(msg);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/net/juniper/netconf/LoadException.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2013 Juniper Networks, Inc.
3 | All Rights Reserved
4 |
5 | Use is subject to license terms.
6 |
7 | */
8 |
9 | package net.juniper.netconf;
10 |
11 | import java.io.IOException;
12 |
13 | /**
14 | * Describes exceptions related to load operation
15 | */
16 | public class LoadException extends IOException {
17 |
18 | LoadException(String msg) {
19 | super(msg);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/net/juniper/netconf/NetconfConstants.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf;
2 |
3 | /**
4 | * @author Jonas Glass
5 | */
6 | public class NetconfConstants {
7 |
8 | private NetconfConstants() {
9 | }
10 |
11 | /**
12 | * Device prompt for the framing protocol.
13 | * https://tools.ietf.org/html/rfc6242#section-4.1
14 | */
15 | public static final String DEVICE_PROMPT = "]]>]]>";
16 |
17 | /**
18 | * XML Schema prefix.
19 | */
20 | public static final String XML_VERSION = "";
21 |
22 | /**
23 | * XML Namespace for NETCONF Base 1.0
24 | * https://tools.ietf.org/html/rfc6241#section-8.1
25 | */
26 | public static final String URN_XML_NS_NETCONF_BASE_1_0 = "urn:ietf:params:xml:ns:netconf:base:1.0";
27 |
28 | /**
29 | * URN for NETCONF Base 1.0
30 | * https://tools.ietf.org/html/rfc6241#section-8.1
31 | */
32 | public static final String URN_IETF_PARAMS_NETCONF_BASE_1_0 = "urn:ietf:params:netconf:base:1.0";
33 |
34 | public static final String EMPTY_LINE = "";
35 | public static final String LF = "\n";
36 | public static final String CR = "\r";
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/net/juniper/netconf/NetconfException.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2013 Juniper Networks, Inc.
3 | All Rights Reserved
4 |
5 | Use is subject to license terms.
6 |
7 | */
8 |
9 | package net.juniper.netconf;
10 |
11 | import java.io.IOException;
12 |
13 | /**
14 | * Describes exceptions related to establishing Netconf session.
15 | */
16 | public class NetconfException extends IOException {
17 | public NetconfException(String msg) {
18 | super(msg);
19 | }
20 |
21 | public NetconfException(String msg, Throwable t) {
22 | super(msg, t);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/net/juniper/netconf/element/AbstractNetconfElement.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf.element;
2 |
3 | import lombok.EqualsAndHashCode;
4 | import lombok.ToString;
5 | import lombok.Value;
6 | import lombok.experimental.NonFinal;
7 | import net.juniper.netconf.NetconfConstants;
8 | import org.w3c.dom.Document;
9 | import org.w3c.dom.Element;
10 |
11 | import javax.xml.parsers.DocumentBuilderFactory;
12 | import javax.xml.parsers.ParserConfigurationException;
13 | import javax.xml.transform.OutputKeys;
14 | import javax.xml.transform.Transformer;
15 | import javax.xml.transform.TransformerException;
16 | import javax.xml.transform.TransformerFactory;
17 | import javax.xml.transform.dom.DOMSource;
18 | import javax.xml.transform.stream.StreamResult;
19 | import java.io.StringWriter;
20 |
21 | import static java.lang.String.format;
22 |
23 | @Value
24 | @NonFinal
25 | public abstract class AbstractNetconfElement {
26 |
27 | @ToString.Exclude
28 | @EqualsAndHashCode.Exclude
29 | Document document;
30 |
31 | @ToString.Exclude
32 | String xml;
33 |
34 | protected AbstractNetconfElement(final Document document) {
35 | this.document = document;
36 | this.xml = createXml(document);
37 | }
38 |
39 | protected static Document createBlankDocument() {
40 | try {
41 | return createDocumentBuilderFactory().newDocumentBuilder().newDocument();
42 | } catch (final ParserConfigurationException e) {
43 | throw new IllegalStateException("Unable to create document builder", e);
44 | }
45 | }
46 |
47 | protected static DocumentBuilderFactory createDocumentBuilderFactory() {
48 | final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
49 | documentBuilderFactory.setNamespaceAware(true);
50 | return documentBuilderFactory;
51 | }
52 |
53 | protected static String createXml(final Document document) {
54 | try {
55 | final TransformerFactory transformerFactory = TransformerFactory.newInstance();
56 | final Transformer transformer = transformerFactory.newTransformer();
57 | transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
58 | final StringWriter stringWriter = new StringWriter();
59 | transformer.transform(new DOMSource(document), new StreamResult(stringWriter));
60 | return stringWriter.toString();
61 | } catch (final TransformerException e) {
62 | throw new IllegalStateException("Unable to transform document to XML", e);
63 | }
64 | }
65 |
66 | protected static String getXpathFor(final String elementName) {
67 | return format("/*[namespace-uri()='urn:ietf:params:xml:ns:netconf:base:1.0' and local-name()='%s']", elementName);
68 | }
69 |
70 | protected static Element appendElementWithText(
71 | final Document document,
72 | final Element parentElement,
73 | final String namespacePrefix,
74 | final String elementName,
75 | final String text) {
76 |
77 | if (text != null) {
78 | final Element childElement = document.createElementNS(NetconfConstants.URN_XML_NS_NETCONF_BASE_1_0, elementName);
79 | childElement.setPrefix(namespacePrefix);
80 | childElement.setTextContent(text);
81 | parentElement.appendChild(childElement);
82 | return childElement;
83 | } else {
84 | return null;
85 | }
86 | }
87 |
88 | protected static String getAttribute(final Element element, final String attributeName) {
89 | if (element != null && element.hasAttribute(attributeName)) {
90 | return element.getAttribute(attributeName);
91 | } else {
92 | return null;
93 | }
94 | }
95 |
96 | protected static String getTextContent(final Element element) {
97 | if (element == null) {
98 | return null;
99 | } else {
100 | return trim(element.getTextContent());
101 | }
102 | }
103 |
104 | protected static String trim(final String string) {
105 | return string == null ? null : string.trim();
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/main/java/net/juniper/netconf/element/Datastore.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf.element;
2 |
3 | import java.util.Locale;
4 |
5 | /**
6 | * Datastore
7 | *
8 | * As defined by RFC-8342.
9 | * See https://datatracker.ietf.org/doc/html/rfc8342#section-5
10 | */
11 | public enum Datastore {
12 | RUNNING, CANDIDATE, STARTUP, INTENDED, OPERATIONAL;
13 |
14 | @Override
15 | public String toString() {
16 | return this.name().toLowerCase(Locale.US);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/net/juniper/netconf/element/Hello.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf.element;
2 |
3 | import lombok.Builder;
4 | import lombok.EqualsAndHashCode;
5 | import lombok.Singular;
6 | import lombok.ToString;
7 | import lombok.Value;
8 | import lombok.extern.slf4j.Slf4j;
9 | import net.juniper.netconf.NetconfConstants;
10 | import org.w3c.dom.Document;
11 | import org.w3c.dom.Element;
12 | import org.w3c.dom.Node;
13 | import org.w3c.dom.NodeList;
14 | import org.xml.sax.InputSource;
15 | import org.xml.sax.SAXException;
16 |
17 | import javax.xml.parsers.ParserConfigurationException;
18 | import javax.xml.xpath.XPath;
19 | import javax.xml.xpath.XPathConstants;
20 | import javax.xml.xpath.XPathExpressionException;
21 | import javax.xml.xpath.XPathFactory;
22 | import java.io.IOException;
23 | import java.io.StringReader;
24 | import java.util.List;
25 |
26 | /**
27 | * Class to represent a NETCONF hello element - https://datatracker.ietf.org/doc/html/rfc6241#section-8.1
28 | */
29 | @Slf4j
30 | @Value
31 | @ToString(callSuper = true)
32 | @EqualsAndHashCode(callSuper = true)
33 | public class Hello extends AbstractNetconfElement {
34 |
35 | private static final String XPATH_HELLO = getXpathFor("hello");
36 | private static final String XPATH_HELLO_SESSION_ID = XPATH_HELLO + getXpathFor("session-id");
37 | private static final String XPATH_HELLO_CAPABILITIES = XPATH_HELLO + getXpathFor("capabilities");
38 | private static final String XPATH_HELLO_CAPABILITIES_CAPABILITY = XPATH_HELLO_CAPABILITIES + getXpathFor("capability");
39 |
40 | String sessionId;
41 |
42 | @Singular("capability")
43 | List capabilities;
44 |
45 | public boolean hasCapability(final String capability) {
46 | return capabilities.contains(capability);
47 | }
48 |
49 | /**
50 | * Creates a Hello object based on the supplied XML.
51 | *
52 | * @param xml The XML of the NETCONF <hello>
53 | * @return an new, immutable, Hello object.
54 | * @throws ParserConfigurationException If the XML parser cannot be created
55 | * @throws IOException If the XML cannot be read
56 | * @throws SAXException If the XML cannot be parsed
57 | * @throws XPathExpressionException If there is a problem in the parsing expressions
58 | */
59 | public static Hello from(final String xml)
60 | throws ParserConfigurationException, IOException, SAXException, XPathExpressionException {
61 |
62 | final Document document = createDocumentBuilderFactory().newDocumentBuilder()
63 | .parse(new InputSource(new StringReader(xml)));
64 | final XPath xPath = XPathFactory.newInstance().newXPath();
65 | final String sessionId = xPath.evaluate(XPATH_HELLO_SESSION_ID, document);
66 | final HelloBuilder builder = Hello.builder()
67 | .originalDocument(document)
68 | .sessionId(sessionId);
69 | final NodeList capabilities = (NodeList) xPath.evaluate(XPATH_HELLO_CAPABILITIES_CAPABILITY, document, XPathConstants.NODESET);
70 | for (int i = 0; i < capabilities.getLength(); i++) {
71 | final Node node = capabilities.item(i);
72 | builder.capability(node.getTextContent());
73 | }
74 | final Hello hello = builder.build();
75 | log.info("hello is: {}", hello.getXml());
76 | return hello;
77 | }
78 |
79 | @Builder
80 | private Hello(
81 | final Document originalDocument,
82 | final String namespacePrefix,
83 | final String sessionId,
84 | @Singular("capability") final List capabilities) {
85 | super(getDocument(originalDocument, namespacePrefix, sessionId, capabilities));
86 | this.sessionId = sessionId;
87 | this.capabilities = capabilities;
88 | }
89 |
90 | private static Document getDocument(
91 | final Document originalDocument,
92 | final String namespacePrefix,
93 | final String sessionId,
94 | final List capabilities) {
95 | if (originalDocument != null) {
96 | return originalDocument;
97 | } else {
98 | return createDocument(namespacePrefix, sessionId, capabilities);
99 | }
100 | }
101 |
102 | private static Document createDocument(
103 | final String namespacePrefix,
104 | final String sessionId,
105 | final List capabilities) {
106 |
107 | final Document createdDocument = createBlankDocument();
108 |
109 | final Element helloElement
110 | = createdDocument.createElementNS(NetconfConstants.URN_XML_NS_NETCONF_BASE_1_0, "hello");
111 | helloElement.setPrefix(namespacePrefix);
112 | createdDocument.appendChild(helloElement);
113 |
114 | final Element capabilitiesElement
115 | = createdDocument.createElementNS(NetconfConstants.URN_XML_NS_NETCONF_BASE_1_0, "capabilities");
116 | capabilitiesElement.setPrefix(namespacePrefix);
117 | capabilities.forEach(capability -> {
118 | final Element capabilityElement =
119 | createdDocument.createElementNS(NetconfConstants.URN_XML_NS_NETCONF_BASE_1_0, "capability");
120 | capabilityElement.setTextContent(capability);
121 | capabilityElement.setPrefix(namespacePrefix);
122 | capabilitiesElement.appendChild(capabilityElement);
123 | });
124 | helloElement.appendChild(capabilitiesElement);
125 |
126 | if (sessionId != null) {
127 | final Element sessionIdElement
128 | = createdDocument.createElementNS(NetconfConstants.URN_XML_NS_NETCONF_BASE_1_0, "session-id");
129 | sessionIdElement.setPrefix(namespacePrefix);
130 | sessionIdElement.setTextContent(sessionId);
131 | helloElement.appendChild(sessionIdElement);
132 | }
133 | return createdDocument;
134 | }
135 |
136 | }
137 |
--------------------------------------------------------------------------------
/src/main/java/net/juniper/netconf/element/RpcError.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf.element;
2 |
3 | import lombok.AccessLevel;
4 | import lombok.Builder;
5 | import lombok.Getter;
6 | import lombok.RequiredArgsConstructor;
7 | import lombok.Value;
8 |
9 | /**
10 | * Class to represent a NETCONF rpc-error element - https://datatracker.ietf.org/doc/html/rfc6241#section-4.3
11 | */
12 | @Value
13 | @Builder
14 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
15 | public class RpcError {
16 |
17 | ErrorType errorType;
18 | ErrorTag errorTag;
19 | ErrorSeverity errorSeverity;
20 | String errorPath;
21 | String errorMessage;
22 | String errorMessageLanguage;
23 | RpcErrorInfo errorInfo;
24 |
25 | @Getter
26 | @RequiredArgsConstructor
27 | public enum ErrorType {
28 | TRANSPORT("transport"), RPC("rpc"), PROTOCOL("protocol"), APPLICATION("application");
29 |
30 | private final String textContent;
31 |
32 | public static ErrorType from(final String textContent) {
33 | for (final ErrorType errorType : ErrorType.values()) {
34 | if (errorType.textContent.equals(textContent)) {
35 | return errorType;
36 | }
37 | }
38 | return null;
39 | }
40 | }
41 |
42 | @Getter
43 | @RequiredArgsConstructor
44 | public enum ErrorTag {
45 | IN_USE("in-use"),
46 | INVALID_VALUE("invalid-value"),
47 | TOO_BIG("too-big"),
48 | MISSING_ATTRIBUTE("missing-attribute"),
49 | BAD_ATTRIBUTE("bad-attribute"),
50 | UNKNOWN_ATTRIBUTE("unknown-attribute"),
51 | MISSING_ELEMENT("missing-element"),
52 | BAD_ELEMENT("bad-element"),
53 | UNKNOWN_ELEMENT("unknown-element"),
54 | UNKNOWN_NAMESPACE("unknown-namespace"),
55 | ACCESS_DENIED("access-denied"),
56 | LOCK_DENIED("lock-denied"),
57 | DATA_EXISTS("data-exists"),
58 | DATA_MISSING("data-missing"),
59 | OPERATION_NOT_SUPPORTED("operation-not-supported"),
60 | OPERATION_FAILED("operation-failed"),
61 | PARTIAL_OPERATION("partial-operation"),
62 | MALFORMED_MESSAGE("malformed-message");
63 |
64 | private final String textContent;
65 |
66 | public static ErrorTag from(final String textContent) {
67 | for (final ErrorTag errorTag : ErrorTag.values()) {
68 | if (errorTag.textContent.equals(textContent)) {
69 | return errorTag;
70 | }
71 | }
72 | return null;
73 | }
74 | }
75 |
76 | @Getter
77 | @RequiredArgsConstructor
78 | public enum ErrorSeverity {
79 | ERROR("error"), WARNING("warning");
80 |
81 | private final String textContent;
82 |
83 | public static ErrorSeverity from(final String textContent) {
84 | for (final ErrorSeverity errorSeverity : ErrorSeverity.values()) {
85 | if (errorSeverity.textContent.equals(textContent)) {
86 | return errorSeverity;
87 | }
88 | }
89 | return null;
90 | }
91 | }
92 |
93 | /**
94 | * Class to represent a NETCONF rpc error-info element - https://datatracker.ietf.org/doc/html/rfc6241#section-4.3
95 | */
96 | @Value
97 | @Builder
98 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
99 | public static class RpcErrorInfo {
100 |
101 | String badAttribute;
102 | String badElement;
103 | String badNamespace;
104 | String sessionId;
105 | String okElement;
106 | String errElement;
107 | String noOpElement;
108 |
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/main/java/net/juniper/netconf/element/RpcReplyLoadConfigResults.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf.element;
2 |
3 | import lombok.Builder;
4 | import lombok.EqualsAndHashCode;
5 | import lombok.Singular;
6 | import lombok.ToString;
7 | import lombok.Value;
8 | import lombok.experimental.NonFinal;
9 | import lombok.extern.slf4j.Slf4j;
10 | import net.juniper.netconf.NetconfConstants;
11 | import org.w3c.dom.Document;
12 | import org.w3c.dom.Element;
13 | import org.xml.sax.InputSource;
14 | import org.xml.sax.SAXException;
15 |
16 | import javax.xml.parsers.ParserConfigurationException;
17 | import javax.xml.xpath.XPath;
18 | import javax.xml.xpath.XPathConstants;
19 | import javax.xml.xpath.XPathExpressionException;
20 | import javax.xml.xpath.XPathFactory;
21 | import java.io.IOException;
22 | import java.io.StringReader;
23 | import java.util.List;
24 |
25 | @Slf4j
26 | @Value
27 | @NonFinal
28 | @ToString(callSuper = true)
29 | @EqualsAndHashCode(callSuper = true)
30 | public class RpcReplyLoadConfigResults extends RpcReply {
31 |
32 | static final String XPATH_RPC_REPLY_LOAD_CONFIG_RESULT = RpcReply.XPATH_RPC_REPLY + "/*[local-name()='load-configuration-results']";
33 | private static final String XPATH_RPC_REPLY_LOAD_CONFIG_RESULT_OK = XPATH_RPC_REPLY_LOAD_CONFIG_RESULT + getXpathFor("ok");
34 | private static final String XPATH_RPC_REPLY_LOAD_CONFIG_RESULT_ERROR = XPATH_RPC_REPLY_LOAD_CONFIG_RESULT + getXpathFor("rpc-error");
35 |
36 | String action;
37 |
38 | public static RpcReplyLoadConfigResults from(final String xml)
39 | throws ParserConfigurationException, IOException, SAXException, XPathExpressionException {
40 |
41 | final Document document = createDocumentBuilderFactory().newDocumentBuilder()
42 | .parse(new InputSource(new StringReader(xml)));
43 | final XPath xPath = XPathFactory.newInstance().newXPath();
44 |
45 | final Element rpcReplyElement = (Element) xPath.evaluate(XPATH_RPC_REPLY, document, XPathConstants.NODE);
46 | final Element loadConfigResultsElement = (Element) xPath.evaluate(RpcReplyLoadConfigResults.XPATH_RPC_REPLY_LOAD_CONFIG_RESULT, document, XPathConstants.NODE);
47 | final Element rpcReplyOkElement = (Element) xPath.evaluate(XPATH_RPC_REPLY_LOAD_CONFIG_RESULT_OK, document, XPathConstants.NODE);
48 | final List errorList = getRpcErrors(document, xPath, XPATH_RPC_REPLY_LOAD_CONFIG_RESULT_ERROR);
49 |
50 | return RpcReplyLoadConfigResults.loadConfigResultsBuilder()
51 | .messageId(getAttribute(rpcReplyElement, "message-id"))
52 | .action(getAttribute(loadConfigResultsElement, "action"))
53 | .ok(rpcReplyOkElement != null)
54 | .errors(errorList)
55 | .originalDocument(document)
56 | .build();
57 | }
58 |
59 | @Builder(builderMethodName = "loadConfigResultsBuilder")
60 | private RpcReplyLoadConfigResults(
61 | final Document originalDocument,
62 | final String namespacePrefix,
63 | final String messageId,
64 | final String action,
65 | final boolean ok,
66 | @Singular("error") final List errors) {
67 | super(getDocument(originalDocument, namespacePrefix, messageId, action, ok, errors),
68 | namespacePrefix, messageId, ok, errors);
69 | this.action = action;
70 | }
71 |
72 | private static Document getDocument(
73 | final Document originalDocument,
74 | final String namespacePrefix,
75 | final String messageId,
76 | final String action,
77 | final boolean ok,
78 | final List errors) {
79 | if (originalDocument != null) {
80 | return originalDocument;
81 | } else {
82 | return createDocument(namespacePrefix, messageId, action, ok, errors);
83 | }
84 | }
85 |
86 | private static Document createDocument(
87 | final String namespacePrefix,
88 | final String messageId,
89 | final String action,
90 | final boolean ok,
91 | final List errors) {
92 | final Document createdDocument = createBlankDocument();
93 | final Element rpcReplyElement = createdDocument.createElementNS(NetconfConstants.URN_XML_NS_NETCONF_BASE_1_0, "rpc-reply");
94 | rpcReplyElement.setPrefix(namespacePrefix);
95 | rpcReplyElement.setAttribute("message-id", messageId);
96 | createdDocument.appendChild(rpcReplyElement);
97 | final Element loadConfigResultsElement = createdDocument.createElement("load-configuration-results");
98 | loadConfigResultsElement.setAttribute("action", action);
99 | rpcReplyElement.appendChild(loadConfigResultsElement);
100 | appendErrors(namespacePrefix, errors, createdDocument, loadConfigResultsElement);
101 | if (ok) {
102 | final Element okElement = createdDocument.createElementNS(NetconfConstants.URN_XML_NS_NETCONF_BASE_1_0, "ok");
103 | okElement.setPrefix(namespacePrefix);
104 | loadConfigResultsElement.appendChild(okElement);
105 | }
106 |
107 | return createdDocument;
108 | }
109 | }
--------------------------------------------------------------------------------
/src/test/java/net/juniper/netconf/CommitExceptionTest.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf;
2 |
3 | import org.junit.Test;
4 | import org.junit.experimental.categories.Category;
5 |
6 | import static org.assertj.core.api.Assertions.assertThatThrownBy;
7 |
8 | @Category(Test.class)
9 | public class CommitExceptionTest {
10 | private static final String TEST_MESSAGE = "test message";
11 |
12 | private void throwCommitException() throws CommitException {
13 | throw new CommitException(TEST_MESSAGE);
14 | }
15 |
16 | @Test
17 | public void GIVEN_newCommitException_THEN_exceptionCreated() {
18 | assertThatThrownBy(this::throwCommitException)
19 | .isInstanceOf(CommitException.class)
20 | .hasMessage(TEST_MESSAGE);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/test/java/net/juniper/netconf/DatastoreTest.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf;
2 |
3 | import net.juniper.netconf.element.Datastore;
4 | import org.junit.Test;
5 |
6 | import static org.hamcrest.Matchers.is;
7 | import static org.junit.Assert.assertThat;
8 |
9 | public class DatastoreTest {
10 | @Test
11 | public void testDatastoreName() {
12 | assertThat(Datastore.OPERATIONAL.toString(), is("operational"));
13 | assertThat(Datastore.RUNNING.toString(), is("running"));
14 | assertThat(Datastore.CANDIDATE.toString(), is("candidate"));
15 | assertThat(Datastore.STARTUP.toString(), is("startup"));
16 | assertThat(Datastore.INTENDED.toString(), is("intended"));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/test/java/net/juniper/netconf/DeviceTest.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf;
2 |
3 | import com.jcraft.jsch.ChannelSubsystem;
4 | import com.jcraft.jsch.HostKeyRepository;
5 | import com.jcraft.jsch.JSch;
6 | import com.jcraft.jsch.JSchException;
7 | import com.jcraft.jsch.Session;
8 | import org.junit.Before;
9 | import org.junit.Test;
10 | import org.junit.experimental.categories.Category;
11 | import org.xmlunit.assertj.XmlAssert;
12 |
13 | import java.io.ByteArrayInputStream;
14 | import java.io.ByteArrayOutputStream;
15 | import java.io.IOException;
16 | import java.nio.charset.StandardCharsets;
17 | import java.util.Collections;
18 |
19 | import static org.assertj.core.api.Assertions.assertThat;
20 | import static org.assertj.core.api.Assertions.assertThatThrownBy;
21 | import static org.junit.Assert.assertFalse;
22 | import static org.junit.Assert.assertNull;
23 | import static org.mockito.ArgumentMatchers.anyString;
24 | import static org.mockito.ArgumentMatchers.eq;
25 | import static org.mockito.Mockito.doThrow;
26 | import static org.mockito.Mockito.mock;
27 | import static org.mockito.Mockito.times;
28 | import static org.mockito.Mockito.verify;
29 | import static org.mockito.Mockito.verifyNoMoreInteractions;
30 | import static org.mockito.Mockito.when;
31 |
32 | @Category(Test.class)
33 | public class DeviceTest {
34 |
35 | private static final String TEST_HOSTNAME = "hostname";
36 | private static final String TEST_USERNAME = "username";
37 | private static final String TEST_PASSWORD = "password";
38 | private static final int DEFAULT_NETCONF_PORT = 830;
39 | private static final int DEFAULT_TIMEOUT = 5000;
40 | private static final String SUBSYSTEM = "subsystem";
41 | private static final String HELLO_WITH_DEFAULT_CAPABILITIES = ""
42 | + "\n"
43 | + "\n"
44 | + "urn:ietf:params:netconf:base:1.0 \n"
45 | + "urn:ietf:params:netconf:base:1.0#candidate \n"
46 | + "urn:ietf:params:netconf:base:1.0#confirmed-commit \n"
47 | + "urn:ietf:params:netconf:base:1.0#validate \n"
48 | + "urn:ietf:params:netconf:base:1.0#url?protocol=http,ftp,file \n"
49 | + " \n"
50 | + " ";
51 | private static final String HELLO_WITH_BASE_CAPABILITIES = ""
52 | + "\n"
53 | + "\n"
54 | + "urn:ietf:params:netconf:base:1.0 \n"
55 | + " \n"
56 | + " ";
57 |
58 | private ByteArrayOutputStream outputStream;
59 |
60 | private Device createTestDevice() throws NetconfException {
61 | return Device.builder()
62 | .hostName(TEST_HOSTNAME)
63 | .userName(TEST_USERNAME)
64 | .password(TEST_PASSWORD)
65 | .strictHostKeyChecking(false)
66 | .build();
67 | }
68 |
69 | @Before
70 | public void setUp() {
71 | outputStream = new ByteArrayOutputStream();
72 | }
73 |
74 | @Test
75 | public void GIVEN_requiredParameters_THEN_createDevice() throws NetconfException {
76 | Device device = createTestDevice();
77 | assertThat(device.getHostName()).isEqualTo(TEST_HOSTNAME);
78 | assertThat(device.getUserName()).isEqualTo(TEST_USERNAME);
79 | assertThat(device.getPassword()).isEqualTo(TEST_PASSWORD);
80 | assertThat(device.getPort()).isEqualTo(DEFAULT_NETCONF_PORT);
81 | assertThat(device.getConnectionTimeout()).isEqualTo(DEFAULT_TIMEOUT);
82 | assertThat(device.getCommandTimeout()).isEqualTo(DEFAULT_TIMEOUT);
83 | assertFalse(device.isKeyBasedAuthentication());
84 | assertNull(device.getPemKeyFile());
85 | assertNull(device.getHostKeysFileName());
86 | }
87 |
88 | @Test
89 | public void GIVEN_sshAvailableNetconfNot_THEN_closeDevice() throws Exception {
90 | JSch sshClient = mock(JSch.class);
91 | Session session = mock(Session.class);
92 | HostKeyRepository hostKeyRepository = mock(HostKeyRepository.class);
93 | ChannelSubsystem channel = mock(ChannelSubsystem.class);
94 | when(channel.isConnected()).thenReturn(false);
95 |
96 | when(session.isConnected()).thenReturn(true);
97 | when(session.openChannel(eq(SUBSYSTEM))).thenReturn(channel);
98 | doThrow(new JSchException("failed to send channel request")).when(channel).connect(eq(DEFAULT_TIMEOUT));
99 |
100 | when(sshClient.getSession(eq(TEST_USERNAME), eq(TEST_HOSTNAME), eq(DEFAULT_NETCONF_PORT))).thenReturn(session);
101 | when(sshClient.getHostKeyRepository()).thenReturn(hostKeyRepository);
102 |
103 | try (Device device = Device.builder()
104 | .sshClient(sshClient)
105 | .hostName(TEST_HOSTNAME)
106 | .userName(TEST_USERNAME)
107 | .password(TEST_PASSWORD)
108 | .strictHostKeyChecking(false)
109 | .build()) {
110 | device.connect();
111 | } catch (NetconfException e) {
112 | // Do nothing
113 | }
114 |
115 | verify(channel).connect(eq(DEFAULT_TIMEOUT));
116 | verify(channel).setSubsystem(anyString());
117 | verify(channel).getInputStream();
118 | verify(channel).getOutputStream();
119 | verify(channel).isConnected();
120 |
121 | verify(session).disconnect();
122 | verify(session).openChannel(eq(SUBSYSTEM));
123 | verify(session, times(2)).isConnected();
124 | verify(session).getTimeout();
125 | verify(session).connect(eq(DEFAULT_TIMEOUT));
126 | verify(session).setTimeout(eq(DEFAULT_TIMEOUT));
127 | verify(session, times(2)).setConfig(anyString(), anyString());
128 | verify(session).setPassword(anyString());
129 |
130 | verify(sshClient).getSession(eq(TEST_USERNAME), eq(TEST_HOSTNAME), eq(DEFAULT_NETCONF_PORT));
131 | verify(sshClient).getHostKeyRepository();
132 | verify(sshClient).setHostKeyRepository(hostKeyRepository);
133 |
134 | verifyNoMoreInteractions(channel);
135 | verifyNoMoreInteractions(session);
136 | verifyNoMoreInteractions(sshClient);
137 | }
138 |
139 | @Test
140 | public void GIVEN_newDevice_WHEN_withNullUserName_THEN_throwsException() {
141 | assertThatThrownBy(() -> Device.builder().hostName("foo").build())
142 | .isInstanceOf(NullPointerException.class)
143 | .hasMessage("userName is marked non-null but is null");
144 | }
145 |
146 | @Test
147 | public void GIVEN_newDevice_WHEN_withHostName_THEN_throwsException() {
148 | assertThatThrownBy(() -> Device.builder().userName("foo").build())
149 | .isInstanceOf(NullPointerException.class)
150 | .hasMessage("hostName is marked non-null but is null");
151 | }
152 |
153 | @Test
154 | public void GIVEN_newDevice_WHEN_checkIfConnected_THEN_returnFalse() throws NetconfException {
155 | Device device = createTestDevice();
156 | assertFalse(device.isConnected());
157 | }
158 |
159 | @Test
160 | public void GIVEN_newDevice_WHEN_connect_THEN_sendHelloWithDefaultCapabilities() throws Exception {
161 |
162 | final JSch sshClient = givenConnectingSshClient();
163 |
164 | final Device device = Device.builder()
165 | .sshClient(sshClient)
166 | .hostName(TEST_HOSTNAME)
167 | .userName(TEST_USERNAME)
168 | .password(TEST_PASSWORD)
169 | .strictHostKeyChecking(false)
170 | .build();
171 | device.connect();
172 |
173 | final String message = outputStream.toString();
174 | assertThat(message).endsWith(NetconfConstants.DEVICE_PROMPT);
175 | final String hello = message.substring(0, message.length() - NetconfConstants.DEVICE_PROMPT.length());
176 | XmlAssert.assertThat(hello)
177 | .and(HELLO_WITH_DEFAULT_CAPABILITIES)
178 | .ignoreWhitespace()
179 | .areIdentical();
180 | }
181 |
182 | @Test
183 | public void GIVEN_newDevice_WHEN_connect_THEN_sendHelloWithCustomCapabilities() throws Exception {
184 |
185 | final JSch sshClient = givenConnectingSshClient();
186 |
187 | final Device device = Device.builder()
188 | .sshClient(sshClient)
189 | .netconfCapabilities(Collections.singletonList(NetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0))
190 | .hostName(TEST_HOSTNAME)
191 | .userName(TEST_USERNAME)
192 | .password(TEST_PASSWORD)
193 | .strictHostKeyChecking(false)
194 | .build();
195 | device.connect();
196 |
197 | final String message = outputStream.toString();
198 | assertThat(message).endsWith(NetconfConstants.DEVICE_PROMPT);
199 | final String hello = message.substring(0, message.length() - NetconfConstants.DEVICE_PROMPT.length());
200 | XmlAssert.assertThat(hello)
201 | .and(HELLO_WITH_BASE_CAPABILITIES)
202 | .ignoreWhitespace()
203 | .areIdentical();
204 | }
205 |
206 | private JSch givenConnectingSshClient() throws IOException, JSchException {
207 | final Session sshSession = mock(Session.class);
208 | when(sshSession.isConnected())
209 | .thenReturn(true);
210 | final ChannelSubsystem sshChannel = mock(ChannelSubsystem.class);
211 | when(sshChannel.getOutputStream())
212 | .thenReturn(outputStream);
213 | final ByteArrayInputStream is = new ByteArrayInputStream(
214 | (" " + NetconfConstants.DEVICE_PROMPT)
215 | .getBytes(StandardCharsets.UTF_8));
216 | when(sshChannel.getInputStream())
217 | .thenReturn(is);
218 | when(sshSession.openChannel(eq(SUBSYSTEM)))
219 | .thenReturn(sshChannel);
220 | final JSch sshClient = mock(JSch.class);
221 | when(sshClient.getSession(eq(TEST_USERNAME), eq(TEST_HOSTNAME), eq(DEFAULT_NETCONF_PORT)))
222 | .thenReturn(sshSession);
223 | return sshClient;
224 | }
225 | }
226 |
--------------------------------------------------------------------------------
/src/test/java/net/juniper/netconf/LoadExceptionTest.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf;
2 |
3 | import org.junit.Test;
4 | import org.junit.experimental.categories.Category;
5 | import static org.assertj.core.api.Assertions.assertThatThrownBy;
6 |
7 | @Category(Test.class)
8 | public class LoadExceptionTest {
9 |
10 | private static final String TEST_MESSAGE = "test message";
11 |
12 | private void throwLoadException() throws LoadException {
13 | throw new LoadException(TEST_MESSAGE);
14 | }
15 |
16 |
17 | @Test
18 | public void GIVEN_newLoadException_THEN_exceptionCreated() {
19 | assertThatThrownBy(this::throwLoadException)
20 | .isInstanceOf(LoadException.class)
21 | .hasMessage(TEST_MESSAGE);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/test/java/net/juniper/netconf/NetconfExceptionTest.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf;
2 |
3 | import org.junit.Test;
4 | import org.junit.experimental.categories.Category;
5 |
6 | import static org.assertj.core.api.Assertions.assertThatThrownBy;
7 |
8 | @Category(Test.class)
9 | public class NetconfExceptionTest {
10 | private static final String TEST_MESSAGE = "test message";
11 |
12 | private void throwNetconfException() throws NetconfException {
13 | throw new NetconfException(TEST_MESSAGE);
14 | }
15 |
16 | @Test
17 | public void GIVEN_newNetconfException_THEN_exceptionCreated() {
18 | assertThatThrownBy(this::throwNetconfException)
19 | .isInstanceOf(NetconfException.class)
20 | .hasMessage(TEST_MESSAGE);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/test/java/net/juniper/netconf/TestConstants.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf;
2 |
3 | public class TestConstants {
4 |
5 | public static final String CORRECT_HELLO = "\n" +
6 | "\n" +
7 | "urn:ietf:params:netconf:base:1.0 \n" +
8 | "urn:ietf:params:netconf:base:1.0#candidate \n" +
9 | "urn:ietf:params:netconf:base:1.0#confirmed-commit \n" +
10 | "urn:ietf:params:netconf:base:1.0#validate \n" +
11 | "urn:ietf:params:netconf:base:1.0#url?protocol=http,ftp,file \n" +
12 | " \n" +
13 | " ";
14 | public static final String LLDP_REQUEST = " ";
15 | }
16 |
--------------------------------------------------------------------------------
/src/test/java/net/juniper/netconf/TestHelper.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.net.URL;
6 |
7 | class TestHelper {
8 |
9 | static File getSampleFile(String fileName) throws FileNotFoundException {
10 | URL sampleFileUri = ClassLoader.getSystemClassLoader()
11 | .getResource(fileName);
12 | if (sampleFileUri == null) {
13 | throw new FileNotFoundException(String.format("Could not find file %s", fileName));
14 | }
15 | return new File(sampleFileUri.getFile());
16 | }
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/src/test/java/net/juniper/netconf/XMLTest.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf;
2 |
3 | import org.junit.Test;
4 |
5 | import javax.xml.parsers.DocumentBuilder;
6 | import javax.xml.parsers.DocumentBuilderFactory;
7 | import java.io.File;
8 | import java.util.Arrays;
9 | import java.util.Collections;
10 | import java.util.List;
11 |
12 | import static net.juniper.netconf.TestHelper.getSampleFile;
13 | import static org.assertj.core.api.Assertions.assertThat;
14 |
15 | public class XMLTest {
16 |
17 | private final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance() ;
18 |
19 | private void testFindValue(String sampleFileName, List findValueList, String expectedValue)
20 | throws Exception {
21 | DocumentBuilder builder = factory.newDocumentBuilder();
22 | File sampleRPCFile = getSampleFile(sampleFileName);
23 | XML testXml = new XML(builder.parse(sampleRPCFile).getDocumentElement());
24 |
25 | assertThat(testXml.findValue(findValueList)).isEqualTo(expectedValue);
26 | }
27 |
28 | @Test
29 | public void GIVEN_sampleXML_WHEN_findValueOfSample_THEN_returnValue() throws Exception {
30 | String sampleFileName = "sampleFPCTempRPCReply.xml";
31 | List findValueList = Arrays.asList(
32 | "environment-component-information",
33 | "environment-component-item",
34 | "name~Routing Engine 0",
35 | "temperature"
36 | );
37 | String expectedValue = "41 degrees C / 105 degrees F";
38 | testFindValue(sampleFileName,findValueList, expectedValue);
39 | }
40 |
41 | @Test
42 | public void GIVEN_sampleCliOutputRpc_WHEN_findValueOfSample_THEN_returnValue() throws Exception {
43 | String sampleFileName = "sampleCliOutputReply.xml";
44 | List findValueList = Collections.singletonList("output");
45 | String expectedValue = "operational-response";
46 | testFindValue(sampleFileName,findValueList, expectedValue);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/java/net/juniper/netconf/element/HelloTest.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf.element;
2 |
3 | import org.junit.Test;
4 | import org.xmlunit.assertj.XmlAssert;
5 |
6 | import static org.assertj.core.api.Assertions.assertThat;
7 |
8 | public class HelloTest {
9 |
10 | // Samples taken from https://www.juniper.net/documentation/us/en/software/junos/netconf/topics/concept/netconf-session-rfc-compliant.html
11 | public static final String HELLO_WITHOUT_NAMESPACE = ""
12 | + "\n"
13 | + " \n"
14 | + " urn:ietf:params:netconf:base:1.0 \n"
15 | + " urn:ietf:params:netconf:base:1.0#candidate \n"
16 | + " urn:ietf:params:netconf:base:1.0#confirmed-commit \n"
17 | + " urn:ietf:params:netconf:base:1.0#validate \n"
18 | + " urn:ietf:params:netconf:base:1.0#url?protocol=http,ftp,file \n"
19 | + " \n"
20 | + " 27700 \n"
21 | + " ";
22 |
23 | public static final String HELLO_WITH_NAMESPACE = "" +
24 | "\n"
25 | + " \n"
26 | + " urn:ietf:params:netconf:base:1.0 \n"
27 | + " urn:ietf:params:netconf:base:1.0#candidate \n"
28 | + " urn:ietf:params:netconf:base:1.0#confirmed-commit \n"
29 | + " urn:ietf:params:netconf:base:1.0#validate \n"
30 | + " urn:ietf:params:netconf:base:1.0#url?protocol=http,ftp,file \n"
31 | + " \n"
32 | + " 27703 \n"
33 | + " ";
34 |
35 | @Test
36 | public void willCreateAnObjectFromPacketWithoutNamespace() throws Exception {
37 |
38 | final Hello hello = Hello.from(HELLO_WITHOUT_NAMESPACE);
39 |
40 | assertThat(hello.getSessionId())
41 | .isEqualTo("27700");
42 | assertThat(hello.getCapabilities())
43 | .containsExactly(
44 | "urn:ietf:params:netconf:base:1.0",
45 | "urn:ietf:params:netconf:base:1.0#candidate",
46 | "urn:ietf:params:netconf:base:1.0#confirmed-commit",
47 | "urn:ietf:params:netconf:base:1.0#validate",
48 | "urn:ietf:params:netconf:base:1.0#url?protocol=http,ftp,file");
49 | assertThat(hello.hasCapability("urn:ietf:params:netconf:base:1.0#candidate"))
50 | .isTrue();
51 | }
52 |
53 | @Test
54 | public void willCreateAnObjectFromPacketWithNamespace() throws Exception {
55 |
56 | final Hello hello = Hello.from(HELLO_WITH_NAMESPACE);
57 |
58 | assertThat(hello.getSessionId())
59 | .isEqualTo("27703");
60 | assertThat(hello.getCapabilities())
61 | .containsExactly(
62 | "urn:ietf:params:netconf:base:1.0",
63 | "urn:ietf:params:netconf:base:1.0#candidate",
64 | "urn:ietf:params:netconf:base:1.0#confirmed-commit",
65 | "urn:ietf:params:netconf:base:1.0#validate",
66 | "urn:ietf:params:netconf:base:1.0#url?protocol=http,ftp,file");
67 | assertThat(hello.hasCapability("urn:ietf:params:netconf:base:1.0#candidate"))
68 | .isTrue();
69 | }
70 |
71 | @Test
72 | public void willCreateXmlFromAnObject() {
73 |
74 | final Hello hello = Hello.builder()
75 | .capability("urn:ietf:params:netconf:base:1.0")
76 | .capability("urn:ietf:params:netconf:base:1.0#candidate")
77 | .capability("urn:ietf:params:netconf:base:1.0#confirmed-commit")
78 | .capability("urn:ietf:params:netconf:base:1.0#validate")
79 | .capability("urn:ietf:params:netconf:base:1.0#url?protocol=http,ftp,file")
80 | .sessionId("27700")
81 | .build();
82 |
83 | XmlAssert.assertThat(hello.getXml())
84 | .and(HELLO_WITHOUT_NAMESPACE)
85 | .ignoreWhitespace()
86 | .areIdentical();
87 | }
88 |
89 | @Test
90 | public void willCreateXmlWithNamespaceFromAnObject() {
91 |
92 | final Hello hello = Hello.builder()
93 | .namespacePrefix("nc")
94 | .capability("urn:ietf:params:netconf:base:1.0")
95 | .capability("urn:ietf:params:netconf:base:1.0#candidate")
96 | .capability("urn:ietf:params:netconf:base:1.0#confirmed-commit")
97 | .capability("urn:ietf:params:netconf:base:1.0#validate")
98 | .capability("urn:ietf:params:netconf:base:1.0#url?protocol=http,ftp,file")
99 | .sessionId("27703")
100 | .build();
101 |
102 | XmlAssert.assertThat(hello.getXml())
103 | .and(HELLO_WITH_NAMESPACE)
104 | .ignoreWhitespace()
105 | .areIdentical();
106 | }
107 | }
--------------------------------------------------------------------------------
/src/test/java/net/juniper/netconf/element/RpcReplyLoadConfigResultsTest.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf.element;
2 |
3 | import org.junit.Test;
4 | import org.xmlunit.assertj.XmlAssert;
5 |
6 | import static org.assertj.core.api.Assertions.assertThat;
7 |
8 | public class RpcReplyLoadConfigResultsTest {
9 |
10 | private static final String LOAD_CONFIG_RESULTS_OK_NO_NAMESPACE = ""
11 | + "\n" +
14 | " \n" +
15 | " \n" +
16 | " \n" +
17 | " ";
18 |
19 | private static final String LOAD_CONFIG_RESULTS_OK_WITH_NAMESPACE = ""
20 | + "\n" +
23 | " \n" +
24 | " \n" +
25 | " \n" +
26 | " ";
27 |
28 | private static final String LOAD_CONFIG_RESULTS_ERROR_NO_NAMESPACE = ""
29 | + "\n" +
32 | " \n" +
33 | " \n" +
34 | " protocol \n" +
35 | " operation-failed \n" +
36 | " error \n" +
37 | " syntax error \n" +
38 | " \n" +
39 | " foobar \n" +
40 | " \n" +
41 | " \n" +
42 | " \n" +
43 | " \n" +
44 | " \n";
45 |
46 | private static final String LOAD_CONFIG_RESULTS_ERROR_WITH_NAMESPACE = ""
47 | + "\n" +
50 | " \n" +
51 | " \n" +
52 | " protocol \n" +
53 | " operation-failed \n" +
54 | " error \n" +
55 | " syntax error \n" +
56 | " \n" +
57 | " foobar \n" +
58 | " \n" +
59 | " \n" +
60 | " \n" +
61 | " \n" +
62 | " \n";
63 |
64 | @Test
65 | public void willParseAnOkResponseWithNoNamespacePrefix() throws Exception {
66 |
67 | final RpcReplyLoadConfigResults rpcReply = RpcReply.from(LOAD_CONFIG_RESULTS_OK_NO_NAMESPACE);
68 |
69 | assertThat(rpcReply.getMessageId())
70 | .isEqualTo("3");
71 | assertThat(rpcReply.getAction())
72 | .isEqualTo("set");
73 | assertThat(rpcReply.isOk())
74 | .isTrue();
75 | assertThat(rpcReply.hasErrorsOrWarnings())
76 | .isFalse();
77 | assertThat(rpcReply.hasErrors())
78 | .isFalse();
79 | assertThat(rpcReply.hasWarnings())
80 | .isFalse();
81 | assertThat(rpcReply.getErrors())
82 | .isEmpty();
83 |
84 | }
85 |
86 | @Test
87 | public void willParseAnOkResponseWithNamespacePrefix() throws Exception {
88 |
89 | final RpcReplyLoadConfigResults rpcReply = RpcReply.from(LOAD_CONFIG_RESULTS_OK_WITH_NAMESPACE);
90 |
91 | assertThat(rpcReply.getMessageId())
92 | .isEqualTo("4");
93 | assertThat(rpcReply.getAction())
94 | .isEqualTo("set");
95 | assertThat(rpcReply.isOk())
96 | .isTrue();
97 | assertThat(rpcReply.hasErrorsOrWarnings())
98 | .isFalse();
99 | assertThat(rpcReply.hasErrors())
100 | .isFalse();
101 | assertThat(rpcReply.hasWarnings())
102 | .isFalse();
103 | assertThat(rpcReply.getErrors())
104 | .isEmpty();
105 |
106 | }
107 |
108 | @Test
109 | public void willParseAnErrorResponseWithoutNamespacePrefix() throws Exception {
110 |
111 | final RpcReplyLoadConfigResults rpcReply = RpcReply.from(LOAD_CONFIG_RESULTS_ERROR_NO_NAMESPACE);
112 |
113 | assertThat(rpcReply.getMessageId())
114 | .isEqualTo("5");
115 | assertThat(rpcReply.getAction())
116 | .isEqualTo("set");
117 | assertThat(rpcReply.isOk())
118 | .isTrue();
119 | assertThat(rpcReply.hasErrorsOrWarnings())
120 | .isTrue();
121 | assertThat(rpcReply.hasErrors())
122 | .isTrue();
123 | assertThat(rpcReply.hasWarnings())
124 | .isFalse();
125 | assertThat(rpcReply.getErrors())
126 | .containsExactly(RpcError.builder()
127 | .errorType(RpcError.ErrorType.PROTOCOL)
128 | .errorTag(RpcError.ErrorTag.OPERATION_FAILED)
129 | .errorSeverity(RpcError.ErrorSeverity.ERROR)
130 | .errorMessage("syntax error")
131 | .errorInfo(RpcError.RpcErrorInfo.builder()
132 | .badElement("foobar")
133 | .build())
134 | .build());
135 | }
136 |
137 | @Test
138 | public void willParseAnErrorResponseWithNamespacePrefix() throws Exception {
139 |
140 | final RpcReplyLoadConfigResults rpcReply = RpcReply.from(LOAD_CONFIG_RESULTS_ERROR_WITH_NAMESPACE);
141 |
142 | assertThat(rpcReply.getMessageId())
143 | .isEqualTo("6");
144 | assertThat(rpcReply.getAction())
145 | .isEqualTo("set");
146 | assertThat(rpcReply.isOk())
147 | .isTrue();
148 | assertThat(rpcReply.hasErrorsOrWarnings())
149 | .isTrue();
150 | assertThat(rpcReply.hasErrors())
151 | .isTrue();
152 | assertThat(rpcReply.hasWarnings())
153 | .isFalse();
154 | assertThat(rpcReply.getErrors())
155 | .containsExactly(RpcError.builder()
156 | .errorType(RpcError.ErrorType.PROTOCOL)
157 | .errorTag(RpcError.ErrorTag.OPERATION_FAILED)
158 | .errorSeverity(RpcError.ErrorSeverity.ERROR)
159 | .errorMessage("syntax error")
160 | .errorInfo(RpcError.RpcErrorInfo.builder()
161 | .badElement("foobar")
162 | .build())
163 | .build());
164 | }
165 |
166 | @Test
167 | public void willCreateXmlOkWithoutNamespace() {
168 |
169 | final RpcReply rpcReply = RpcReplyLoadConfigResults.loadConfigResultsBuilder()
170 | .messageId("3")
171 | .action("set")
172 | .ok(true)
173 | .build();
174 |
175 | XmlAssert.assertThat(rpcReply.getXml())
176 | .and(LOAD_CONFIG_RESULTS_OK_NO_NAMESPACE)
177 | .ignoreWhitespace()
178 | .areIdentical();
179 | }
180 |
181 | @Test
182 | public void willCreateXmlOkWithNamespace() {
183 |
184 | final RpcReply rpcReply = RpcReplyLoadConfigResults.loadConfigResultsBuilder()
185 | .namespacePrefix("nc")
186 | .messageId("4")
187 | .action("set")
188 | .ok(true)
189 | .build();
190 |
191 | XmlAssert.assertThat(rpcReply.getXml())
192 | .and(LOAD_CONFIG_RESULTS_OK_WITH_NAMESPACE)
193 | .ignoreWhitespace()
194 | .areIdentical();
195 | }
196 |
197 | @Test
198 | public void willCreateXmlErrorWithoutNamespace() {
199 |
200 | final RpcReply rpcReply = RpcReplyLoadConfigResults.loadConfigResultsBuilder()
201 | .messageId("5")
202 | .action("set")
203 | .ok(true)
204 | .error(RpcError.builder()
205 | .errorType(RpcError.ErrorType.PROTOCOL)
206 | .errorTag(RpcError.ErrorTag.OPERATION_FAILED)
207 | .errorSeverity(RpcError.ErrorSeverity.ERROR)
208 | .errorMessage("syntax error")
209 | .errorInfo(RpcError.RpcErrorInfo.builder()
210 | .badElement("foobar")
211 | .build())
212 | .build())
213 | .build();
214 |
215 | XmlAssert.assertThat(rpcReply.getXml())
216 | .and(LOAD_CONFIG_RESULTS_ERROR_NO_NAMESPACE)
217 | .ignoreWhitespace()
218 | .areIdentical();
219 | }
220 |
221 | @Test
222 | public void willCreateXmlErrorWithNamespace() {
223 |
224 | final RpcReply rpcReply = RpcReplyLoadConfigResults.loadConfigResultsBuilder()
225 | .namespacePrefix("nc")
226 | .messageId("6")
227 | .action("set")
228 | .ok(true)
229 | .error(RpcError.builder()
230 | .errorType(RpcError.ErrorType.PROTOCOL)
231 | .errorTag(RpcError.ErrorTag.OPERATION_FAILED)
232 | .errorSeverity(RpcError.ErrorSeverity.ERROR)
233 | .errorMessage("syntax error")
234 | .errorInfo(RpcError.RpcErrorInfo.builder()
235 | .badElement("foobar")
236 | .build())
237 | .build())
238 | .build();
239 |
240 | XmlAssert.assertThat(rpcReply.getXml())
241 | .and(LOAD_CONFIG_RESULTS_ERROR_WITH_NAMESPACE)
242 | .ignoreWhitespace()
243 | .areIdentical();
244 | }
245 |
246 | }
--------------------------------------------------------------------------------
/src/test/java/net/juniper/netconf/element/RpcReplyTest.java:
--------------------------------------------------------------------------------
1 | package net.juniper.netconf.element;
2 |
3 | import org.junit.Test;
4 | import org.xmlunit.assertj.XmlAssert;
5 |
6 | import java.util.Arrays;
7 |
8 | import static org.assertj.core.api.Assertions.assertThat;
9 |
10 | public class RpcReplyTest {
11 |
12 | private static final String RPC_REPLY_WITHOUT_NAMESPACE = "" +
13 | " ";
16 | private static final String RPC_REPLY_WITH_NAMESPACE = "" +
17 | " ";
20 | private static final String RPC_REPLY_WITH_OK = "" +
21 | "\n" +
23 | " \n" +
24 | " ";
25 | // Example from https://datatracker.ietf.org/doc/html/rfc6241#section-4.3
26 | private static final String RPC_REPLY_WITH_ERRORS = "" +
27 | "\n" +
29 | " \n" +
30 | " application \n" +
31 | " invalid-value \n" +
32 | " error \n" +
33 | " /t:top/t:interface[t:name=\"Ethernet0/0\"]/t:mtu \n" +
34 | " MTU value 25000 is not within range 256..9192 \n" +
35 | " \n" +
36 | " \n" +
37 | " application \n" +
38 | " invalid-value \n" +
39 | " error \n" +
40 | " /t:top/t:interface[t:name=\"Ethernet1/0\"]/t:address/t:name \n" +
41 | " Invalid IP address for interface Ethernet1/0 \n" +
42 | " \n" +
43 | " ";
44 |
45 | @Test
46 | public void willParseRpcReplyWithoutNamespace() throws Exception {
47 | final RpcReply rpcReply = RpcReply.from(RPC_REPLY_WITHOUT_NAMESPACE);
48 |
49 | assertThat(rpcReply.getMessageId())
50 | .isEqualTo("3");
51 | assertThat(rpcReply.isOk())
52 | .isFalse();
53 | assertThat(rpcReply.hasErrorsOrWarnings())
54 | .isFalse();
55 | assertThat(rpcReply.hasErrors())
56 | .isFalse();
57 | assertThat(rpcReply.hasWarnings())
58 | .isFalse();
59 | }
60 |
61 | @Test
62 | public void willParseRpcReplyWithNamespace() throws Exception {
63 | final RpcReply rpcReply = RpcReply.from(RPC_REPLY_WITH_NAMESPACE);
64 |
65 | assertThat(rpcReply.getMessageId())
66 | .isEqualTo("4");
67 | assertThat(rpcReply.isOk())
68 | .isFalse();
69 | assertThat(rpcReply.hasErrorsOrWarnings())
70 | .isFalse();
71 | assertThat(rpcReply.hasErrors())
72 | .isFalse();
73 | assertThat(rpcReply.hasWarnings())
74 | .isFalse();
75 | }
76 |
77 | @Test
78 | public void willCreateOkRpcReply() throws Exception {
79 | final RpcReply rpcReply = RpcReply.from(RPC_REPLY_WITH_OK);
80 |
81 | assertThat(rpcReply.getMessageId())
82 | .isEqualTo("5");
83 | assertThat(rpcReply.isOk())
84 | .isTrue();
85 | assertThat(rpcReply.hasErrorsOrWarnings())
86 | .isFalse();
87 | assertThat(rpcReply.hasErrors())
88 | .isFalse();
89 | assertThat(rpcReply.hasWarnings())
90 | .isFalse();
91 | }
92 |
93 | @Test
94 | public void willParseRpcReplyWithErrors() throws Exception {
95 | final RpcReply rpcReply = RpcReply.from(RPC_REPLY_WITH_ERRORS);
96 |
97 | assertThat(rpcReply.getMessageId())
98 | .isEqualTo("101");
99 | assertThat(rpcReply.isOk())
100 | .isFalse();
101 | assertThat(rpcReply.hasErrorsOrWarnings())
102 | .isTrue();
103 | assertThat(rpcReply.hasErrors())
104 | .isTrue();
105 | assertThat(rpcReply.hasWarnings())
106 | .isFalse();
107 | assertThat(rpcReply.getErrors())
108 | .isEqualTo(Arrays.asList(
109 | RpcError.builder()
110 | .errorType(RpcError.ErrorType.APPLICATION)
111 | .errorTag(RpcError.ErrorTag.INVALID_VALUE)
112 | .errorSeverity(RpcError.ErrorSeverity.ERROR)
113 | .errorPath("/t:top/t:interface[t:name=\"Ethernet0/0\"]/t:mtu")
114 | .errorMessage("MTU value 25000 is not within range 256..9192")
115 | .errorMessageLanguage("en")
116 | .build(),
117 | RpcError.builder()
118 | .errorType(RpcError.ErrorType.APPLICATION)
119 | .errorTag(RpcError.ErrorTag.INVALID_VALUE)
120 | .errorSeverity(RpcError.ErrorSeverity.ERROR)
121 | .errorPath("/t:top/t:interface[t:name=\"Ethernet1/0\"]/t:address/t:name")
122 | .errorMessage("Invalid IP address for interface Ethernet1/0")
123 | .build()));
124 | }
125 |
126 | @Test
127 | public void willCreateXmlFromAnObject() {
128 |
129 | final RpcReply rpcReply = RpcReply.builder()
130 | .messageId("3")
131 | .build();
132 |
133 | XmlAssert.assertThat(rpcReply.getXml())
134 | .and(RPC_REPLY_WITHOUT_NAMESPACE)
135 | .ignoreWhitespace()
136 | .areIdentical();
137 | }
138 |
139 | @Test
140 | public void willCreateXmlWithNamespaceFromAnObject() {
141 | final RpcReply rpcReply = RpcReply.builder()
142 | .namespacePrefix("nc")
143 | .messageId("4")
144 | .build();
145 |
146 | XmlAssert.assertThat(rpcReply.getXml())
147 | .and(RPC_REPLY_WITH_NAMESPACE)
148 | .ignoreWhitespace()
149 | .areIdentical();
150 | }
151 |
152 | @Test
153 | public void willCreateXmlWithOkFromAnObject() {
154 |
155 | final RpcReply rpcReply = RpcReply.builder()
156 | .namespacePrefix("nc")
157 | .messageId("5")
158 | .ok(true)
159 | .build();
160 |
161 | XmlAssert.assertThat(rpcReply.getXml())
162 | .and(RPC_REPLY_WITH_OK)
163 | .ignoreWhitespace()
164 | .areIdentical();
165 | }
166 |
167 | @Test
168 | public void willCreateXmlWithErrors() {
169 | final RpcReply rpcReply = RpcReply.builder()
170 | .messageId("101")
171 | .error(RpcError.builder()
172 | .errorType(RpcError.ErrorType.APPLICATION)
173 | .errorTag(RpcError.ErrorTag.INVALID_VALUE)
174 | .errorSeverity(RpcError.ErrorSeverity.ERROR)
175 | .errorPath("/t:top/t:interface[t:name=\"Ethernet0/0\"]/t:mtu")
176 | .errorMessage("MTU value 25000 is not within range 256..9192")
177 | .errorMessageLanguage("en")
178 | .build())
179 | .error(RpcError.builder()
180 | .errorType(RpcError.ErrorType.APPLICATION)
181 | .errorTag(RpcError.ErrorTag.INVALID_VALUE)
182 | .errorSeverity(RpcError.ErrorSeverity.ERROR)
183 | .errorPath("/t:top/t:interface[t:name=\"Ethernet1/0\"]/t:address/t:name")
184 | .errorMessage("Invalid IP address for interface Ethernet1/0")
185 | .build())
186 | .build();
187 |
188 | XmlAssert.assertThat(rpcReply.getXml())
189 | .and(RPC_REPLY_WITH_ERRORS)
190 | .ignoreWhitespace()
191 | .areIdentical();
192 | }
193 | }
--------------------------------------------------------------------------------
/src/test/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | # Root logger option
2 | log4j.rootLogger=DEBUG, file, stdout
3 |
4 | # Direct log messages to a log file
5 | log4j.appender.file=org.apache.log4j.RollingFileAppender
6 | log4j.appender.file.File=log-test/netconf-java.log
7 | log4j.appender.file.MaxFileSize=100MB
8 | log4j.appender.file.MaxBackupIndex=10
9 | log4j.appender.file.layout=org.apache.log4j.PatternLayout
10 | log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
11 |
12 | # Direct log messages to stdout
13 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
14 | log4j.appender.stdout.Target=System.out
15 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
16 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
--------------------------------------------------------------------------------
/src/test/resources/responses/lldpResponse.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | xe-0/0/9:1
5 | ae51
6 | Mac address
7 | 00:00:00:80:1e:00
8 | ethernet 6/1
9 | test.system.new
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/test/resources/sampleCliOutputReply.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | operational-response
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/test/resources/sampleFPCTempRPCReply.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Routing Engine 0
5 |
6 | 41 degrees C / 105 degrees F
7 |
8 |
9 |
10 | Routing Engine 1
11 |
12 | 37 degrees C / 98 degrees F
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------