blob: 0bc675eb3a69ccb6c4349a6bae9b6987b70e0cb3 [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.ListIterator;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepFecObject;
import org.onosproject.pcepio.protocol.PcepLabelObject;
import org.onosproject.pcepio.protocol.PcepLabelUpdate;
import org.onosproject.pcepio.protocol.PcepLspObject;
import org.onosproject.pcepio.protocol.PcepSrpObject;
import org.onosproject.pcepio.types.PcepLabelDownload;
import org.onosproject.pcepio.types.PcepLabelMap;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.MoreObjects;
/**
* Provides PCEP LABEL update .
* Reference :draft-zhao-pce-pcep-extension-for-pce-controller-01.
*/
public class PcepLabelUpdateVer1 implements PcepLabelUpdate {
/*
* <pce-label-update> ::= (<pce-label-download>|<pce-label-map>)
Where:
<pce-label-download> ::= <SRP>
<LSP>
<label-list>
<pce-label-map> ::= <SRP>
<LABEL>
<FEC>
<label-list > ::= <LABEL>
[<label-list>]
*/
protected static final Logger log = LoggerFactory.getLogger(PcepLabelUpdateVer1.class);
//Either PceLabelDownload or PceLabelMap is mandatory.
//label Download
private PcepLabelDownload labelDownload;
private boolean isLabelDownloadSet;
//label Map
private PcepLabelMap labelMap;
private boolean isLabelMapSet;
/**
* Constructor to reset parameters.
*/
public PcepLabelUpdateVer1() {
this.labelDownload = null;
this.isLabelDownloadSet = false;
this.labelMap = null;
this.isLabelMapSet = false;
}
/**
* Constructor to initialize PCEP label download.
*
* @param labelDownload PCEP label download
*/
public PcepLabelUpdateVer1(PcepLabelDownload labelDownload) {
this.labelDownload = labelDownload;
this.isLabelDownloadSet = true;
this.labelMap = null;
this.isLabelMapSet = false;
}
/**
* Constructor to initialize PCEP label map.
*
* @param labelMap PCEP label map
*/
public PcepLabelUpdateVer1(PcepLabelMap labelMap) {
this.labelDownload = null;
this.isLabelDownloadSet = false;
this.labelMap = labelMap;
this.isLabelMapSet = true;
}
/**
* builder class for PCEP label update.
*/
static class Builder implements PcepLabelUpdate.Builder {
private PcepLabelDownload labelDownload;
private boolean isLabelDownloadSet;
private PcepLabelMap labelMap;
private boolean isLabelMapSet;
@Override
public PcepLabelUpdate build() throws PcepParseException {
if (isLabelDownloadSet) {
return new PcepLabelUpdateVer1(labelDownload);
}
if (isLabelMapSet) {
return new PcepLabelUpdateVer1(labelMap);
}
if (!isLabelDownloadSet && !isLabelMapSet) {
throw new PcepParseException(
"Label Download or Label Map is not set while building PcepLabelUpdate Message");
}
return new PcepLabelUpdateVer1();
}
@Override
public Builder setLabelDownload(PcepLabelDownload labelDownload) {
this.labelDownload = labelDownload;
this.isLabelDownloadSet = true;
return this;
}
@Override
public PcepLabelDownload getLabelDownload() {
return labelDownload;
}
@Override
public Builder setLabelMap(PcepLabelMap labelMap) {
this.labelMap = labelMap;
this.isLabelMapSet = true;
return this;
}
@Override
public PcepLabelMap getLabelMap() {
return labelMap;
}
}
/**
* Reads PcepLabels from the byte stream received from channel buffer.
*
* @param cb of type channel buffer.
* @return PcepLabelUpdate object.
* @throws PcepParseException when fails to read from channel buffer
*/
public static PcepLabelUpdate read(ChannelBuffer cb) throws PcepParseException {
PcepLabelUpdateVer1 pceLabelUpdate = new PcepLabelUpdateVer1();
PcepSrpObject srpObject;
PcepObjectHeader tempObjHeader;
//read SRP mandatory Object
srpObject = PcepSrpObjectVer1.read(cb);
//checking next object
cb.markReaderIndex();
tempObjHeader = PcepObjectHeader.read(cb);
cb.resetReaderIndex();
if (tempObjHeader.getObjClass() == PcepLspObjectVer1.LSP_OBJ_CLASS) {
//now it is belong to <pce-label-download>
PcepLabelDownload labelDownload = new PcepLabelDownload();
//set SRP
labelDownload.setSrpObject(srpObject);
//read and set LSP
labelDownload.setLspObject(PcepLspObjectVer1.read(cb));
//<label-list>
LinkedList<PcepLabelObject> llLabelList = new LinkedList<>();
PcepLabelObject labelObject;
while (0 < cb.readableBytes()) {
cb.markReaderIndex();
tempObjHeader = PcepObjectHeader.read(cb);
cb.resetReaderIndex();
if (tempObjHeader.getObjClass() != PcepLabelObjectVer1.LABEL_OBJ_CLASS) {
break;
}
labelObject = PcepLabelObjectVer1.read(cb);
llLabelList.add(labelObject);
}
labelDownload.setLabelList(llLabelList);
pceLabelUpdate.setLabelDownload(labelDownload);
} else if (tempObjHeader.getObjClass() == PcepLabelObjectVer1.LABEL_OBJ_CLASS) {
//belong to <pce-label-map>
PcepLabelMap labelMap = new PcepLabelMap();
//set SRP Object
labelMap.setSrpObject(srpObject);
//read and set Label Object
labelMap.setLabelObject(PcepLabelObjectVer1.read(cb));
cb.markReaderIndex();
tempObjHeader = PcepObjectHeader.read(cb);
cb.resetReaderIndex();
PcepFecObject fecObject = null;
switch (tempObjHeader.getObjType()) {
case PcepFecObjectIPv4Ver1.FEC_OBJ_TYPE:
fecObject = PcepFecObjectIPv4Ver1.read(cb);
break;
case PcepFecObjectIPv6Ver1.FEC_OBJ_TYPE:
fecObject = PcepFecObjectIPv6Ver1.read(cb);
break;
case PcepFecObjectIPv4AdjacencyVer1.FEC_OBJ_TYPE:
fecObject = PcepFecObjectIPv4AdjacencyVer1.read(cb);
break;
case PcepFecObjectIPv6AdjacencyVer1.FEC_OBJ_TYPE:
fecObject = PcepFecObjectIPv6AdjacencyVer1.read(cb);
break;
case PcepFecObjectIPv4UnnumberedAdjacencyVer1.FEC_OBJ_TYPE:
fecObject = PcepFecObjectIPv4UnnumberedAdjacencyVer1.read(cb);
break;
default:
throw new PcepParseException("Unkown FEC object type " + tempObjHeader.getObjType());
}
labelMap.setFecObject(fecObject);
pceLabelUpdate.setLabelMap(labelMap);
} else {
throw new PcepParseException(
"Either <pce-label-download> or <pce-label-map> should be present. Received Class: "
+ tempObjHeader.getObjClass());
}
return pceLabelUpdate;
}
@Override
public void write(ChannelBuffer cb) throws PcepParseException {
if ((labelDownload != null) && (labelMap != null)) {
throw new PcepParseException("Label Download and Label Map both can't be present.");
}
if ((labelDownload == null) && (labelMap == null)) {
throw new PcepParseException("Either Label Download or Label Map should be present.");
}
if (labelDownload != null) {
PcepLspObject lspObject;
PcepSrpObject srpObject;
PcepLabelObject labelObject;
LinkedList<PcepLabelObject> llLabelList;
srpObject = labelDownload.getSrpObject();
if (srpObject == null) {
throw new PcepParseException("SRP Object is mandatory object for Label Download.");
} else {
srpObject.write(cb);
}
lspObject = labelDownload.getLspObject();
if (lspObject == null) {
throw new PcepParseException("LSP Object is mandatory object for Label Download.");
} else {
lspObject.write(cb);
}
llLabelList = labelDownload.getLabelList();
if (llLabelList == null) {
throw new PcepParseException("Label list is mandatory object for Label Download.");
} else {
ListIterator<PcepLabelObject> listIterator = llLabelList.listIterator();
while (listIterator.hasNext()) {
labelObject = listIterator.next();
labelObject.write(cb);
}
}
}
if (labelMap != null) {
PcepSrpObject srpObject;
PcepLabelObject labelObject;
PcepFecObject fecObject;
srpObject = labelMap.getSrpObject();
if (srpObject == null) {
throw new PcepParseException("SRP Object is mandatory object for Label map.");
} else {
srpObject.write(cb);
}
labelObject = labelMap.getLabelObject();
if (labelObject == null) {
throw new PcepParseException("label Object is mandatory object for Label map.");
} else {
labelObject.write(cb);
}
fecObject = labelMap.getFecObject();
if (fecObject == null) {
throw new PcepParseException("fec Object is mandatory object for Label map.");
} else {
fecObject.write(cb);
}
}
}
@Override
public void setLabelDownload(PcepLabelDownload labelDownload) {
if (this.isLabelMapSet) {
return;
}
this.labelDownload = labelDownload;
this.isLabelDownloadSet = true;
}
@Override
public PcepLabelDownload getLabelDownload() {
return this.labelDownload;
}
@Override
public void setLabelMap(PcepLabelMap labelMap) {
if (this.isLabelDownloadSet) {
return;
}
this.labelMap = labelMap;
this.isLabelMapSet = true;
}
@Override
public PcepLabelMap getLabelMap() {
return this.labelMap;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.omitNullValues()
.add("LabelDownload", labelDownload)
.add("LabelMap", labelMap)
.toString();
}
}