| /******************************************************************************** |
| * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation |
| * |
| * See the NOTICE file(s) distributed with this work for additional |
| * information regarding copyright ownership. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| ********************************************************************************/ |
| package org.eclipse.mdm.apicopy.boundary; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.util.Comparator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.ejb.Stateless; |
| import javax.inject.Inject; |
| import javax.ws.rs.core.Response; |
| |
| import org.eclipse.mdm.api.base.ConnectionException; |
| import org.eclipse.mdm.api.base.ServiceNotProvidedException; |
| import org.eclipse.mdm.api.dflt.ApplicationContext; |
| import org.eclipse.mdm.api.dflt.ApplicationContextFactory; |
| import org.eclipse.mdm.api.dflt.EntityManager; |
| import org.eclipse.mdm.api.dflt.model.Project; |
| import org.eclipse.mdm.apicopy.control.ApiCopyException; |
| import org.eclipse.mdm.apicopy.control.ApiCopyService; |
| import org.eclipse.mdm.apicopy.control.ApiCopyServiceImpl; |
| import org.eclipse.mdm.apicopy.entity.CopyStatusResponse; |
| import org.eclipse.mdm.apicopy.entity.CopyStatusResponse.State; |
| import org.eclipse.mdm.connector.boundary.ConnectorService; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.google.common.base.Function; |
| import com.google.common.collect.ImmutableMap; |
| |
| /** |
| * Service for importing an ATFX file into a MDM datasource. |
| * |
| */ |
| @Stateless |
| public class ImportService { |
| |
| private static final Logger LOG = LoggerFactory.getLogger(ImportService.class); |
| |
| // TODO make temp path configurable |
| private static final Path TMP = Paths.get(System.getProperty("java.io.tmpdir")); |
| |
| @Inject |
| private ConnectorService connectorService; |
| |
| private ApiCopyService apiCopyService = new ApiCopyServiceImpl(); |
| |
| private final String atfxContextFactoryClassname = "org.eclipse.mdm.api.atfxadapter.ATFXContextFactory"; |
| |
| /** |
| * Default public constructor |
| */ |
| public ImportService() { |
| } |
| |
| /** |
| * Imports an ATFX file into the provided datasource. |
| * |
| * @param atfxFileSupplier returns a {@link Path} to an ATFX file. Accompanying |
| * binary files are expected to be on the same folder. |
| * @param dstContextName target datasource of the import |
| * @return |
| */ |
| public Response importAtfx(Function<Path, Path> atfxFileSupplier, String dstContextName) { |
| ApplicationContext contextDst = connectorService.getContextByName(dstContextName); |
| ApplicationContext contextSrc = null; |
| |
| Path tmpDir = null; |
| try { |
| tmpDir = Files.createTempDirectory(TMP, "atfximport"); |
| |
| Path atfxFile = atfxFileSupplier.apply(tmpDir); |
| |
| Map<String, String> params = ImmutableMap.of("atfxfile", atfxFile.toFile().getAbsolutePath(), |
| "freetext.active", "false"); |
| |
| contextSrc = connectContext(atfxContextFactoryClassname, params); |
| List<Project> projects = contextSrc.getEntityManager() |
| .orElseThrow(() -> new ServiceNotProvidedException(EntityManager.class)).loadAll(Project.class); |
| |
| apiCopyService.newApiCopyTask(contextSrc, contextDst).copy(projects); |
| |
| CopyStatusResponse response = new CopyStatusResponse(); |
| response.setState(State.OK); |
| return Response.ok(response).build(); |
| } catch (ServiceNotProvidedException e) { |
| throw new ApiCopyException("Could not retrive all required services from ATFX application context!", e); |
| } catch (ConnectionException e) { |
| throw new ApiCopyException("Could not create ATFX application context!", e); |
| } catch (IOException e) { |
| throw new ApiCopyException("Cold not create temporary directory!", e); |
| } finally { |
| if (contextSrc != null) { |
| try { |
| contextSrc.close(); |
| } catch (ConnectionException e) { |
| LOG.warn("Could not close application context!", e); |
| } |
| } |
| if (tmpDir != null) { |
| try { |
| deleteDirectory(tmpDir); |
| } catch (IOException e) { |
| LOG.warn("Could not delete temporary directory " + tmpDir.toFile().getAbsolutePath(), e); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Deletes a directory. |
| * |
| * @param pathToBeDeleted directory to delete |
| * @throws IOException |
| */ |
| private void deleteDirectory(java.nio.file.Path pathToBeDeleted) throws IOException { |
| Files.walk(pathToBeDeleted).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); |
| } |
| |
| /** |
| * Connects to a {@link ApplicationContext}. |
| * |
| * @param contextFactoryClassname classname of the |
| * {@link ApplicationContextFactory} |
| * @param parameters connection parameters |
| * @return connected {@link ApplicationContext} |
| * @throws ConnectionException |
| */ |
| private ApplicationContext connectContext(String contextFactoryClassname, Map<String, String> parameters) |
| throws ConnectionException { |
| try { |
| |
| Class<? extends ApplicationContextFactory> contextFactoryClass = Thread.currentThread() |
| .getContextClassLoader().loadClass(contextFactoryClassname) |
| .asSubclass(ApplicationContextFactory.class); |
| |
| ApplicationContextFactory contextFactory = contextFactoryClass.newInstance(); |
| return contextFactory.connect(parameters); |
| } catch (Exception e) { |
| throw new ConnectionException( |
| "failed to initialize entity manager using factory '" + contextFactoryClassname + "'", e); |
| } |
| } |
| } |