blob: 1c5bf6336a16c8d74d7e6e1aaf26605017d1c19f [file] [log] [blame]
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.pcepio.protocol.ver1;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepError;
import org.onosproject.pcepio.protocol.PcepErrorObject;
import org.onosproject.pcepio.protocol.PcepRPObject;
import org.onosproject.pcepio.protocol.PcepLSObject;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.MoreObjects;
/**
* Provides PcepError list which contains RP or LS objects.
* Reference: draft-dhodylee-pce-pcep-ls-01, section 8.2.
*/
public class PcepErrorVer1 implements PcepError {
/*
<error>::=[<request-id-list> | <ls-id-list>]
<error-obj-list>
<request-id-list>::=<RP>[<request-id-list>]
<ls-id-list>::=<LS>[<ls-id-list>]
*/
protected static final Logger log = LoggerFactory.getLogger(PcepErrorVer1.class);
private boolean isErroInfoSet;
//PcepErrorObject list
private List<PcepErrorObject> errObjList;
//PcepRPObject list
private List<PcepRPObject> rpObjList;
//PcepLSObject list
private List<PcepLSObject> lsObjList;
private boolean isLSObjListSet;
public static final int OBJECT_HEADER_LENGTH = 4;
/**
* Constructor to initialize variable.
*/
public PcepErrorVer1() {
this.rpObjList = null;
this.lsObjList = null;
this.errObjList = null;
}
/**
* Constructor to initialize variable.
*
* @param rpObjList list of PcepRPObject
* @param lsObjList list of PcepLSObject
* @param errObjListObjList list of PcepErrorObject
*/
public PcepErrorVer1(List<PcepRPObject> rpObjList, List<PcepLSObject> lsObjList,
List<PcepErrorObject> errObjListObjList) {
this.rpObjList = rpObjList;
this.lsObjList = lsObjList;
this.errObjList = errObjListObjList;
}
/**
* Constructor to initialize PcepError.
*
* @param errObjList list of PcepErrorObject
*/
public PcepErrorVer1(List<PcepErrorObject> errObjList) {
this.rpObjList = null;
this.lsObjList = null;
this.errObjList = errObjList;
}
@Override
public List<PcepRPObject> getRPObjList() {
return this.rpObjList;
}
@Override
public List<PcepLSObject> getLSObjList() {
return this.lsObjList;
}
@Override
public List<PcepErrorObject> getErrorObjList() {
return this.errObjList;
}
/**
* Parse RP List from the channel buffer.
*
* @param cb of type channel buffer
* @throws PcepParseException if mandatory fields are missing
*/
public void parseRPList(ChannelBuffer cb) throws PcepParseException {
byte yObjClass;
byte yObjType;
rpObjList = new LinkedList<>();
// caller should verify for RP object
if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
log.debug("Unable to find RP Object");
return;
}
cb.markReaderIndex();
PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
cb.resetReaderIndex();
yObjClass = tempObjHeader.getObjClass();
yObjType = tempObjHeader.getObjType();
PcepRPObject rpObj;
while ((yObjClass == PcepRPObjectVer1.RP_OBJ_CLASS) && (yObjType == PcepRPObjectVer1.RP_OBJ_TYPE)) {
rpObj = PcepRPObjectVer1.read(cb);
rpObjList.add(rpObj);
if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
cb.markReaderIndex();
tempObjHeader = PcepObjectHeader.read(cb);
cb.resetReaderIndex();
yObjClass = tempObjHeader.getObjClass();
yObjType = tempObjHeader.getObjType();
} else {
break;
}
}
}
/**
* Parse LS List from the channel buffer.
*
* @param cb of type channel buffer
* @throws PcepParseException if mandatory fields are missing
*/
public void parseLSList(ChannelBuffer cb) throws PcepParseException {
byte yObjClass;
byte yObjType;
lsObjList = new LinkedList<>();
// caller should verify for LS object
if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
log.debug("Unable to find LS Object");
return;
}
cb.markReaderIndex();
PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
cb.resetReaderIndex();
yObjClass = tempObjHeader.getObjClass();
yObjType = tempObjHeader.getObjType();
PcepLSObject lsObj;
while ((yObjClass == PcepLSObjectVer1.LS_OBJ_CLASS) && ((yObjType == PcepLSObjectVer1.LS_OBJ_TYPE_NODE_VALUE)
|| (yObjType == PcepLSObjectVer1.LS_OBJ_TYPE_LINK_VALUE))) {
lsObj = PcepLSObjectVer1.read(cb);
lsObjList.add(lsObj);
if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
cb.markReaderIndex();
tempObjHeader = PcepObjectHeader.read(cb);
cb.resetReaderIndex();
yObjClass = tempObjHeader.getObjClass();
yObjType = tempObjHeader.getObjType();
} else {
break;
}
}
}
/**
* parseErrObjList from the channel buffer.
*
* @param cb of type channel buffer
* @throws PcepParseException if mandatory fields are missing
*/
public void parseErrObjList(ChannelBuffer cb) throws PcepParseException {
byte yObjClass;
byte yObjType;
boolean bIsErrorObjFound = false;
errObjList = new LinkedList<>();
// caller should verify for RP object
if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
throw new PcepParseException("Unable to find PCEP-ERROR Object");
}
cb.markReaderIndex();
PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
cb.resetReaderIndex();
yObjClass = tempObjHeader.getObjClass();
yObjType = tempObjHeader.getObjType();
PcepErrorObject errorObject;
while ((yObjClass == PcepErrorObjectVer1.ERROR_OBJ_CLASS) && (yObjType == PcepErrorObjectVer1.ERROR_OBJ_TYPE)) {
errorObject = PcepErrorObjectVer1.read(cb);
errObjList.add(errorObject);
bIsErrorObjFound = true;
if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
cb.markReaderIndex();
tempObjHeader = PcepObjectHeader.read(cb);
cb.resetReaderIndex();
yObjClass = tempObjHeader.getObjClass();
yObjType = tempObjHeader.getObjType();
} else {
break;
}
}
if (!bIsErrorObjFound) {
throw new PcepParseException("At least one PCEP-ERROR Object should be present.");
}
}
/**
* Reads the byte stream of PcepError from channel buffer.
*
* @param cb of type channel buffer
* @return PcepError error part of PCEP-ERROR
* @throws PcepParseException if mandatory fields are missing
*/
public static PcepErrorVer1 read(ChannelBuffer cb) throws PcepParseException {
if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
throw new PcepParseException("Unknown Object");
}
PcepErrorVer1 pcepError = new PcepErrorVer1();
// check whether any PCEP Error Info is present
cb.markReaderIndex();
PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
cb.resetReaderIndex();
byte yObjClass = tempObjHeader.getObjClass();
//If RPlist present then store it.RPList and LSList are optional
if (yObjClass == PcepRPObjectVer1.RP_OBJ_CLASS) {
log.debug("RP_LIST");
pcepError.parseRPList(cb);
yObjClass = checkNextObject(cb);
} else if (yObjClass == PcepLSObjectVer1.LS_OBJ_CLASS) {
log.debug("LS_LIST");
pcepError.parseLSList(cb);
yObjClass = checkNextObject(cb);
}
if (yObjClass == PcepErrorObjectVer1.ERROR_OBJ_CLASS) {
log.debug("PCEP-ERROR obj list");
pcepError.parseErrObjList(cb);
yObjClass = checkNextObject(cb);
}
return pcepError;
}
/**
* Checks Next Object.
*
* @param cb of type channel buffer.
* @return object type class.
*/
private static byte checkNextObject(ChannelBuffer cb) {
if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
return 0;
}
cb.markReaderIndex();
PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
cb.resetReaderIndex();
return tempObjHeader.getObjClass();
}
/**
* Writes the byte stream of PCEP error to the channel buffer.
*
* @param cb of type channel buffer
* @return object length index
* @throws PcepParseException if mandatory fields are missing
*/
@Override
public int write(ChannelBuffer cb) throws PcepParseException {
int iLenStartIndex = cb.writerIndex();
// RPlist is optional
if (this.isErroInfoSet) {
ListIterator<PcepRPObject> rpObjlistIterator = this.rpObjList.listIterator();
while (rpObjlistIterator.hasNext()) {
rpObjlistIterator.next().write(cb);
}
}
// LSlist is optional
if (this.isLSObjListSet) {
ListIterator<PcepLSObject> teObjlistIterator = this.lsObjList.listIterator();
while (teObjlistIterator.hasNext()) {
teObjlistIterator.next().write(cb);
}
}
//ErrList is mandatory
ListIterator<PcepErrorObject> errlistIterator = this.errObjList.listIterator();
while (errlistIterator.hasNext()) {
errlistIterator.next().write(cb);
}
return cb.writerIndex() - iLenStartIndex;
}
/**
* Builder for error part of PCEP-ERROR.
*/
public static class Builder implements PcepError.Builder {
private List<PcepRPObject> rpObjList;
private List<PcepLSObject> lsObjList;
private List<PcepErrorObject> errObjList;
@Override
public PcepError build() {
return new PcepErrorVer1(rpObjList, lsObjList, errObjList);
}
@Override
public List<PcepRPObject> getRPObjList() {
return this.rpObjList;
}
@Override
public Builder setRPObjList(List<PcepRPObject> rpObjList) {
this.rpObjList = rpObjList;
return this;
}
@Override
public List<PcepLSObject> getLSObjList() {
return this.lsObjList;
}
@Override
public Builder setLSObjList(List<PcepLSObject> lsObjList) {
this.lsObjList = lsObjList;
return this;
}
@Override
public List<PcepErrorObject> getErrorObjList() {
return this.errObjList;
}
@Override
public Builder setErrorObjList(List<PcepErrorObject> errObjList) {
this.errObjList = errObjList;
return this;
}
}
@Override
public void setRPObjList(List<PcepRPObject> rpObjList) {
this.rpObjList = rpObjList;
}
@Override
public void setLSObjList(List<PcepLSObject> lsObjList) {
this.lsObjList = lsObjList;
}
@Override
public void setErrorObjList(List<PcepErrorObject> errObjList) {
this.errObjList = errObjList;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.omitNullValues()
.add("RpObjectList", rpObjList)
.add("LsObjectList", lsObjList)
.add("ErrorObjectList", errObjList)
.toString();
}
}