Open resources as stream in test
[bgpcep.git] / bgp / util / src / main / java / org / opendaylight / protocol / bgp / util / HexDumpBGPFileParser.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.protocol.bgp.util;
9
10 import java.io.File;
11 import java.io.FileInputStream;
12 import java.io.FileNotFoundException;
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.io.InputStreamReader;
16 import java.util.List;
17
18 import javax.annotation.concurrent.Immutable;
19
20 import org.apache.commons.codec.DecoderException;
21 import org.apache.commons.codec.binary.Hex;
22 import org.opendaylight.protocol.util.ByteArray;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 import com.google.common.annotations.VisibleForTesting;
27 import com.google.common.base.Preconditions;
28 import com.google.common.base.Strings;
29 import com.google.common.collect.Lists;
30 import com.google.common.io.CharStreams;
31
32 /**
33  * Read text file, parse BGP messages. File can contain comments or other data. BGP messages are detected using 16 ff marker.
34  * New lines and spaces are ignored. Use {@link ByteArray#bytesToHexString(byte[])} for serializing bytes to this format.
35  */
36 @Immutable
37 public class HexDumpBGPFileParser {
38         private static final int MINIMAL_LENGTH = 19;
39         private static final Logger LOG = LoggerFactory.getLogger(HexDumpBGPFileParser.class);
40         private static final String ff_16 = Strings.repeat("FF", 16);
41
42         public static List<byte[]> parseMessages(final File file) throws FileNotFoundException, IOException {
43                 Preconditions.checkArgument(file != null, "Filename cannot be null");
44                 return parseMessages(new FileInputStream(file));
45         }
46
47         public static List<byte[]> parseMessages(final InputStream is) throws IOException {
48                 Preconditions.checkNotNull(is);
49                 try (InputStreamReader isr = new InputStreamReader(is)) {
50                         return parseMessages(CharStreams.toString(isr));
51                 } finally {
52                         is.close();
53                 }
54         }
55
56         public static List<byte[]> parseMessages(String content) {
57                 content = clearWhiteSpace_toUpper(content);
58                 // search for 16 FFs
59
60                 List<byte[]> messages = Lists.newLinkedList();
61                 int idx = 0;
62                 while ((idx = content.indexOf(ff_16, idx)) > -1) {
63                         // next 2 bytes are length
64                         int lengthIdx = idx + 16 * 2;
65                         int messageIdx = lengthIdx + 4;
66                         String hexLength = content.substring(lengthIdx, messageIdx);
67                         byte[] byteLength = null;
68                         try {
69                                 byteLength = Hex.decodeHex(hexLength.toCharArray());
70                         } catch (DecoderException e) {
71                                 throw new RuntimeException(e);
72                         }
73                         int length = ByteArray.bytesToInt(byteLength);
74                         int messageEndIdx = idx + length * 2;
75
76                         // Assert that message is longer than minimum 19(header.length == 19)
77                         // If length in BGP message would be 0, loop would never end
78                         Preconditions.checkArgument(length >=  MINIMAL_LENGTH,
79                                         "Invalid message at index " + idx
80                                         + ", length atribute is lower than " + MINIMAL_LENGTH);
81
82                         String hexMessage = content.substring(idx, messageEndIdx);
83                         byte[] message = null;
84                         try {
85                                 message = Hex.decodeHex(hexMessage.toCharArray());
86                         } catch (DecoderException e) {
87                                 new RuntimeException(e);
88                         }
89                         messages.add(message);
90                         idx = messageEndIdx;
91                 }
92                 LOG.info("Succesfully extracted " + messages.size() + " messages");
93                 return messages;
94         }
95
96         @VisibleForTesting
97         static String clearWhiteSpace_toUpper(final String line){
98                 return line.replaceAll("\\s", "").toUpperCase();
99         }
100
101 }