com.cloudimpl.outstack.spring.service.RepositoryStreamingService Maven / Gradle / Ivy
/*
* Copyright 2021 nuwan.
*
* 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 com.cloudimpl.outstack.spring.service;
import com.cloudimpl.outstack.common.CloudMessage;
import com.cloudimpl.outstack.common.RouterType;
import com.cloudimpl.outstack.core.CloudUtil;
import com.cloudimpl.outstack.core.Inject;
import com.cloudimpl.outstack.core.annon.CloudFunction;
import com.cloudimpl.outstack.core.annon.Router;
import com.cloudimpl.outstack.runtime.EntityIdHelper;
import com.cloudimpl.outstack.runtime.EntityMetaDetailCache;
import com.cloudimpl.outstack.runtime.EventRepositoryFactory;
import com.cloudimpl.outstack.runtime.EventRepositoy;
import com.cloudimpl.outstack.runtime.common.StreamProcessor;
import com.cloudimpl.outstack.runtime.domainspec.ChildEntity;
import com.cloudimpl.outstack.runtime.domainspec.Entity;
import com.cloudimpl.outstack.runtime.domainspec.Query;
import com.cloudimpl.outstack.runtime.domainspec.RootEntity;
import com.cloudimpl.outstack.runtime.repo.MemEventRepositoryFactory;
import com.cloudimpl.outstack.runtime.repo.RepoStreamingReq;
import com.cloudimpl.outstack.runtime.repo.RepoStreamingReq.ResourceInfo;
import com.cloudimpl.outstack.runtime.repo.StreamEvent;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Flux;
/**
*
* @author nuwan
*/
@CloudFunction(name = "RepositoryStreamingService")
@Router(routerType = RouterType.NODE_ID)
@Slf4j
public class RepositoryStreamingService implements Function {
@Override
public Flux apply(CloudMessage t) {
RepoStreamingReq req = t.data();
StreamProcessor eventStream = EventRepositoryFactory.getEventStream();
Flux eventsFlux = eventStream.flux().filter(e -> {
// log.info("repo stream event {}", e.getEvent());
Entity entity = (Entity) e.getEvent();
String rootType = entity.isRoot() ? entity.getClass().getName() : ChildEntity.class.cast(entity).rootType().getName();
Optional> listOptional = req.getResources(rootType);
if (listOptional.isPresent()) {
List list = listOptional.get();
for (RepoStreamingReq.ResourceInfo info : list) {
if (info.getChildType() != null && entity instanceof ChildEntity) {
if (onChildEventListener(info, entity)) {
return true;
}
} else if (info.getChildType() == null) {
if (onRootEventListener(info, entity)) {
return true;
}
}
}
}
return false;
}).cast(StreamEvent.class);
return Flux.merge(subscribeToRootResources(req), eventsFlux);
}
private boolean onRootEventListener(RepoStreamingReq.ResourceInfo info, Entity entity) {
if(!info.getEntityType().equals(entity.getClass().getName())){
return false;
}
if (info.getTenantId() != null && info.getTenantId().equals("*")) {
if (info.getEntityId().equals("*")) {
return true;
} else if (EntityIdHelper.isTechnicalId(info.getEntityId())) {
return info.getEntityId().equals(entity.id());
} else {
return info.getEntityId().equals(entity.entityId());
}
} else if (info.getTenantId() == null && entity.getTenantId() == null) {
if (info.getEntityId().equals("*")) {
return true;
} else if (EntityIdHelper.isTechnicalId(info.getEntityId())) {
return info.getEntityId().equals(entity.id());
} else {
return info.getEntityId().equals(entity.entityId());
}
} else if (info.getTenantId() != null && entity.getTenantId() != null && info.getTenantId().equals(entity.getTenantId())) {
if (info.getEntityId().equals("*")) {
return true;
} else if (EntityIdHelper.isTechnicalId(info.getEntityId())) {
return info.getEntityId().equals(entity.id());
} else {
return info.getEntityId().equals(entity.entityId());
}
}
return false;
}
private boolean onChildEventListener(RepoStreamingReq.ResourceInfo info, Entity entity) {
if (!info.getChildType().equals("*") && !info.getChildType().equals(entity.getClass().getName())) {
return false;
}
ChildEntity child = (ChildEntity) entity;
if (!info.getEntityId().equals("*")) {
if (EntityIdHelper.isTechnicalId(info.getEntityId())) {
if (!info.getEntityId().equals(child.rootId())) {
return false;
}
} else {
throw new RuntimeException("resource " + info.getEntityType() + " rootId should be technical id");
}
}
if (info.getTenantId() != null && info.getTenantId().equals("*")) {
if (info.getChildId().equals("*")) {
return true;
} else if (EntityIdHelper.isTechnicalId(info.getChildId())) {
return info.getChildId().equals(entity.id());
} else {
return info.getChildId().equals(entity.entityId());
}
} else if (info.getTenantId() == null && entity.getTenantId() == null) {
if (info.getChildId().equals("*")) {
return true;
} else if (EntityIdHelper.isTechnicalId(info.getChildId())) {
return info.getChildId().equals(entity.id());
} else {
return info.getChildId().equals(entity.entityId());
}
} else if (info.getTenantId() != null && entity.getTenantId() != null && info.getTenantId().equals(entity.getTenantId())) {
if (info.getChildId().equals("*")) {
return true;
} else if (EntityIdHelper.isTechnicalId(info.getChildId())) {
return info.getChildId().equals(entity.id());
} else {
return info.getChildId().equals(entity.entityId());
}
}
return false;
}
private Flux subscribeToRootResources(RepoStreamingReq req) {
return Flux.fromIterable(req.getInitialDownloadResources()).map(s -> getResources(s)).flatMapIterable(l -> l);
}
private Collection getResources(ResourceInfo resourceInfo) {
if (resourceInfo.getChildType() == null) {
return (Collection) getEventRepo(resourceInfo.getEntityType()).getAllByRootType(CloudUtil.classForName(resourceInfo.getEntityType()), resourceInfo.getTenantId(),
new Query.PagingRequest(0, Integer.MAX_VALUE, Collections.EMPTY_LIST, Collections.EMPTY_MAP, resourceInfo.getSearchParam(), null)).getItems().stream().
map(r -> new StreamEvent(StreamEvent.Action.ADD, r)).collect(Collectors.toList());
} else {
return (Collection) getEventRepo(resourceInfo.getEntityType()).getAllChildByType(CloudUtil.classForName(resourceInfo.getEntityType()), resourceInfo.getEntityId(), CloudUtil.classForName(resourceInfo.getChildType()), resourceInfo.getTenantId(), new Query.PagingRequest(0, Integer.MAX_VALUE, Collections.EMPTY_LIST, Collections.EMPTY_MAP, resourceInfo.getSearchParam(), null)).getItems().stream().
map(r -> new StreamEvent(StreamEvent.Action.ADD, r)).collect(Collectors.toList());
}
}
private EventRepositoy getEventRepo(String rootType) {
return EventRepositoryFactory.getRepository(CloudUtil.classForName(rootType)).orElseThrow(() -> new RuntimeException("repository " + rootType + " not found"));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy