【发布时间】:2015-08-19 13:47:39
【问题描述】:
我有以下问题。我正在从 SonicWall 中删除一些防火墙规则。我这样做的方法是从声波墙中获取所有规则,找到匹配的规则,将它们存储在一个列表中并使用这个列表来发出删除它们的命令。删除规则的方法是使用 SSH 和带有其 ID 的命令。我遇到的问题是,每次删除 ID 时,所有 ID 都会更改,导致第二个命令尝试删除不存在的访问规则(或者更糟糕的是错误的访问规则)。我为了克服这个问题,在每次删除过程之后,我都会刷新我订购的列表以获取更新的元素,从而获得它们的新 ID。我面临的问题是列表的更新不正确(它发生在 for each 循环中),因为列表被用作迭代器(导致发出错误的命令)。
用新元素更新此列表的最佳和最安全的方法是什么?
下面是有问题的代码部分:
multiResult = expect.expect(anyOf(regexp("(.*)" + promptPattern)));
accessRules = getAccessRules(multiResult, accessRule);
if(accessRules == null){
Trc.trc("No access rules found to delete");
return false;
}
numberOfRulesToDelete = accessRules.size();
int size = numberOfRulesToDelete;
IntList deleteRulesId = new IntList();
while(numberOfRulesToDelete != 0){
for(AccessRule arToDelete : accessRules){
expect.sendLine("configure");
multiResult = expect.expect(anyOf(regexp("(.*)" + confmodePromptPattern)));
Result showCmdResult = multiResult.getResults().get(0);
GenericCmdDto outPut = null;
ObjectMapper objectMapper = new ObjectMapper();
GenericFailedCmdDto failedOutPut = null;
String swResponse = null;
swResponse = handleSWConfModeResponse(showCmdResult);
outPut = objectMapper.readValue(createSuccessfullJSONResponse(swResponse.getBytes()), GenericCmdDto.class);
if(outPut.getSuccess()){//if change to configure command was successfull
Result confCmdResult = null;
Trc.trc("Configure command: " + outPut.getSuccess());
expect.sendLine("no access-rule id " + arToDelete.getIndex());
MultiResult confResult = expect.expect(anyOf(regexp("(.*)" + confmodePromptPattern)));
confCmdResult = confResult.getResults().get(0);
swResponse = handleSWConfModeResponse(confCmdResult);
outPut = objectMapper.readValue(createSuccessfullJSONResponse(swResponse.getBytes()), GenericCmdDto.class);
if(outPut.getSuccess()){//if the delete command was successfull
Trc.trc("Delete command issued successfully");
expect.sendLine("commit");
confCmdResult = expect.expect(anyOf(regexp("(.*)" + confmodePromptPattern)));
swResponse = handleSWConfModeResponse(confCmdResult);
outPut = objectMapper.readValue(createSuccessfullJSONResponse(swResponse.getBytes()), GenericCmdDto.class);
if(outPut.getSuccess()){//if the commit command was successfull
Trc.trc("Commit command issued succesfully!");
Trc.trc("Deleted successfully access rule: " + arToDelete.getIndex());
deleteRulesId.addElement(arToDelete.getIndex());
expect.sendLine("exit");//change to no conf mode
confCmdResult = expect.expect(anyOf(regexp("(.*)" + promptPattern)));
swResponse = handleSWPromptModeResponse(confCmdResult);
outPut = objectMapper.readValue(createSuccessfullJSONResponse(swResponse.getBytes()), GenericCmdDto.class);
if(outPut.getSuccess()){//if the exit command was successfull
Trc.trc("Exit command issued successfully!");
operationSuccess = outPut.getSuccess();
}else{//if exit unsucessfull
failedOutPut = objectMapper.readValue(createFailedJSONResponse(swResponse.getBytes()), GenericFailedCmdDto.class);
operationSuccess = outPut.getSuccess();
Trc.trc("Commit command has failed! Message: " + failedOutPut.getMessage() + ", Code: " + failedOutPut.getCode());
Trc.trc("Changing to show mode....");
expect.sendLine("exit");
multiResult = expect.expect(anyOf(regexp("(.*)" + promptPattern)));
showCmdResult = multiResult.getResults().get(0);
swResponse = handleSWPromptModeResponse(confCmdResult);
outPut = objectMapper.readValue(createSuccessfullJSONResponse(swResponse.getBytes()), GenericCmdDto.class);
if(outPut.getSuccess()){
Trc.trc("Exiting from conf mode..");
Trc.trc("Exit command: " + outPut.getSuccess());
}
return operationSuccess;
}
}else{//if commit unsucessfull
failedOutPut = objectMapper.readValue(createFailedJSONResponse(swResponse.getBytes()), GenericFailedCmdDto.class);
operationSuccess = outPut.getSuccess();
Trc.trc("Commit command has failed! Message: " + failedOutPut.getMessage() + ", Code: " + failedOutPut.getCode());
Trc.trc("Changing to show mode....");
expect.sendLine("exit");
multiResult = expect.expect(anyOf(regexp("(.*)" + promptPattern)));
showCmdResult = multiResult.getResults().get(0);
swResponse = handleSWPromptModeResponse(showCmdResult);
outPut = objectMapper.readValue(createSuccessfullJSONResponse(swResponse.getBytes()), GenericCmdDto.class);
if(outPut.getSuccess()){
Trc.trc("Exiting from conf mode..");
Trc.trc("Exit command: " + outPut.getSuccess());
}
return operationSuccess;
}
}else{//if delete unsucessfull
failedOutPut = objectMapper.readValue(createFailedJSONResponse(swResponse.getBytes()), GenericFailedCmdDto.class);
operationSuccess = outPut.getSuccess();
Trc.trc("Commit command has failed! Message: " + failedOutPut.getMessage() + ", Code: " + failedOutPut.getCode());
Trc.trc("Changing to show mode....");
expect.sendLine("exit");
multiResult = expect.expect(anyOf(regexp("(.*)" + promptPattern)));
showCmdResult = multiResult.getResults().get(0);
swResponse = handleSWPromptModeResponse(showCmdResult);
outPut = objectMapper.readValue(createSuccessfullJSONResponse(swResponse.getBytes()), GenericCmdDto.class);
if(outPut.getSuccess()){
Trc.trc("Exiting from conf mode..");
Trc.trc("Exit command: " + outPut.getSuccess());
}
return operationSuccess;
}
}
else{//if configure unsuccessfull
failedOutPut = objectMapper.readValue(createFailedJSONResponse(swResponse.getBytes()), GenericFailedCmdDto.class);
operationSuccess = outPut.getSuccess();
Trc.trc("Commit command has failed! Message: " + failedOutPut.getMessage() + ", Code: " + failedOutPut.getCode());
Trc.trc("Changing to show mode....");
expect.sendLine("exit");
multiResult = expect.expect(anyOf(regexp("(.*)" + promptPattern)));
showCmdResult = multiResult.getResults().get(0);
swResponse = handleSWPromptModeResponse(showCmdResult);
outPut = objectMapper.readValue(createSuccessfullJSONResponse(swResponse.getBytes()), GenericCmdDto.class);
if(outPut.getSuccess()){
Trc.trc("Exiting from conf mode..");
Trc.trc("Exit command: " + outPut.getSuccess());
}
return operationSuccess;
}
expect.sendLine("show access-rules from " + accessRule.getFromZone() + " to " + accessRule.getToZone());
multiResult = expect.expect(anyOf(regexp("(.*)" + promptPattern)));
accessRules = getAccessRules(multiResult, accessRule);
if(accessRules != null){
numberOfRulesToDelete = accessRules.size();
}else{
Trc.trc("Deleting process complete!");
numberOfRulesToDelete = 0;
for(int i = 0; i < deleteRulesId.size(); i++){
Trc.trc("Deleted " + size + " successfully rules: " + deleteRulesId.getElementAt(i));
}
}
}
}
return operationSuccess;
【问题讨论】:
-
请去掉代码中不相关的部分并创建一个SSCCE来显示问题。
-
我同意 Keppil 的观点,即代码似乎包含太多与问题无关的部分,但除此之外,您可以尝试直接使用迭代器(使用
hasNext()和next()进行迭代)并调用remove()在需要删除的元素的迭代器上。如果有可能在迭代器已经存在的地方插入新元素,这可能是一个问题,所以不要在迭代时添加新元素。 (如果只是 ids 改变并且顺序是不变的,那应该不是问题)。