org.streampipes.manager.recommender.ElementRecommender Maven / Gradle / Ivy
/*
* Copyright 2018 FZI Forschungszentrum Informatik
*
* 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.streampipes.manager.recommender;
import com.rits.cloning.Cloner;
import org.streampipes.commons.Utils;
import org.streampipes.commons.exceptions.NoSepaInPipelineException;
import org.streampipes.commons.exceptions.NoSuitableSepasAvailableException;
import org.streampipes.manager.matching.PipelineVerificationHandler;
import org.streampipes.manager.storage.UserManagementService;
import org.streampipes.manager.util.PipelineVerificationUtils;
import org.streampipes.model.base.InvocableStreamPipesEntity;
import org.streampipes.model.base.NamedStreamPipesEntity;
import org.streampipes.model.client.pipeline.Pipeline;
import org.streampipes.model.client.pipeline.PipelineElementRecommendation;
import org.streampipes.model.client.pipeline.PipelineElementRecommendationMessage;
import org.streampipes.model.graph.DataSinkDescription;
import org.streampipes.model.graph.DataSinkInvocation;
import org.streampipes.model.graph.DataProcessorDescription;
import org.streampipes.model.graph.DataProcessorInvocation;
import org.streampipes.storage.api.INoSqlStorage;
import org.streampipes.storage.management.StorageDispatcher;
import org.streampipes.storage.management.StorageManager;
import org.apache.commons.lang.RandomStringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class ElementRecommender {
private Pipeline pipeline;
private String email;
private PipelineElementRecommendationMessage recommendationMessage;
private Cloner cloner;
public ElementRecommender(String email, Pipeline partialPipeline) {
this.email = email;
this.pipeline = partialPipeline;
this.recommendationMessage = new PipelineElementRecommendationMessage();
this.cloner = new Cloner();
}
public PipelineElementRecommendationMessage findRecommendedElements() throws NoSuitableSepasAvailableException {
String connectedTo;
String rootNodeElementId;
try {
InvocableStreamPipesEntity sepaElement = getRootNode();
sepaElement.setConfigured(true);
rootNodeElementId = sepaElement.getBelongsTo();
connectedTo = sepaElement.getDOM();
} catch (NoSepaInPipelineException e) {
connectedTo = pipeline.getStreams().get(0).getDOM();
rootNodeElementId = pipeline.getStreams().get(0).getElementId();
}
validateSepas(connectedTo);
validateSecs(connectedTo);
if (recommendationMessage.getPossibleElements().size() == 0) throw new NoSuitableSepasAvailableException();
else {
recommendationMessage
.setRecommendedElements(calculateWeights(
filterOldElements(getNoSqlStorage()
.getConnectionStorageApi()
.getRecommendedElements(rootNodeElementId))));
return recommendationMessage;
}
}
private List filterOldElements(List recommendedElements) {
return recommendedElements
.stream()
.filter(r -> getAll()
.stream()
.anyMatch(a -> a.getElementId().equals(r.getElementId())))
.collect(Collectors.toList());
}
private List calculateWeights(List recommendedElements) {
int allConnectionsCount = recommendedElements
.stream()
.mapToInt(r -> r.getCount())
.sum();
recommendedElements
.forEach(r -> {
r.setWeight(getWeight(r.getCount(), allConnectionsCount));
r.setName(getName(r.getElementId()));
r.setDescription(getDescription(r.getElementId()));
});
return recommendedElements;
}
private String getName(String elementId) {
return filter(elementId).getName();
}
private String getDescription(String elementId) {
return filter(elementId).getDescription();
}
private NamedStreamPipesEntity filter(String elementId) {
List allElements = getAll();
return allElements
.stream()
.filter(a -> a.getElementId().equals(elementId))
.findFirst()
.get();
}
private Float getWeight(Integer count, Integer allConnectionsCount) {
return ((float) (count)) / allConnectionsCount;
}
private void validateSepas(String connectedTo) {
List sepas = getAllSepas();
for (DataProcessorDescription sepa : sepas) {
sepa = new DataProcessorDescription(sepa);
Pipeline tempPipeline = cloner.deepClone(pipeline);
DataProcessorInvocation newSepa = generateSepa(sepa, connectedTo);
tempPipeline.getSepas().add(newSepa);
validateConnection(tempPipeline, sepa);
tempPipeline.setSepas(new ArrayList<>());
}
}
private void validateSecs(String connectedTo) {
List secs = getAllSecs();
for (DataSinkDescription sec : secs) {
sec = new DataSinkDescription(sec);
Pipeline tempPipeline = cloner.deepClone(pipeline);
DataSinkInvocation newSec = generateSec(sec, connectedTo);
tempPipeline.getActions().add(newSec);
validateConnection(tempPipeline, sec);
tempPipeline.setSepas(new ArrayList<>());
}
}
private void validateConnection(Pipeline tempPipeline, NamedStreamPipesEntity currentElement) {
try {
new PipelineVerificationHandler(tempPipeline)
.validateConnection()
.getPipelineModificationMessage();
addPossibleElements(currentElement);
} catch (Exception e) {
//e.printStackTrace();
}
}
private DataProcessorInvocation generateSepa(DataProcessorDescription sepa, String connectedTo) {
DataProcessorInvocation invocation = new DataProcessorInvocation(sepa);
invocation.setConnectedTo(Utils.createList(connectedTo));
invocation.setDOM(RandomStringUtils.randomAlphanumeric(5));
return invocation;
}
private DataSinkInvocation generateSec(DataSinkDescription sec, String connectedTo) {
DataSinkInvocation invocation = new DataSinkInvocation(sec);
invocation.setConnectedTo(Utils.createList(connectedTo));
invocation.setDOM(RandomStringUtils.randomAlphanumeric(5));
return invocation;
}
private void addPossibleElements(NamedStreamPipesEntity sepa) {
recommendationMessage.addPossibleElement(new PipelineElementRecommendation(sepa.getElementId().toString(), sepa.getName(), sepa.getDescription()));
}
private List getAllSepas() {
List userObjects = UserManagementService.getUserService().getOwnSepaUris(email);
return StorageManager
.INSTANCE
.getStorageAPI()
.getAllSEPAs()
.stream()
.filter(e -> userObjects.stream().anyMatch(u -> u.equals(e.getElementId())))
.collect(Collectors.toList());
}
private List getAllSecs() {
List userObjects = UserManagementService.getUserService().getOwnActionUris(email);
return StorageManager
.INSTANCE
.getStorageAPI()
.getAllSECs()
.stream()
.filter(e -> userObjects.stream().anyMatch(u -> u.equals(e.getElementId())))
.collect(Collectors.toList());
}
private List getAll() {
List allElements = new ArrayList<>();
allElements.addAll(getAllSepas());
allElements.addAll(getAllSecs());
return allElements;
}
private InvocableStreamPipesEntity getRootNode() throws NoSepaInPipelineException {
return PipelineVerificationUtils.getRootNode(pipeline);
}
private INoSqlStorage getNoSqlStorage() {
return StorageDispatcher.INSTANCE.getNoSqlStore();
}
}