![JAR search and dependency download from the Maven repository](/logo.png)
org.apache.geode.deployment.internal.legacy.LegacyJarDeploymentService Maven / Gradle / Ivy
/*
* 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 org.apache.geode.deployment.internal.legacy;
import java.io.File;
import java.io.IOException;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.logging.log4j.Logger;
import org.apache.geode.annotations.Experimental;
import org.apache.geode.cache.CacheClosedException;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.internal.execute.FunctionToFileTracker;
import org.apache.geode.deployment.internal.DeployedJar;
import org.apache.geode.deployment.internal.JarDeployer;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.deployment.JarDeploymentService;
import org.apache.geode.logging.internal.log4j.api.LogService;
import org.apache.geode.management.configuration.Deployment;
import org.apache.geode.management.internal.utils.JarFileUtils;
import org.apache.geode.pdx.internal.TypeRegistry;
import org.apache.geode.services.result.ServiceResult;
import org.apache.geode.services.result.impl.Failure;
import org.apache.geode.services.result.impl.Success;
/**
* Implementation of {@link JarDeploymentService} that encapsulates the standard method of deploying
* jars by delegating to the {@link JarDeployer}.
*
* @since Geode 1.15
*/
@Experimental
public class LegacyJarDeploymentService implements JarDeploymentService {
private static final Logger logger = LogService.getLogger();
private final Map deployments = new ConcurrentHashMap<>();
private final FunctionToFileTracker functionToFileTracker = new FunctionToFileTracker();
private JarDeployer jarDeployer = new JarDeployer();
@Override
public synchronized ServiceResult deploy(Deployment deployment) {
try {
DeployedJar deployedJar = jarDeployer.deploy(deployment.getFile());
// This means that the jars are already deployed, so we call it a Success.
if (deployedJar == null) {
logger.info("Jar already been deployed: {}", deployment);
// null is returned when already deployed to satisfy existing public API constraints
return Success.of(null);
} else {
// This will only iterate once since deploy is given a singleton list.
logger.debug("Adding Deployment: {} with DeployedJar: {}", deployment, deployedJar);
Deployment deploymentCopy = new Deployment(deployment, deployedJar.getFile());
deploymentCopy.setDeployedTime(Instant.now().toString());
deployments.put(JarFileUtils.getArtifactId(deploymentCopy.getFileName()), deploymentCopy);
logger.debug("Deployments List size after add: {}", deployments.size());
logger.debug("Deployment copy to return: {}", deploymentCopy);
try {
functionToFileTracker.registerFunctionsFromFile(deploymentCopy.getFile());
} catch (ClassNotFoundException | IOException e) {
jarDeployer.undeploy(JarFileUtils.getArtifactId(deployment.getFileName()));
return Failure.of(e);
}
return Success.of(deploymentCopy);
}
} catch (IOException | ClassNotFoundException e) {
return Failure.of(e);
} finally {
flushCaches();
}
}
@Override
public ServiceResult deploy(File file) {
return deploy(createDeployment(file));
}
@Override
public synchronized ServiceResult undeployByFileName(String fileName) {
try {
logger.debug("Deployments List size before undeploy: {}", deployments.size());
logger.debug("File being undeployed: {}", fileName);
jarDeployer.deleteAllVersionsOfJar(fileName);
String artifactId = JarFileUtils.getArtifactId(fileName);
Deployment deployment = deployments.get(artifactId);
if (deployment == null || !deployment.getFileName().equals(fileName)) {
return Failure.of(fileName + " not deployed");
}
Deployment removedDeployment = deployments.remove(artifactId);
logger.debug("Removed Deployment: {}", removedDeployment);
logger.debug("Deployments List size after remove: {}", deployments.size());
String undeployedPath =
jarDeployer.undeploy(JarFileUtils.getArtifactId(removedDeployment.getFileName()));
logger.debug("Jar at path: {} removed by JarDeployer", undeployedPath);
functionToFileTracker.unregisterFunctionsForDeployment(removedDeployment.getFileName());
return Success.of(removedDeployment);
} catch (IOException e) {
return Failure.of(e);
} finally {
flushCaches();
}
}
@Override
public List listDeployed() {
return Collections.unmodifiableList(new LinkedList<>(deployments.values()));
}
@Override
public ServiceResult getDeployed(String fileName) {
logger.debug("Looking up Deployment for name: {}", fileName);
logger.debug("Deployments keySet: {}", Arrays.toString(deployments.keySet().toArray()));
String artifactId = JarFileUtils.getArtifactId(fileName);
if (deployments.containsKey(artifactId)) {
return Success.of(deployments.get(artifactId));
} else {
return Failure.of(fileName + " is not deployed.");
}
}
@Override
public void reinitializeWithWorkingDirectory(File workingDirectory) {
logger.info("Reinitializing JarDeploymentService with new working directory: {}",
workingDirectory);
if (deployments.isEmpty()) {
jarDeployer = new JarDeployer(workingDirectory);
} else {
throw new RuntimeException(
"Cannot reinitialize working directory with existing deployments. Please undeploy first.");
}
}
@Override
public void loadJarsFromWorkingDirectory() {
logger.debug("Loading jars from Working Directory");
Map latestVersionOfJarsOnDisk = jarDeployer.getLatestVersionOfJarsOnDisk();
try {
List deploymentList = new LinkedList<>();
for (Map.Entry entry : latestVersionOfJarsOnDisk.entrySet()) {
DeployedJar deployedJar = entry.getValue();
jarDeployer.registerNewVersions(entry.getKey(), deployedJar);
logger.debug("Deploying DeployedJar: {} from working directory", deployedJar);
Deployment deployment = createDeployment(deployedJar);
deploymentList.add(deployment);
deployments.put(JarFileUtils.toArtifactId(deployment.getFileName()), deployment);
}
for (Deployment deployment : deploymentList) {
functionToFileTracker.registerFunctionsFromFile(deployment.getFile());
}
} catch (ClassNotFoundException | IOException e) {
logger.error(e);
throw new RuntimeException(e);
} finally {
flushCaches();
}
}
@Override
public void close() {
String[] jarNames = deployments.keySet().toArray(new String[] {});
logger.debug(
"Closing LegacyJarDeploymentService. The following Deployments will be removed: {}",
Arrays.toString(jarNames));
for (String jarName : jarNames) {
undeployByFileName(jarName);
}
}
private Deployment createDeployment(DeployedJar deployedJar) {
Deployment deployment = new Deployment(deployedJar.getArtifactId(), "",
Instant.ofEpochMilli(deployedJar.getFile().lastModified()).toString());
deployment.setFile(deployedJar.getFile());
return deployment;
}
private Deployment createDeployment(File deployedJar) {
Deployment deployment = new Deployment(deployedJar.getName(), "",
Instant.ofEpochMilli(deployedJar.lastModified()).toString());
deployment.setFile(deployedJar);
return deployment;
}
/**
* Flush the type registry after possibly receiving new types or having old types replaced.
*/
private synchronized void flushCaches() {
try {
TypeRegistry typeRegistry = ((InternalCache) CacheFactory.getAnyInstance()).getPdxRegistry();
if (typeRegistry != null) {
typeRegistry.flushCache();
}
} catch (CacheClosedException ignored) {
// That's okay, it just means there was nothing to flush to begin with
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy