Skip to content

Commit

Permalink
Dhfprod 1718 process manager (#1790)
Browse files Browse the repository at this point in the history
* Add a method to return all of the ProcessTypes

* Add interface for ProcessManager

* Update Process interface

* Add ProcessManager class for handling Processes

* Add tests for ProcessManager class

* Update HubProject to have a single getProcessDir method

* Update Process model class and test docs to better conform to the model
  • Loading branch information
akshaysonvane authored and aebadirad committed Jan 24, 2019
1 parent 58a83a0 commit b7ceb9a
Show file tree
Hide file tree
Showing 14 changed files with 517 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.marklogic.client.DatabaseClient;
import com.marklogic.client.DatabaseClientFactory;
import com.marklogic.hub.impl.HubConfigImpl;
import com.marklogic.hub.processes.Process;

import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;
Expand Down Expand Up @@ -408,6 +409,8 @@ public interface HubConfig {
*/
Path getHubMappingsDir();

Path getProcessDir(Process.ProcessType type);

/**
* Gets the path for the hub's config directory
* @return the path for the hub's config directory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@

package com.marklogic.hub;

import com.marklogic.hub.impl.HubProjectImpl;
import org.springframework.core.io.ProtocolResolver;
import com.marklogic.hub.processes.Process;

import java.io.IOException;
import java.nio.file.Path;
Expand Down Expand Up @@ -48,6 +47,8 @@ public interface HubProject {
*/
Path getHubPluginsDir();

Path getProcessesDir();

/**
* Gets the path for the hub entities directory
*
Expand All @@ -62,6 +63,8 @@ public interface HubProject {
*/
Path getHubMappingsDir();

Path getProcessDir(Process.ProcessType type);

/**
* Gets the path for the hub's config directory
*
Expand Down Expand Up @@ -210,6 +213,7 @@ public interface HubProject {

/**
* Returns the base directory for this project
*
* @return the project's directory as a Path
*/
Path getProjectDir();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2012-2019 MarkLogic Corporation
*
* 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.marklogic.hub;

import com.fasterxml.jackson.databind.JsonNode;
import com.marklogic.hub.processes.Process;

import java.util.ArrayList;

public interface ProcessManager {

/**
* String value for the mapping file extension
*/
String PROCESSES_FILE_EXTENSION = ".processes.json";

/**
* Saves a Process to disk
*
* @param process - the Process object to be saved
*/
void saveProcess(Process process);

/**
* Deletes a Process from disk
*
* @param process - the Process object to be deleted
*/
void deleteProcess(Process process);

/**
* Returns a list of all Processes currently defined
*
* @return - an ArrayList of all Process objects from disk
*/
ArrayList<Process> getProcesses();

/**
* Returns a single Process given a name and a type
*
* @param name - name of the Process
* @param type - type of the Process
* @return the Process object
*/
Process getProcess(String name, Process.ProcessType type);

/**
* Returns a list of Processes that have the given type
*
* @param type - type of the Process
* @return an ArrayList of Process objects of a given type
*/
ArrayList<Process> getProcessesByType(Process.ProcessType type);

/**
* Returns a list of Process names that have the given type
*
* @param type - type of the Process
* @return an ArrayList of Process names of a given type
*/
ArrayList<String> getProcessNamesByType(Process.ProcessType type);

/**
* Creates a Process from a given JsonNode
*
* @param json - a JsonNode
* @return a Process object
*/
Process createProcessFromJSON(JsonNode json);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.marklogic.hub.error.DataHubConfigurationException;
import com.marklogic.hub.error.DataHubProjectException;
import com.marklogic.hub.error.InvalidDBOperationError;
import com.marklogic.hub.processes.Process;
import com.marklogic.mgmt.DefaultManageConfigFactory;
import com.marklogic.mgmt.ManageClient;
import com.marklogic.mgmt.ManageConfig;
Expand Down Expand Up @@ -807,7 +808,7 @@ public String getMlUsername() {
public String getMlPassword() {
return mlPassword;
}

public void setMlUsername(String mlUsername) {
this.mlUsername = mlUsername;
}
Expand Down Expand Up @@ -1282,7 +1283,7 @@ public void loadConfigurationFromProperties(Properties properties, boolean loadG
else {
projectProperties.setProperty("mlHubUserName", hubUserName);
}

if (hubAdminRoleName == null) {
hubAdminRoleName = getEnvPropString(projectProperties, "mlHubAdminRole", environment.getProperty("mlHubAdminRole"));
}
Expand Down Expand Up @@ -1531,6 +1532,12 @@ public DatabaseClient newModulesDbClient() {
@JsonIgnore
@Override public Path getHubMappingsDir() { return hubProject.getHubMappingsDir(); }

@JsonIgnore
@Override
public Path getProcessDir(Process.ProcessType type) {
return hubProject.getProcessDir(type);
}

@JsonIgnore
@Override public Path getHubConfigDir() {
return hubProject.getHubConfigDir();
Expand Down Expand Up @@ -1759,7 +1766,7 @@ private void updateAppConfig(AppConfig config) {
*
* But if the config paths have been customized - most likely via mlConfigPaths in gradle.properties - then this
* method just ensures that they're relative to the DHF project directory.
*
*
* @param config
*/
protected void initializeConfigDirs(AppConfig config) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.marklogic.hub.HubProject;
import com.marklogic.hub.error.DataHubProjectException;
import com.marklogic.hub.processes.Process;
import com.marklogic.hub.util.FileUtil;
import com.marklogic.rest.util.JsonNodeUtil;

Expand Down Expand Up @@ -63,6 +65,7 @@ public class HubProjectImpl implements HubProject {
private String projectDirString;
private Path projectDir;
private Path pluginsDir;
private Path processesDir;

protected final Logger logger = LoggerFactory.getLogger(this.getClass());

Expand All @@ -77,12 +80,39 @@ public void createProject(String projectDirString) {
this.projectDirString = projectDirString;
this.projectDir = Paths.get(projectDirString).toAbsolutePath();
this.pluginsDir = this.projectDir.resolve("plugins");
this.processesDir = this.projectDir.resolve("processes");
}

@Override public Path getHubPluginsDir() {
return this.pluginsDir;
}

@Override
public Path getProcessesDir() {
return this.processesDir;
}

@Override
public Path getProcessDir(Process.ProcessType type) {
Path path;

switch (type) {
case CUSTOM:
path = this.processesDir.resolve("custom");
break;
case INGEST:
path = this.processesDir.resolve("ingest");
break;
case MAPPING:
path = this.processesDir.resolve("mapping");
break;
default:
throw new DataHubProjectException("Invalid Process path");
}

return path;
}

@Override public Path getHubEntitiesDir() {
return this.pluginsDir.resolve("entities");
}
Expand Down Expand Up @@ -185,6 +215,7 @@ public void createProject(String projectDirString) {

@Override public void init(Map<String, String> customTokens) {
this.pluginsDir.toFile().mkdirs();
this.processesDir.toFile().mkdirs();

Path userModules = this.projectDir.resolve(MODULES_DIR);
userModules.toFile().mkdirs();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Copyright 2012-2019 MarkLogic Corporation
*
* 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.marklogic.hub.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.marklogic.hub.HubConfig;
import com.marklogic.hub.ProcessManager;
import com.marklogic.hub.error.DataHubProjectException;
import com.marklogic.hub.processes.Process;
import com.marklogic.hub.util.FileUtil;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;

@Component
public class ProcessManagerImpl implements ProcessManager {

@Autowired
private HubConfig hubConfig;

@Override
public void saveProcess(Process process) {
try {
String processString = process.serialize();
Path dir = resolvePath(hubConfig.getProcessDir(process.getType()), process.getName());
if (!dir.toFile().exists()) {
dir.toFile().mkdirs();
}
String processFileName = process.getName() + PROCESSES_FILE_EXTENSION;
File file = Paths.get(dir.toString(), processFileName).toFile();
//create the object mapper to pretty print to disk
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
Object json = objectMapper.readValue(processString, Object.class);
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(json).getBytes());
fileOutputStream.flush();
fileOutputStream.close();
}
catch (JsonProcessingException e) {
throw new DataHubProjectException("Could not serialize Process for project.");
}
catch (IOException e) {
throw new DataHubProjectException("Could not write Process to disk for project.");
}
}

@Override
public void deleteProcess(Process process) {
Path dir = resolvePath(hubConfig.getProcessDir(process.getType()), process.getName());
if (dir.toFile().exists()) {
try {
FileUtils.deleteDirectory(dir.toFile());
}
catch (IOException e) {
throw new DataHubProjectException("Could not delete Process for project.");
}
}
}

@Override
public ArrayList<Process> getProcesses() {
ArrayList<Process> processList = new ArrayList<>();
for (Process.ProcessType processType : Process.ProcessType.getProcessTypes()) {
for (String name : getProcessNamesByType(processType)) {
processList.add(getProcess(name, processType));
}
}
return processList;
}

@Override
public Process getProcess(String name, Process.ProcessType type) {
Path processPath = resolvePath(hubConfig.getProcessDir(type), name);

try {
String targetFileName = name + PROCESSES_FILE_EXTENSION;
FileInputStream fileInputStream = new FileInputStream(processPath.resolve(targetFileName).toFile());
ObjectMapper objectMapper = new ObjectMapper();
JsonNode node = objectMapper.readTree(fileInputStream);
Process newProcess = createProcessFromJSON(node);
if (newProcess != null && newProcess.getName().length() > 0) {
return newProcess;
}
}
catch (IOException e) {
throw new DataHubProjectException("Could not read mapping on disk.");
}

return null;
}

@Override
public ArrayList<Process> getProcessesByType(Process.ProcessType type) {
ArrayList<Process> processList = new ArrayList<>();
for (String name : getProcessNamesByType(type)) {
processList.add(getProcess(name, type));
}
return processList;
}

@Override
public ArrayList<String> getProcessNamesByType(Process.ProcessType type) {
return (ArrayList<String>) FileUtil.listDirectFolders(hubConfig.getProcessDir(type));
}

@Override
public Process createProcessFromJSON(JsonNode json) {
Process process = Process.create("default", Process.ProcessType.INGEST);
process.deserialize(json);
return process;
}

private Path resolvePath(Path path, String more) {
return path.resolve(more);
}
}
Loading

0 comments on commit b7ceb9a

Please sign in to comment.