-
Notifications
You must be signed in to change notification settings - Fork 34
Gateway Manager Micorservice #541
Gateway Manager Micorservice #541
Conversation
# Conflicts: # services/port_manager/src/main/java/com/futurewei/alcor/portmanager/processor/FixedIpsProcessor.java # services/port_manager/src/main/java/com/futurewei/alcor/portmanager/request/RequestManager.java # services/private_ip_manager/src/main/java/com/futurewei/alcor/privateipmanager/controller/IpAddrController.java # services/private_ip_manager/src/main/java/com/futurewei/alcor/privateipmanager/repo/IpAddrRangeRepo.java # services/private_ip_manager/src/main/java/com/futurewei/alcor/privateipmanager/service/implement/IpAddrServiceImpl.java
# Conflicts: # services/port_manager/src/main/java/com/futurewei/alcor/portmanager/request/UpdatePortIpAddressRequest.java
…to gateway_manager_micorservice # Conflicts: # services/gateway_manager/src/main/java/com/futurewei/alcor/gatewaymanager/service/GatewayService.java
Codecov Report
@@ Coverage Diff @@
## master #541 +/- ##
============================================
- Coverage 34.95% 34.90% -0.05%
+ Complexity 1189 1183 -6
============================================
Files 473 473
Lines 11799 11799
Branches 1526 1526
============================================
- Hits 4124 4119 -5
- Misses 7112 7113 +1
- Partials 563 567 +4
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songxiaoyan I cannot find UT codes in this PR. Could you add UT in this PR to verify basic functionalities especially for DB (create/update/delete/query) operations?
| public void getGatewaysByVpcId(@PathVariable("projectid") String projectId) { | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songxiaoyan The gateway here should be project-scope, not vpc-scope. So, it should be listed all available gateways in the current project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a reserved interface, which will be adjusted according to actual business in the future
| public class GWAttachmentRepository implements ICacheRepository<GWAttachment> { | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songxiaoyan do we need cache for GWAttachment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to create the Cache Cache of GatewayEntity and GwAttachment in GM's DB for later interface query
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, agree.
| public class GatewayRepository implements ICacheRepository<GatewayEntity> { | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songxiaoyan Same here. Do we need cache for Gateway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree to have cache for GM's DB access.
| package com.futurewei.alcor.gatewaymanager.dao; | ||
|
|
||
| import org.springframework.stereotype.Repository; | ||
|
|
||
| @Repository | ||
| public class RouteTableRepository { | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songxiaoyan We probably don't need it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I can deleted reserved interface if don't need
| public class GatewayWebJson { | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this class is the return for "list all available gateway", it's better rename it "GatewaysWebJson"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
| server.port=9015 | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@xieus Does this port for GM? please confirm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am fine with 9015 and K8s cluster port of 30015. Keep in mind that 9014 remain available therefore we can keep it for other microservice.
|
|
||
| //TODO check whether the project type is zeta by projectId | ||
|
|
||
| // create GatewayInfo entity in the DB |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songxiaoyan Please re-phrase the comment here. We are not creating a GatewayInfo enity in GM's DB.
| <module>services/security_group_manager</module> | ||
| <module>services/elastic_ip_manager</module> | ||
| <module>services/quota_manager</module> | ||
| <module>services/network_acl_manager</module> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Irrelevant comment :-) Can we replace tab with space?
| public class GatewayIpJson { | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we include "zeta" in the class name? since it's dedicated for zeta gateway only.
| log.info("update GatewayEntity status to READY failed, detail message: {}", e.getMessage()); | ||
| //TODO how to handle this exception? rollback all? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the execution goes to this far, that's mean DPM already has an gatewayinfo entry for zeta with status = PENDING. In that case, when port creation comes to DPM, DPM should wait for the status become READY for 30s. If the status still PENDING or FAILED, DPM will switch to OVS plugin. So, should we let the updateDPMCacheGateway try some times and if still failed rollback GM's DB and ask Zeta to remove the corresponding gateway resources.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if update DPM's cache status to READY is fail,we need retry some times(3 times?),if still failed,we should rollback all the request resource, is this mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. that's what I think.
| //TODO if rollback failed,how we should handle it? | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songxiaoyan If rollback failed, we should raise an alarm or error.
| import com.futurewei.alcor.web.entity.route.RouteWebJson; | ||
| import com.futurewei.alcor.web.entity.subnet.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songxiaoyan why your code will touch the import in the SubnetController.java?
| import com.futurewei.alcor.web.entity.route.InternalRouterInfo; | ||
| import com.futurewei.alcor.web.entity.route.RouteWebJson; | ||
| import com.futurewei.alcor.web.entity.subnet.NewHostRoutes; | ||
| import com.futurewei.alcor.web.entity.subnet.SubnetEntity; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songxiaoyan Your IDE seems re-arrange the import statements in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merge code and resolve conflicts, it automatically import, I tried to turn it off.
| private List<String> tags; | ||
| private String owner; | ||
| private Map<String, String> options; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songxiaoyan Do we need constructor here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you mean it should be constructor in the GM entity package?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean such the code like this:
public GatewayEntity() {
}
public GatewayEntity(GatewayType type, String status, List<GatewayIp> ips, private List<String> attachments, List<String> routetables, ...) {
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh,I get your mean,I use the set method to assign values, if necessary, I can add the construction method
I'll make it up as soon as possible |
| * @param gatewayId | ||
| * @param gwAttachment | ||
| */ | ||
| @PostMapping("/project/{projectid}/gateways/{gateway_id}/attachments") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Underscore style is recommended: project_id
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
| if (!gatewayId.equals(attachment.getGatewayId())) { | ||
| throw new Exception(ExceptionMsgConfig.GATEWAY_NOT_ASSOCIATED_ATTACHMENT.getMsg()); | ||
| } | ||
| gatewayEntity.getAttachments().removeIf(attachId::equals); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also need to persist the updated gatewayEntity to db here, linke this: gatewayRepository.addItem(gatewayEntity)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have updates in the code below
| gatewayEntity.getAttachments().removeIf(attachId::equals); | ||
|
|
||
| //delete attachment and update GatewayEntity in the DB | ||
| gwAttachmentRepository.deleteItem(attachId,gatewayEntity); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is a transaction required to ensure the consistency of gatewayRepository and gwAttachmentRepository?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are transactions in the method
|
|
||
|
|
||
| public List<GWAttachment> getAllAttachments(String gatewayId) throws CacheException { | ||
| Map<String, GWAttachment> attachmentMap = gwAttachmentRepository.findAllItems(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest using findAllItems(Map < String, Object [] > queryParams) instead of findAllItems() here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
| RestPreconditionsUtil.verifyParameterNotNullorEmpty(projectId); | ||
| RestPreconditionsUtil.verifyParameterNotNullorEmpty(vpcId); | ||
| gatewayService.deleteGatewayInfoForZeta(projectId, vpcId); | ||
| log.info("GatewayInfo deleted success,the resource_id is: {}", vpcId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to initialize log with module class? linke this: private static final Logger log = LoggerFactory.getLogger(GatewayController.class);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used the @slf4j annotation,do don't need to initialize log.
| //TODO check whether the project type is zeta by projectId | ||
|
|
||
| GatewayEntity gatewayEntity = null; | ||
| Map<String, GWAttachment> attachmentsMap = gwAttachmentRepository.findAllItems(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is recommended to use the method of findAllItems (Map < String, Object [] > queryParams).
| Map<String, GWAttachment> attachmentsMap = gwAttachmentRepository.findAllItems(); | ||
| for (GatewayEntity newGatewayEntity : newGatewayInfo.getGatewayEntities()) { | ||
| for (GWAttachment attachment : attachmentsMap.values()) { | ||
| if (attachment.getResourceId().equals(newGatewayInfo.getResourceId())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be attachment.getGatewayId() == newGatewayInfo.getResourceId() ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
String parameters,I think use the equals to compare is better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
attachment.getGatewayId(), not attachment.getResourceId() ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
attachment.getGatewayId() is the gatewayId, attachment.getResourceId() and newGatewayInfo.getResourceId() is the vpcId
| */ | ||
| @PutMapping("/project/{projectid}/gatewayinfo/{resource_id}") | ||
| @ResponseStatus(HttpStatus.NO_CONTENT) | ||
| public ResponseId updateGatewayInfoForZeta(@PathVariable("projectid") String projectId, @PathVariable("resource_id") String vpcId, @RequestBody GatewayInfoJson gatewayInfoJson) throws Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Who will call this interface? vpc-manager?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure, now it’s just providing this interface
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DPM will call this interface if there is no gatewayinfo entry in the DPM's cache for a vpc.
| throw new Exception(ExceptionMsgConfig.GATEWAY_ENTITY_NOT_FOUND.getMsg()); | ||
| } | ||
| if (gatewayEntity.getType().equals(newGatewayEntity.getType())) { | ||
| gatewayEntity.setStatus(newGatewayEntity.getStatus()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need gatewayRepository.addItem(gatewayEntity) here ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have updates in the code below
| log.info("update GatewayEntity status to READY failed, detail message: {}", e.getMessage()); | ||
| // rollback GM's DB and ask Zeta to remove the corresponding gateway resources | ||
| } | ||
|
|
||
| try { | ||
| rollback(result, gatewayInfo, gatewayEntity, projectId); | ||
| } catch (Exception e) { | ||
| log.info("rollback failed, detail message: {}", e.getMessage()); | ||
| // If rollback failed, we should raise an alarm or error. | ||
| } | ||
| return null; | ||
| }); | ||
| return gatewayInfo; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can leave rollback to another PR and figure out a better generic way for rollback.
cj-chung
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current code looks good for zeta gateway integration. The rollback part can leave for another PR after we figure out a better generic way to handle the rollback.
Current support CREATE,UPDATE,DELETE(for zeta gateway),continued development based on the design will follow