Merge "Add Enqueue validation check in FlowConfig"
[controller.git] / opendaylight / netconf / config-persister-impl / src / test / java / org / opendaylight / controller / netconf / persist / impl / osgi / MockNetconfEndpoint.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.netconf.persist.impl.osgi;
9
10 import java.io.BufferedReader;
11 import java.io.IOException;
12 import java.io.InputStreamReader;
13 import java.io.PrintWriter;
14 import java.net.ServerSocket;
15 import java.net.Socket;
16 import java.net.SocketTimeoutException;
17 import java.util.Collection;
18 import java.util.List;
19 import java.util.concurrent.atomic.AtomicBoolean;
20
21 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
22 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
23
24 import com.google.common.collect.Lists;
25
26 class MockNetconfEndpoint implements AutoCloseable {
27
28     public static final int READ_SOCKET_TIMEOUT = 3000;
29
30     public static final String MSG_SEPARATOR = "]]>]]>\n";
31
32     private final AtomicBoolean stopped = new AtomicBoolean(false);
33     private List<String> receivedMessages = Lists.newCopyOnWriteArrayList();
34     private Thread innerThread;
35
36     MockNetconfEndpoint(String capability, String netconfPort, List<MessageSequence> messageSequence) {
37         helloMessage = helloMessage.replace("capability_place_holder", capability);
38         start(netconfPort, messageSequence);
39     }
40
41     private String helloMessage = "<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
42             "<capabilities>\n" +
43             "<capability>capability_place_holder</capability>\n" +
44             "</capabilities>\n" +
45             "<session-id>1</session-id>\n" +
46             "</hello>\n" +
47             MSG_SEPARATOR;
48
49     public static String conflictingVersionErrorMessage;
50     static {
51         try {
52             conflictingVersionErrorMessage = XmlUtil.toString(XmlFileLoader
53                     .xmlFileToDocument("netconfMessages/conflictingversion/conflictingVersionResponse.xml")) + MSG_SEPARATOR;
54         } catch (Exception e) {
55             throw new RuntimeException(e);
56         }
57     }
58
59     public static String okMessage = "<rpc-reply message-id=\"1\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
60             "<ok/>\n" +
61             "</rpc-reply>" +
62             MSG_SEPARATOR ;
63
64     private void start(final String port, final List<MessageSequence> messagesToSend) {
65         innerThread = new Thread(new Runnable() {
66             @Override
67             public void run() {
68                 int clientCounter = 0;
69
70                 while (stopped.get() == false) {
71                     try (ServerSocket s = new ServerSocket(Integer.valueOf(port))) {
72                         s.setSoTimeout(READ_SOCKET_TIMEOUT);
73
74                         Socket clientSocket = s.accept();
75                         clientCounter++;
76                         clientSocket.setSoTimeout(READ_SOCKET_TIMEOUT);
77
78                         PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
79                         BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
80
81                         // Negotiate
82                         sendMessage(out, helloMessage);
83                         receiveMessage(in);
84
85                         // Accept next message (edit-config)
86                         receiveMessage(in);
87
88                         for (String message : getMessageSequenceForClient(messagesToSend, clientCounter)) {
89                             sendMessage(out, message);
90                             receiveMessage(in);
91                         }
92                     } catch (SocketTimeoutException e) {
93                         // No more activity on netconf endpoint, close
94                         return;
95                     } catch (Exception e) {
96                         throw new RuntimeException(e);
97                     }
98                 }
99             }
100
101             private Iterable<? extends String> getMessageSequenceForClient(List<MessageSequence> messagesToSend,
102                     int clientCounter) {
103                 if (messagesToSend.size() <= clientCounter) {
104                     return messagesToSend.get(messagesToSend.size() - 1).getMessages();
105                 } else {
106                     return messagesToSend.get(clientCounter - 1).getMessages();
107                 }
108             }
109
110             private void receiveMessage(BufferedReader in) throws Exception {
111                 String message = readMessage(in);
112                 if(message == null || message.equals(""))
113                     return;
114                 receivedMessages.add(message);
115             }
116
117             private String readMessage(BufferedReader in) throws IOException {
118                 int c;
119                 StringBuilder b = new StringBuilder();
120
121                 while((c = in.read()) != -1) {
122                     b.append((char)c);
123                     if(b.toString().endsWith("]]>]]>"))
124                         break;
125                 }
126
127                 return b.toString();
128             }
129
130             private void sendMessage(PrintWriter out, String message) throws InterruptedException {
131                 out.print(message);
132                 out.flush();
133             }
134
135         });
136         innerThread.setName("Mocked-netconf-endpoint-inner-thread");
137         innerThread.start();
138     }
139
140     public List<String> getReceivedMessages() {
141         return receivedMessages;
142     }
143
144     public void close() throws IOException, InterruptedException {
145         stopped.set(true);
146         innerThread.join();
147     }
148
149     static class MessageSequence {
150         private List<String> messages;
151
152         MessageSequence(List<String> messages) {
153             this.messages = messages;
154         }
155
156         MessageSequence(String... messages) {
157             this(Lists.newArrayList(messages));
158         }
159
160         public Collection<String> getMessages() {
161             return messages;
162         }
163     }
164 }