diff --git a/src/main/java/component/NackHeader.java b/src/main/java/component/NackHeader.java index 91fab99..21ac8d0 100644 --- a/src/main/java/component/NackHeader.java +++ b/src/main/java/component/NackHeader.java @@ -24,6 +24,23 @@ public class NackHeader implements TlvComponentBase,InitialAble, IEncodingAble { this.setNackReason(nackReason); } + /** + * GetNackReasonString 根据 NackReason 的枚举值,获取其对应的字符串描述 + * @param reason + * @return + */ + public static String getNackReasonString(long reason){ + switch ((int) reason){ + case (int) NackReasonUnknown: + return "Unknown"; + case (int) NackReasonDuplicate: + return "Duplicate"; + case (int) NackReasonNoRoute: + return "NoRoute"; + } + return "Unknown"; + } + // 函数 public long getNackReason() { return nackReason; diff --git a/src/main/java/mgmt/CommandExecutor.java b/src/main/java/mgmt/CommandExecutor.java index 1e79a7d..744efd7 100644 --- a/src/main/java/mgmt/CommandExecutor.java +++ b/src/main/java/mgmt/CommandExecutor.java @@ -2,6 +2,7 @@ package mgmt; import component.ComponentException; import component.Identifier; +import component.NackHeader; import jnr.ffi.annotations.In; import logicface.LogicFace; import logicface.LogicFaceException; @@ -225,11 +226,29 @@ public class CommandExecutor { } }else if(PacketTypeHelper.isNack(minPacket)){ // onNack -// Nack nack=new Nack().createNackByInterest(); - // todo: here here!!!! + Nack nack=new Nack().createNackByMINPacket(minPacket); + if(nack==null){ + return null; + }else{ + // onNack + controlResponse.code=ControlResponse.ControlResponseCodeCommonError; + controlResponse.msg="Request failed, receive nack => "+ + NackHeader.getNackReasonString(nack.getNackReason()); + } + }else{ + // 收到其他类型的包直接抛出错误,未预期的行为 + controlResponse.code=ControlResponse.ControlResponseCodeCommonError; + controlResponse.msg="Receive one other type packet, Unexpected behavior!"; } - return null; + // 如果设置了自动shutdown,则执行shutdown + if(this.autoShutdown){ + if(!this.shutdown()){ + return null; + } + } + + return controlResponse; } catch (MgmtException | ComponentException | LogicFaceException | PacketException e) { throw new MgmtException("CommandExecutor.start: "+e.getMessage()); } diff --git a/src/main/java/mgmt/ControlResponse.java b/src/main/java/mgmt/ControlResponse.java index 5da9532..1fe6d2c 100644 --- a/src/main/java/mgmt/ControlResponse.java +++ b/src/main/java/mgmt/ControlResponse.java @@ -33,18 +33,69 @@ public class ControlResponse { // 信息 public String msg; // 数据 - public interface data{}; + public class ControlResponseData{ + public E value; + } + public ControlResponseData data=new ControlResponseData(); /** * GetString 按字符串类型访问 Data * @return */ -// public String getString(){ -// return this.d -// } + public String getString(){ + return (String) this.data.value; + } -// public void setString(String str){ -// this.type=ControlResponseTypeString; -// this.da -// } + /** + * SetString 按字符串类型设置 Data + * @param str + */ + public void setString(String str){ + this.type=ControlResponseTypeString; + this.data.value=str; + } + + /** + * GetMeta 按元数据类型访问 Data + * @return + */ + public ControlResponseMeta getMeta(){ + return (ControlResponseMeta) this.data.value; + } + + /** + * SetMeta 按元数据类型设置 Data + * @param meta + */ + public void setMeta(ControlResponseMeta meta){ + this.type=ControlResponseTypeMeta; + this.data.value=meta; + } + + /** + * GetBytes 按字节数组类型获取 Data + * @return + */ + public byte[] getBytes(){ + return (byte[]) this.data.value; + } + + /** + * SetBytes 按字节数组类型设置 Data + * @param bytes + */ + public void setBytes(byte[] bytes){ + this.type=ControlResponseTypeBytes; + this.data.value=bytes; + } + + /** + * UnmarshalJSON 自定义 JSON 反序列化逻辑,可以根据不同类型,Data 反序列化为对应的子类型 + * @param data + * @return + */ + public boolean UnmarshalJSON(byte[] data){ + // todo: here!!! + return true; + } } diff --git a/src/main/java/mgmt/ControlResponseMeta.java b/src/main/java/mgmt/ControlResponseMeta.java new file mode 100644 index 0000000..3563dc9 --- /dev/null +++ b/src/main/java/mgmt/ControlResponseMeta.java @@ -0,0 +1,31 @@ +package mgmt; + +/* + * @Author: Wang Feng + * @Description: ControlResponseMeta 表示一个管理控制命令的元数据结构 + * @Version: 1.0.0 + * @Date: 9:39 2021/4/28 + * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 + */ +public class ControlResponseMeta { + // 版本号 + public long Version; + // 总的分片数量 + public long SliceNum; + + /** + * CreateMetaDataControlResponse 创建一个表示元数据的返回响应 + * @param version + * @param sliceNum + * @return + */ + public static ControlResponse createMetaDataControlResponse(long version,long sliceNum){ + ControlResponse response=new ControlResponse(); + response.code=ControlResponse.ControlResponseCodeContinue; + ControlResponseMeta meta=new ControlResponseMeta(); + meta.Version=version; + meta.SliceNum=sliceNum; + response.setMeta(meta); + return response; + } +} diff --git a/src/main/java/mgmt/RegisterPrefixHelper.java b/src/main/java/mgmt/RegisterPrefixHelper.java index fc9934b..90714eb 100644 --- a/src/main/java/mgmt/RegisterPrefixHelper.java +++ b/src/main/java/mgmt/RegisterPrefixHelper.java @@ -22,24 +22,34 @@ public class RegisterPrefixHelper { * @param keyChain * @return */ - public boolean registerPrefix(Identifier identifier, LogicFace face, KeyChain keyChain){ - MIRController controller=MIRController.createMIRController(new LogicFaceBuilderInterface() { - @Override - public LogicFace LogicFaceBuilder() { - return face; - } - }, - false, keyChain); - ControlParameters parameters=new ControlParameters(); - parameters.controlParameterPrefix.setPrefix(identifier); - CommandExecutor commandExecutor=controller.prepareCommandExecutor( - RegisterPrefixCommand.createRegisterPrefixCommand("/min-mir/mgmt/localhost",parameters)); - if(commandExecutor==null){ - return false; - } -// ControlResponse response=commandExecutor - // todo: here here!!! + public boolean registerPrefix(Identifier identifier, LogicFace face, KeyChain keyChain) throws MgmtException { + try { + MIRController controller = MIRController.createMIRController(new LogicFaceBuilderInterface() { + @Override + public LogicFace LogicFaceBuilder() { + return face; + } + }, + false, keyChain); + ControlParameters parameters = new ControlParameters(); + parameters.controlParameterPrefix.setPrefix(identifier); + CommandExecutor commandExecutor = controller.prepareCommandExecutor( + RegisterPrefixCommand.createRegisterPrefixCommand("/min-mir/mgmt/localhost", parameters)); + if (commandExecutor == null) { + return false; + } + ControlResponse response = commandExecutor.start(); + if(response==null){ + return false; + } - return true; + if(response.code==ControlResponse.ControlResponseCodeSuccess){ + return true; + }else{ + throw new MgmtException("RegisterPrefixHelper.registerPrefix: "+response.msg); + } + }catch (MgmtException e){ + throw new MgmtException("RegisterPrefixHelper.registerPrefix: "+e.getMessage()); + } } } diff --git a/src/main/java/packet/Nack.java b/src/main/java/packet/Nack.java index 37afd07..92c4b00 100644 --- a/src/main/java/packet/Nack.java +++ b/src/main/java/packet/Nack.java @@ -4,6 +4,7 @@ import component.ComponentException; import encoding.Block; import encoding.Encoder; import encoding.IEncodingAble; +import jnr.ffi.annotations.In; /* * @Author: Wang Feng @@ -40,6 +41,11 @@ public class Nack implements IEncodingAble { this.setNackReason(reason); } + /** + * CreateNackByInterest 通过一个兴趣包构造一个 Nack + * @param interest + * @return + */ public Nack createNackByInterest(Interest interest){ if(!interest.nackHeader.isInitial()){ // NackHeader 没有初始化 @@ -51,6 +57,24 @@ public class Nack implements IEncodingAble { return nack; } + /** + * CreateNackByMINPacket 通过一个 MINPacket 构造一个 Nack + * @param minPacket + * @return + */ + public Nack createNackByMINPacket(MINPacket minPacket) throws PacketException { + try { + Interest interest=new Interest().createInterestByMINPacket(minPacket); + if(interest==null){ + return null; + }else{ + return this.createNackByInterest(interest); + } + } catch (PacketException e) { + throw new PacketException("Nack.createNackByMINPacket: "+e.getMessage()); + } + } + /** * 设置 Nack 的原因 */