/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 gobblin.spec_catalog; import java.io.File; import java.net.URI; import java.util.Collection; import java.util.Properties; import org.apache.commons.io.FileUtils; import org.apache.hadoop.fs.Path; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import com.google.common.base.Optional; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.typesafe.config.Config; import gobblin.runtime.api.Spec; import gobblin.runtime.api.SpecExecutorInstanceProducer; import gobblin.runtime.api.TopologySpec; import gobblin.runtime.app.ServiceBasedAppLauncher; import gobblin.runtime.spec_catalog.TopologyCatalog; import gobblin.runtime.spec_executorInstance.InMemorySpecExecutorInstanceProducer; import gobblin.util.ConfigUtils; import gobblin.util.PathUtils; public class TopologyCatalogTest { private static final Logger logger = LoggerFactory.getLogger(TopologyCatalog.class); private static Gson gson = new GsonBuilder().setPrettyPrinting().create(); private static final String SPEC_STORE_PARENT_DIR = "/tmp"; private static final String SPEC_STORE_DIR = "/tmp/topologyTestSpecStore"; private static final String SPEC_DESCRIPTION = "Test Topology Spec"; private static final String SPEC_VERSION = "1"; private ServiceBasedAppLauncher serviceLauncher; private TopologyCatalog topologyCatalog; private TopologySpec topologySpec; @BeforeClass public void setup() throws Exception { File specStoreDir = new File(SPEC_STORE_DIR); if (specStoreDir.exists()) { FileUtils.deleteDirectory(specStoreDir); } Properties properties = new Properties(); properties.put("specStore.fs.dir", SPEC_STORE_DIR); this.serviceLauncher = new ServiceBasedAppLauncher(properties, "TopologyCatalogTest"); this.topologyCatalog = new TopologyCatalog(ConfigUtils.propertiesToConfig(properties), Optional.of(logger)); this.serviceLauncher.addService(topologyCatalog); // Start Catalog this.serviceLauncher.start(); // Create Spec to play with this.topologySpec = initTopologySpec(); } private TopologySpec initTopologySpec() { Properties properties = new Properties(); properties.put("specStore.fs.dir", SPEC_STORE_DIR); properties.put("specExecInstance.capabilities", "source:destination"); Config config = ConfigUtils.propertiesToConfig(properties); SpecExecutorInstanceProducer specExecutorInstanceProducer = new InMemorySpecExecutorInstanceProducer(config); TopologySpec.Builder topologySpecBuilder = TopologySpec.builder(computeTopologySpecURI()) .withConfig(config) .withDescription(SPEC_DESCRIPTION) .withVersion(SPEC_VERSION) .withSpecExecutorInstanceProducer(specExecutorInstanceProducer); return topologySpecBuilder.build(); } @AfterClass public void cleanUp() throws Exception { // Shutdown Catalog this.serviceLauncher.stop(); File specStoreDir = new File(SPEC_STORE_DIR); if (specStoreDir.exists()) { FileUtils.deleteDirectory(specStoreDir); } } @Test public void createTopologySpec() { // List Current Specs Collection<Spec> specs = topologyCatalog.getSpecs(); logger.info("[Before Create] Number of specs: " + specs.size()); int i=0; for (Spec spec : specs) { TopologySpec topologySpec = (TopologySpec) spec; logger.info("[Before Create] Spec " + i++ + ": " + gson.toJson(topologySpec)); } Assert.assertTrue(specs.size() == 0, "Spec store should be empty before addition"); // Create and add Spec this.topologyCatalog.put(topologySpec); // List Specs after adding specs = topologyCatalog.getSpecs(); logger.info("[After Create] Number of specs: " + specs.size()); i = 0; for (Spec spec : specs) { topologySpec = (TopologySpec) spec; logger.info("[After Create] Spec " + i++ + ": " + gson.toJson(topologySpec)); } Assert.assertTrue(specs.size() == 1, "Spec store should contain 1 Spec after addition"); } @Test (dependsOnMethods = "createTopologySpec") public void deleteTopologySpec() { // List Current Specs Collection<Spec> specs = topologyCatalog.getSpecs(); logger.info("[Before Delete] Number of specs: " + specs.size()); int i=0; for (Spec spec : specs) { TopologySpec topologySpec = (TopologySpec) spec; logger.info("[Before Delete] Spec " + i++ + ": " + gson.toJson(topologySpec)); } Assert.assertTrue(specs.size() == 1, "Spec store should initially have 1 Spec before deletion"); this.topologyCatalog.remove(topologySpec.getUri()); // List Specs after adding specs = topologyCatalog.getSpecs(); logger.info("[After Create] Number of specs: " + specs.size()); i = 0; for (Spec spec : specs) { topologySpec = (TopologySpec) spec; logger.info("[After Create] Spec " + i++ + ": " + gson.toJson(topologySpec)); } Assert.assertTrue(specs.size() == 0, "Spec store should be empty after deletion"); } public URI computeTopologySpecURI() { // Make sure this is relative URI uri = PathUtils.relativizePath(new Path(SPEC_STORE_DIR), new Path(SPEC_STORE_PARENT_DIR)).toUri(); return uri; } }