/* * Copyright (c) Bosch Software Innovations GmbH 2016. * With modifications by Siemens AG, 2016. * Part of the SW360 Portal Project. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.eclipse.sw360.cvesearch.service; import org.eclipse.sw360.cvesearch.datasink.VulnerabilityConnector; import org.eclipse.sw360.cvesearch.datasource.CveSearchApiImpl; import org.eclipse.sw360.cvesearch.datasource.CveSearchData; import org.eclipse.sw360.cvesearch.datasource.CveSearchWrapper; import org.eclipse.sw360.cvesearch.entitytranslation.CveSearchDataTranslator; import org.eclipse.sw360.datahandler.common.CommonUtils; import org.eclipse.sw360.datahandler.thrift.RequestStatus; import org.eclipse.sw360.datahandler.thrift.components.Component; import org.eclipse.sw360.datahandler.thrift.components.Release; import org.eclipse.sw360.datahandler.thrift.cvesearch.CveSearchService; import org.eclipse.sw360.datahandler.thrift.cvesearch.UpdateType; import org.eclipse.sw360.datahandler.thrift.cvesearch.VulnerabilityUpdateStatus; import org.eclipse.sw360.datahandler.thrift.projects.Project; import org.apache.log4j.Logger; import org.apache.thrift.TException; import java.io.IOException; import java.util.*; import java.util.stream.Collectors; import static org.eclipse.sw360.cvesearch.helper.VulnerabilityUtils.*; public class CveSearchHandler implements CveSearchService.Iface { public static final String CVESEARCH_HOST_PROPERTY = "cvesearch.host"; VulnerabilityConnector vulnerabilityConnector; CveSearchWrapper cveSearchWrapper; Logger log = Logger.getLogger(CveSearchHandler.class); public CveSearchHandler() { try { vulnerabilityConnector = new VulnerabilityConnector(); } catch (IOException ioe) { log.error("Exception when creating CveSearchHandler", ioe); } Properties props = CommonUtils.loadProperties(CveSearchHandler.class, "/cvesearch.properties"); String host = props.getProperty(CVESEARCH_HOST_PROPERTY, "https://localhost:5000"); cveSearchWrapper = new CveSearchWrapper(new CveSearchApiImpl(host)); } public VulnerabilityUpdateStatus updateForRelease(Release release) { Optional<List<CveSearchData>> cveSearchDatas = cveSearchWrapper.searchForRelease(release); if(!cveSearchDatas.isPresent()) { return new VulnerabilityUpdateStatus().setRequestStatus(RequestStatus.FAILURE); } CveSearchDataTranslator cveSearchDataTranslator = new CveSearchDataTranslator(); List<CveSearchDataTranslator.VulnerabilityWithRelation> translated = cveSearchDatas.get().stream() .map(cveSearchData -> cveSearchDataTranslator.apply(cveSearchData)) .map(vulnerabilityWithRelation -> { vulnerabilityWithRelation.relation.setReleaseId(release.getId()); return vulnerabilityWithRelation; }) .collect(Collectors.toList()); VulnerabilityUpdateStatus updateStatus = getEmptyVulnerabilityUpdateStatus(); for (CveSearchDataTranslator.VulnerabilityWithRelation vulnerabilityWithRelation : translated) { updateStatus = vulnerabilityConnector.addOrUpdate(vulnerabilityWithRelation.vulnerability, vulnerabilityWithRelation.relation, updateStatus); } return updateStatus; } @Override public VulnerabilityUpdateStatus updateForRelease(String releaseId) { Optional<Release> release = vulnerabilityConnector.getRelease(releaseId); Optional<VulnerabilityUpdateStatus> updateStatus = release.map(this::updateForRelease); return updateStatus.orElse(getEmptyVulnerabilityUpdateStatus(RequestStatus.FAILURE)); } @Override public VulnerabilityUpdateStatus updateForComponent(String componentId) throws TException { Optional<Component> component = vulnerabilityConnector.getComponent(componentId); return component.map( c -> c.isSetReleaseIds() ? c.getReleaseIds().stream() .map(this::updateForRelease) .reduce(getEmptyVulnerabilityUpdateStatus(), (r1, r2) -> reduceVulnerabilityUpdateStatus(r1,r2)) : getEmptyVulnerabilityUpdateStatus() ).orElse(getEmptyVulnerabilityUpdateStatus(RequestStatus.FAILURE)); } @Override public VulnerabilityUpdateStatus updateForProject(String projectId) throws TException { Optional<Project> project = vulnerabilityConnector.getProject(projectId); return project.map( r -> r.isSetReleaseIdToUsage() ? r.getReleaseIdToUsage().keySet().stream() .map(this::updateForRelease) .reduce(getEmptyVulnerabilityUpdateStatus(), (r1, r2) -> reduceVulnerabilityUpdateStatus(r1,r2)) : getEmptyVulnerabilityUpdateStatus() ).orElse(getEmptyVulnerabilityUpdateStatus(RequestStatus.FAILURE)); } @Override public VulnerabilityUpdateStatus fullUpdate() throws TException { List<Release> allReleases = vulnerabilityConnector.getAllReleases(); return allReleases.stream() .map(this::updateForRelease) .reduce(getEmptyVulnerabilityUpdateStatus(), (r1, r2) -> reduceVulnerabilityUpdateStatus(r1,r2)); } @Override public RequestStatus update() throws TException { VulnerabilityUpdateStatus vulnerabilityUpdateStatus = fullUpdate(); log.info("CveSearch update finished with status:" + vulnerabilityUpdateStatus.getRequestStatus()); log.info("The following vulnerability/ies could not be imported:" + vulnerabilityUpdateStatus.getStatusToVulnerabilityIds().get(UpdateType.FAILED) + "\n"+ "The following vulnerability/ies were updated:" + vulnerabilityUpdateStatus.getStatusToVulnerabilityIds().get(UpdateType.UPDATED) + "\n"+ "The following vulnerability/ies were added:" + vulnerabilityUpdateStatus.getStatusToVulnerabilityIds().get(UpdateType.NEW)); return vulnerabilityUpdateStatus.getRequestStatus(); } @Override public Set<String> findCpes(String vendor, String product, String version) throws TException { throw new UnsupportedOperationException("Not implemented yet."); } }