Java tutorial
/** * Copyright 2014 Otto (GmbH & Co KG) * * 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.ottogroup.bi.asap.node.server; import io.dropwizard.Application; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.InetAddress; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.ottogroup.bi.asap.exception.RemoteClientConnectionFailedException; import com.ottogroup.bi.asap.exception.RequiredInputMissingException; import com.ottogroup.bi.asap.message.registration.ProcessingNodeRegistration.ProcessingNodeRegistrationResponse; import com.ottogroup.bi.asap.message.registration.ProcessingNodeRegistration.ProcessingNodeRegistrationState; import com.ottogroup.bi.asap.node.resource.AsapResourceManagerClient; import com.ottogroup.bi.asap.node.resource.pipeline.PipelineResource; import com.ottogroup.bi.asap.node.server.configuration.ApplicationRepositoryConfiguration; import com.ottogroup.bi.asap.node.server.configuration.AsapProcessingNodeConfiguration; import com.ottogroup.bi.asap.pipeline.MicroPipelineManager; import com.ottogroup.bi.asap.repository.ComponentDescriptor; import com.ottogroup.bi.asap.repository.ComponentRepository; /** * Core component ramping up the asap processing node * @author mnxfst * @since Nov 26, 2014 */ public class AsapProcessingNodeServer extends Application<AsapProcessingNodeConfiguration> { /** our faithful logging facility ;-) */ private static final Logger logger = Logger.getLogger(AsapProcessingNodeServer.class); /** pipeline manager */ private MicroPipelineManager pipelineManager; /** resource manager client */ private AsapResourceManagerClient resourceManagerClient; /** * @see io.dropwizard.Application#initialize(io.dropwizard.setup.Bootstrap) */ public void initialize(Bootstrap<AsapProcessingNodeConfiguration> bootstrap) { } /** * @see io.dropwizard.Application#run(io.dropwizard.Configuration, io.dropwizard.setup.Environment) */ public void run(AsapProcessingNodeConfiguration configuration, Environment environment) throws Exception { PropertyConfigurator.configure(configuration.getLog4jConfiguration()); this.pipelineManager = new MicroPipelineManager( loadAndDeployApplicationRepository(configuration.getApplicationRepository())); environment.jersey().register(new PipelineResource(this.pipelineManager)); this.resourceManagerClient = new AsapResourceManagerClient(configuration.getResourceManagerConfiguration()); try { ProcessingNodeRegistrationResponse registrationResponse = this.resourceManagerClient .registerProcessingNode(InetAddress.getLocalHost().getHostName(), configuration.getServicePort(), configuration.getAdminPort()); if (registrationResponse == null) { logger.error( "Failed to register processing node with remote resource manager. Error: no response received. Processing node operates in standalone mode"); } else { if (registrationResponse.getState() != ProcessingNodeRegistrationState.OK) throw new RuntimeException( "[error=" + registrationResponse.getState() + "] " + registrationResponse.getMessage()); } } catch (RemoteClientConnectionFailedException e) { logger.error( "Failed to register processing node with remote resource manager. Error: no response received. Processing node operates in standalone mode"); } } /** * Reads contents from {@link ApplicationRepositoryConfiguration referenced repository} and deploys them to given * {@link ActorRef deployment receiver}. * @param cfg * @param jarDeploymentReceiverRef * @throws RequiredInputMissingException * @throws JsonParseException * @throws JsonMappingException * @throws IOException */ public ComponentRepository loadAndDeployApplicationRepository(final ApplicationRepositoryConfiguration cfg) throws RequiredInputMissingException, JsonParseException, JsonMappingException, IOException { //////////////////////////////////////////////////////////////////////////// // validate provided input and ensure that folder exists if (cfg == null) throw new RequiredInputMissingException("Missing required input for parameter 'cfg'"); if (StringUtils.isBlank(cfg.getRepositoryPath())) throw new RequiredInputMissingException("Missing required input for parameter 'repositoryPath'"); File repositoryFolder = new File(cfg.getRepositoryPath()); if (repositoryFolder == null || !repositoryFolder.isDirectory()) throw new RequiredInputMissingException( "No repository found at provided folder '" + cfg.getRepositoryPath() + "'"); // //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// final ComponentRepository library = new ComponentRepository(); //////////////////////////////////////////////////////////////////////////// // find component repositories below repository folder File[] repoFolders = repositoryFolder.listFiles(); if (repoFolders == null || repoFolders.length < 1) return library; // //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// // for each entry check if it is a folder and pass it on the library int folderCount = 0; int componentsCount = 0; for (File folder : repoFolders) { if (folder.isDirectory()) { try { logger.info("Processing folder '" + folder.getAbsolutePath() + "'"); Map<String, ComponentDescriptor> descriptors = library .addComponentFolder(folder.getAbsolutePath()); componentsCount = componentsCount + descriptors.size(); folderCount++; } catch (Exception e) { logger.error("Failed to add folder '" + folder.getAbsolutePath() + "' to component repository. Error: " + e.getMessage()); } } } // //////////////////////////////////////////////////////////////////////////// logger.info("Components deployment finished [repo=" + cfg.getRepositoryPath() + ", componentFolders=" + folderCount + ", componets=" + componentsCount + "]"); return library; } /** * Reads the contents from the referenced files and returns them as array of bytes * @param fileName * @return * @throws IOException */ protected byte[] readFileContents(final String fileName) throws IOException, RequiredInputMissingException { if (StringUtils.isBlank(fileName)) throw new RequiredInputMissingException("Missing required input for parameter 'fileName'"); /////////////////////////////////////////////////////////////////////////////////// // read repo file contents BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileName)); int read = 0; final ByteArrayOutputStream os = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; // buffer size while ((read = bis.read(buffer)) != -1) { os.write(buffer, 0, read); } bis.close(); // /////////////////////////////////////////////////////////////////////////////////// return os.toByteArray(); } /** * Run the server component * @param args */ public static void main(String[] args) throws Exception { new AsapProcessingNodeServer().run(args); } }