2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.protocol.pcep.impl;
10 import java.util.HashMap;
11 import java.util.List;
13 import org.opendaylight.protocol.framework.DeserializerException;
14 import org.opendaylight.protocol.framework.DocumentedException;
15 import org.opendaylight.protocol.framework.ProtocolMessageFactory;
16 import org.opendaylight.protocol.pcep.PCEPDeserializerException;
17 import org.opendaylight.protocol.pcep.PCEPDocumentedException;
18 import org.opendaylight.protocol.pcep.PCEPErrors;
19 import org.opendaylight.protocol.pcep.spi.PCEPMessageType;
20 import org.opendaylight.protocol.util.ByteArray;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
25 import com.google.common.base.Preconditions;
26 import com.google.common.collect.Lists;
27 import com.google.common.primitives.UnsignedBytes;
30 * Factory for subclasses of {@link Message}
32 class RawPCEPMessageFactory implements ProtocolMessageFactory<Message> {
34 private final static Logger logger = LoggerFactory.getLogger(PCEPMessageFactory.class);
36 private final static int TYPE_SIZE = 1; // bytes
38 private final static int LENGTH_SIZE = 2; // bytes
40 public final static int COMMON_HEADER_LENGTH = 4; // bytes
43 * Current supported version of PCEP.
45 public static final int PCEP_VERSION = 1;
47 private static class MapOfParsers extends HashMap<PCEPMessageType, PCEPMessageParser> {
49 private static final long serialVersionUID = -5715193806554448822L;
51 private final static MapOfParsers instance = new MapOfParsers();
53 private MapOfParsers() {
57 private void fillInMap() {
58 // this.put(PCEPMessageType.OPEN, new PCEPOpenMessageParser());
59 // this.put(PCEPMessageType.KEEPALIVE, new PCEPKeepAliveMessageParser());
60 // this.put(PCEPMessageType.NOTIFICATION, new PCEPNotificationMessageParser());
61 // this.put(PCEPMessageType.ERROR, new PCEPErrorMessageParser());
62 // this.put(PCEPMessageType.RESPONSE, new PCEPReplyMessageParser());
63 // this.put(PCEPMessageType.REQUEST, new PCEPRequestMessageParser());
64 // this.put(PCEPMessageType.UPDATE_REQUEST, new PCEPUpdateRequestMessageParser());
65 // this.put(PCEPMessageType.STATUS_REPORT, new PCEPReportMessageParser());
66 // this.put(PCEPMessageType.CLOSE, new PCEPCloseMessageParser());
67 // this.put(PCEPMessageType.PCCREATE, new PCCreateMessageParser());
70 public static MapOfParsers getInstance() {
77 * @param bytes assume array of bytes without common header
78 * @return Parsed specific PCEPMessage
79 * @throws PCEPDeserializerException
80 * @throws PCEPDocumentedException
84 public List<Message> parse(final byte[] bytes) throws DeserializerException, DocumentedException {
85 Preconditions.checkArgument(bytes != null, "Bytes may not be null");
86 Preconditions.checkArgument(bytes.length != 0, "Bytes may not be empty");
88 logger.trace("Attempt to parse message from bytes: {}", ByteArray.bytesToHexString(bytes));
90 final int type = UnsignedBytes.toInt(bytes[1]);
92 final int msgLength = ByteArray.bytesToInt(ByteArray.subByte(bytes, TYPE_SIZE + 1, LENGTH_SIZE));
94 final byte[] msgBody = ByteArray.cutBytes(bytes, TYPE_SIZE + 1 + LENGTH_SIZE);
96 if (msgBody.length != msgLength - COMMON_HEADER_LENGTH) {
97 throw new DeserializerException("Body size " + msgBody.length + " does not match header size "
98 + (msgLength - COMMON_HEADER_LENGTH));
102 * if PCEPObjectIdentifier.getObjectClassFromInt() dont't throws
103 * exception and if returned null we know the error type
105 final PCEPMessageType msgType = PCEPMessageType.getFromInt(type);
106 if (msgType == null) {
107 logger.debug("Unknown message type {}", type);
108 throw new DocumentedException("Unhandled message type " + type, new PCEPDocumentedException("Unhandled message type " + type, PCEPErrors.CAPABILITY_NOT_SUPPORTED));
111 final Message msg = null;
113 // msg = new RawMessage(PCEPObjectFactory.parseObjects(msgBody), msgType);
114 // } catch (final PCEPDeserializerException e) {
115 // logger.debug("Unexpected deserializer problem", e);
116 // throw new DeserializerException(e.getMessage(), e);
117 // } catch (final PCEPDocumentedException e) {
118 // logger.debug("Documented deserializer problem", e);
119 // throw new DocumentedException(e.getMessage(), e);
121 logger.debug("Message was parsed. {}", msg);
122 return Lists.newArrayList(msg);
126 public byte[] put(final Message msg) {
128 throw new IllegalArgumentException("PCEPMessage is mandatory.");
131 final PCEPMessageType msgType = null;
133 // if (msg instanceof PCEPOpenMessage) {
134 // msgType = PCEPMessageType.OPEN;
135 // } else if (msg instanceof KeepaliveMessage) {
136 // msgType = PCEPMessageType.KEEPALIVE;
137 // } else if (msg instanceof CloseMessage) {
138 // msgType = PCEPMessageType.CLOSE;
139 // } else if (msg instanceof PCEPReplyMessage) {
140 // msgType = PCEPMessageType.RESPONSE;
141 // } else if (msg instanceof PCEPRequestMessage) {
142 // msgType = PCEPMessageType.REQUEST;
143 // } else if (msg instanceof PCEPNotificationMessage) {
144 // msgType = PCEPMessageType.NOTIFICATION;
145 // } else if (msg instanceof PCEPErrorMessage) {
146 // msgType = PCEPMessageType.ERROR;
147 // } else if (msg instanceof PCEPReportMessage) {
148 // msgType = PCEPMessageType.STATUS_REPORT;
149 // } else if (msg instanceof PCEPUpdateRequestMessage) {
150 // msgType = PCEPMessageType.UPDATE_REQUEST;
151 // } else if (msg instanceof PCCreateMessage) {
152 // msgType = PCEPMessageType.PCCREATE;
154 // logger.error("Unknown instance of PCEPMessage. Message class: {}", msg.getClass());
155 // throw new IllegalArgumentException("Unknown instance of PCEPMessage. Passed " + msg.getClass());
158 logger.trace("Serializing {}", msgType);
160 final byte[] msgBody = MapOfParsers.getInstance().get(msgType).put(msg);
162 final PCEPMessageHeader msgHeader = new PCEPMessageHeader(msgType.getIdentifier(), msgBody.length
163 + PCEPMessageHeader.COMMON_HEADER_LENGTH, PCEP_VERSION);
165 final byte[] headerBytes = msgHeader.toBytes();
166 final byte[] retBytes = new byte[headerBytes.length + msgBody.length];
168 ByteArray.copyWhole(headerBytes, retBytes, 0);
169 ByteArray.copyWhole(msgBody, retBytes, PCEPMessageHeader.COMMON_HEADER_LENGTH);