use of org.apache.pulsar.functions.runtime.kubernetes.KubernetesRuntimeFactory in project pulsar by apache.
the class FunctionsStatsGenerator method generate.
public static void generate(PulsarWorkerService workerService, SimpleTextOutputStream out) {
// only when worker service is initialized, we generate the stats. otherwise we will get bunch of NPE.
if (workerService != null && workerService.isInitialized()) {
try {
out.write(workerService.getWorkerStatsManager().getStatsAsString());
} catch (IOException e) {
log.warn("Encountered error when generating metrics for worker {}", workerService.getWorkerConfig().getWorkerId(), e);
}
// kubernetes runtime factory doesn't support stats collection through worker service
if (workerService.getFunctionRuntimeManager().getRuntimeFactory() instanceof KubernetesRuntimeFactory) {
return;
}
Map<String, FunctionRuntimeInfo> functionRuntimes = workerService.getFunctionRuntimeManager().getFunctionRuntimeInfos();
for (Map.Entry<String, FunctionRuntimeInfo> entry : functionRuntimes.entrySet()) {
String fullyQualifiedInstanceName = entry.getKey();
FunctionRuntimeInfo functionRuntimeInfo = entry.getValue();
RuntimeSpawner functionRuntimeSpawner = functionRuntimeInfo.getRuntimeSpawner();
if (functionRuntimeSpawner != null) {
Runtime functionRuntime = functionRuntimeSpawner.getRuntime();
if (functionRuntime != null) {
try {
String prometheusMetrics = functionRuntime.getPrometheusMetrics();
if (prometheusMetrics != null) {
out.write(prometheusMetrics);
}
} catch (IOException e) {
log.warn("Failed to collect metrics for function instance {}", fullyQualifiedInstanceName, e);
}
}
}
}
}
}
use of org.apache.pulsar.functions.runtime.kubernetes.KubernetesRuntimeFactory in project pulsar by apache.
the class FunctionRuntimeManagerTest method testKubernetesFunctionInstancesRestart.
@Test
public void testKubernetesFunctionInstancesRestart() throws Exception {
WorkerConfig workerConfig = new WorkerConfig();
workerConfig.setWorkerId("worker-1");
workerConfig.setPulsarServiceUrl(PULSAR_SERVICE_URL);
workerConfig.setStateStorageServiceUrl("foo");
workerConfig.setFunctionAssignmentTopicName("assignments");
WorkerConfig.KubernetesContainerFactory kubernetesContainerFactory = new WorkerConfig.KubernetesContainerFactory();
workerConfig.setKubernetesContainerFactory(kubernetesContainerFactory);
try (MockedConstruction<KubernetesRuntimeFactory> mocked = Mockito.mockConstruction(KubernetesRuntimeFactory.class, (mockedKubernetesRuntimeFactory, context) -> {
doNothing().when(mockedKubernetesRuntimeFactory).initialize(any(WorkerConfig.class), any(AuthenticationConfig.class), any(SecretsProviderConfigurator.class), any(), any(), any());
doNothing().when(mockedKubernetesRuntimeFactory).setupClient();
doReturn(true).when(mockedKubernetesRuntimeFactory).externallyManaged();
})) {
PulsarWorkerService workerService = mock(PulsarWorkerService.class);
// mock pulsarAdmin sources sinks functions
PulsarAdmin pulsarAdmin = mock(PulsarAdmin.class);
Sources sources = mock(Sources.class);
doNothing().when(sources).restartSource(ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any());
doReturn(sources).when(pulsarAdmin).sources();
Sinks sinks = mock(Sinks.class);
doReturn(sinks).when(pulsarAdmin).sinks();
Functions functions = mock(Functions.class);
doNothing().when(functions).restartFunction(ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any());
doReturn(functions).when(pulsarAdmin).functions();
doReturn(pulsarAdmin).when(workerService).getFunctionAdmin();
try (final MockedStatic<RuntimeFactory> runtimeFactoryMockedStatic = Mockito.mockStatic(RuntimeFactory.class)) {
mockRuntimeFactory(runtimeFactoryMockedStatic);
List<WorkerInfo> workerInfos = new LinkedList<>();
workerInfos.add(WorkerInfo.of("worker-1", "localhost", 0));
workerInfos.add(WorkerInfo.of("worker-2", "localhost", 0));
MembershipManager membershipManager = mock(MembershipManager.class);
doReturn(workerInfos).when(membershipManager).getCurrentMembership();
// build three types of FunctionMetaData
Function.FunctionMetaData function = Function.FunctionMetaData.newBuilder().setFunctionDetails(Function.FunctionDetails.newBuilder().setTenant("test-tenant").setNamespace("test-namespace").setName("function").setComponentType(Function.FunctionDetails.ComponentType.FUNCTION)).build();
Function.FunctionMetaData source = Function.FunctionMetaData.newBuilder().setFunctionDetails(Function.FunctionDetails.newBuilder().setTenant("test-tenant").setNamespace("test-namespace").setName("source").setComponentType(Function.FunctionDetails.ComponentType.SOURCE)).build();
Function.FunctionMetaData sink = Function.FunctionMetaData.newBuilder().setFunctionDetails(Function.FunctionDetails.newBuilder().setTenant("test-tenant").setNamespace("test-namespace").setName("sink").setComponentType(Function.FunctionDetails.ComponentType.SINK)).build();
FunctionRuntimeManager functionRuntimeManager = spy(new FunctionRuntimeManager(workerConfig, workerService, mock(Namespace.class), membershipManager, mock(ConnectorsManager.class), mock(FunctionsManager.class), mock(FunctionMetaDataManager.class), mock(WorkerStatsManager.class), mock(ErrorNotifier.class)));
// verify restart function/source/sink using different assignment
verifyRestart(functionRuntimeManager, function, "worker-1", true, false);
verifyRestart(functionRuntimeManager, function, "worker-2", true, true);
verifyRestart(functionRuntimeManager, source, "worker-1", true, false);
verifyRestart(functionRuntimeManager, source, "worker-2", true, true);
verifyRestart(functionRuntimeManager, sink, "worker-1", true, false);
verifyRestart(functionRuntimeManager, sink, "worker-2", true, true);
}
}
}
use of org.apache.pulsar.functions.runtime.kubernetes.KubernetesRuntimeFactory in project pulsar by yahoo.
the class FunctionRuntimeManagerTest method testFunctionRuntimeFactoryConfigsBackwardsCompatibility.
@Test
public void testFunctionRuntimeFactoryConfigsBackwardsCompatibility() throws Exception {
// Test kubernetes runtime
WorkerConfig.KubernetesContainerFactory kubernetesContainerFactory = new WorkerConfig.KubernetesContainerFactory();
kubernetesContainerFactory.setK8Uri("k8Uri");
kubernetesContainerFactory.setJobNamespace("jobNamespace");
kubernetesContainerFactory.setJobName("jobName");
kubernetesContainerFactory.setPulsarDockerImageName("pulsarDockerImageName");
kubernetesContainerFactory.setImagePullPolicy("imagePullPolicy");
kubernetesContainerFactory.setPulsarRootDir("pulsarRootDir");
WorkerConfig workerConfig = new WorkerConfig();
workerConfig.setKubernetesContainerFactory(kubernetesContainerFactory);
try (MockedConstruction<KubernetesRuntimeFactory> mocked = Mockito.mockConstruction(KubernetesRuntimeFactory.class, withSettings().defaultAnswer(CALLS_REAL_METHODS), (mockedKubernetesRuntimeFactory, context) -> {
doNothing().when(mockedKubernetesRuntimeFactory).initialize(any(WorkerConfig.class), any(AuthenticationConfig.class), any(SecretsProviderConfigurator.class), any(), any(), any());
doNothing().when(mockedKubernetesRuntimeFactory).setupClient();
doReturn(true).when(mockedKubernetesRuntimeFactory).externallyManaged();
})) {
FunctionRuntimeManager functionRuntimeManager = new FunctionRuntimeManager(workerConfig, mock(PulsarWorkerService.class), mock(Namespace.class), mock(MembershipManager.class), mock(ConnectorsManager.class), mock(FunctionsManager.class), mock(FunctionMetaDataManager.class), mock(WorkerStatsManager.class), mock(ErrorNotifier.class));
KubernetesRuntimeFactory kubernetesRuntimeFactory = (KubernetesRuntimeFactory) functionRuntimeManager.getRuntimeFactory();
assertEquals(kubernetesRuntimeFactory.getK8Uri(), "k8Uri");
assertEquals(kubernetesRuntimeFactory.getJobNamespace(), "jobNamespace");
assertEquals(kubernetesRuntimeFactory.getPulsarDockerImageName(), "pulsarDockerImageName");
assertEquals(kubernetesRuntimeFactory.getImagePullPolicy(), "imagePullPolicy");
assertEquals(kubernetesRuntimeFactory.getPulsarRootDir(), "pulsarRootDir");
// Test process runtime
WorkerConfig.ProcessContainerFactory processContainerFactory = new WorkerConfig.ProcessContainerFactory();
processContainerFactory.setExtraFunctionDependenciesDir("extraDependenciesDir");
processContainerFactory.setLogDirectory("logDirectory");
processContainerFactory.setPythonInstanceLocation("pythonInstanceLocation");
processContainerFactory.setJavaInstanceJarLocation("javaInstanceJarLocation");
workerConfig = new WorkerConfig();
workerConfig.setProcessContainerFactory(processContainerFactory);
functionRuntimeManager = new FunctionRuntimeManager(workerConfig, mock(PulsarWorkerService.class), mock(Namespace.class), mock(MembershipManager.class), mock(ConnectorsManager.class), mock(FunctionsManager.class), mock(FunctionMetaDataManager.class), mock(WorkerStatsManager.class), mock(ErrorNotifier.class));
assertEquals(functionRuntimeManager.getRuntimeFactory().getClass(), ProcessRuntimeFactory.class);
ProcessRuntimeFactory processRuntimeFactory = (ProcessRuntimeFactory) functionRuntimeManager.getRuntimeFactory();
assertEquals(processRuntimeFactory.getExtraDependenciesDir(), "extraDependenciesDir");
assertEquals(processRuntimeFactory.getLogDirectory(), "logDirectory/functions");
assertEquals(processRuntimeFactory.getPythonInstanceFile(), "pythonInstanceLocation");
assertEquals(processRuntimeFactory.getJavaInstanceJarFile(), "javaInstanceJarLocation");
// Test thread runtime
WorkerConfig.ThreadContainerFactory threadContainerFactory = new WorkerConfig.ThreadContainerFactory();
threadContainerFactory.setThreadGroupName("threadGroupName");
workerConfig = new WorkerConfig();
workerConfig.setThreadContainerFactory(threadContainerFactory);
workerConfig.setPulsarServiceUrl(PULSAR_SERVICE_URL);
functionRuntimeManager = new FunctionRuntimeManager(workerConfig, mock(PulsarWorkerService.class), mock(Namespace.class), mock(MembershipManager.class), mock(ConnectorsManager.class), mock(FunctionsManager.class), mock(FunctionMetaDataManager.class), mock(WorkerStatsManager.class), mock(ErrorNotifier.class));
assertEquals(functionRuntimeManager.getRuntimeFactory().getClass(), ThreadRuntimeFactory.class);
ThreadRuntimeFactory threadRuntimeFactory = (ThreadRuntimeFactory) functionRuntimeManager.getRuntimeFactory();
assertEquals(threadRuntimeFactory.getThreadGroup().getName(), "threadGroupName");
}
}
use of org.apache.pulsar.functions.runtime.kubernetes.KubernetesRuntimeFactory in project pulsar by yahoo.
the class FunctionRuntimeManagerTest method testExternallyManagedRuntimeUpdate.
@Test
public void testExternallyManagedRuntimeUpdate() throws Exception {
WorkerConfig workerConfig = new WorkerConfig();
workerConfig.setWorkerId("worker-1");
workerConfig.setFunctionRuntimeFactoryClassName(KubernetesRuntimeFactory.class.getName());
workerConfig.setFunctionRuntimeFactoryConfigs(ObjectMapperFactory.getThreadLocal().convertValue(new KubernetesRuntimeFactoryConfig().setSubmittingInsidePod(false), Map.class));
workerConfig.setPulsarServiceUrl(PULSAR_SERVICE_URL);
workerConfig.setStateStorageServiceUrl("foo");
workerConfig.setPulsarFunctionsCluster("cluster");
PulsarClient pulsarClient = mock(PulsarClient.class);
ReaderBuilder readerBuilder = mock(ReaderBuilder.class);
doReturn(readerBuilder).when(pulsarClient).newReader();
doReturn(readerBuilder).when(readerBuilder).topic(anyString());
doReturn(readerBuilder).when(readerBuilder).startMessageId(any());
doReturn(readerBuilder).when(readerBuilder).readCompacted(anyBoolean());
doReturn(mock(Reader.class)).when(readerBuilder).create();
PulsarWorkerService workerService = mock(PulsarWorkerService.class);
doReturn(pulsarClient).when(workerService).getClient();
doReturn(mock(PulsarAdmin.class)).when(workerService).getFunctionAdmin();
KubernetesRuntimeFactory kubernetesRuntimeFactory = mock(KubernetesRuntimeFactory.class);
doNothing().when(kubernetesRuntimeFactory).initialize(any(WorkerConfig.class), any(AuthenticationConfig.class), any(SecretsProviderConfigurator.class), any(), any(), any());
doNothing().when(kubernetesRuntimeFactory).setupClient();
doReturn(true).when(kubernetesRuntimeFactory).externallyManaged();
KubernetesRuntime kubernetesRuntime = mock(KubernetesRuntime.class);
doReturn(kubernetesRuntime).when(kubernetesRuntimeFactory).createContainer(any(), any(), any(), any());
FunctionActioner functionActioner = spy(new FunctionActioner(workerConfig, kubernetesRuntimeFactory, null, null, null, null));
try (final MockedStatic<RuntimeFactory> runtimeFactoryMockedStatic = Mockito.mockStatic(RuntimeFactory.class)) {
runtimeFactoryMockedStatic.when(() -> RuntimeFactory.getFuntionRuntimeFactory(anyString())).thenAnswer(invocation -> kubernetesRuntimeFactory);
// test new assignment update functions
FunctionRuntimeManager functionRuntimeManager = new FunctionRuntimeManager(workerConfig, workerService, mock(Namespace.class), mock(MembershipManager.class), mock(ConnectorsManager.class), mock(FunctionsManager.class), mock(FunctionMetaDataManager.class), mock(WorkerStatsManager.class), mock(ErrorNotifier.class));
functionRuntimeManager.setFunctionActioner(functionActioner);
Function.FunctionMetaData function1 = Function.FunctionMetaData.newBuilder().setPackageLocation(Function.PackageLocationMetaData.newBuilder().setPackagePath("path").build()).setFunctionDetails(Function.FunctionDetails.newBuilder().setTenant("test-tenant").setNamespace("test-namespace").setName("func-1")).build();
Function.Assignment assignment1 = Function.Assignment.newBuilder().setWorkerId("worker-1").setInstance(Function.Instance.newBuilder().setFunctionMetaData(function1).setInstanceId(0).build()).build();
/**
* Test transfer from me to other worker *
*/
// add existing assignments
functionRuntimeManager.setAssignment(assignment1);
// new assignment with different worker
Function.Assignment assignment2 = Function.Assignment.newBuilder().setWorkerId("worker-2").setInstance(Function.Instance.newBuilder().setFunctionMetaData(function1).setInstanceId(0).build()).build();
Function.Instance instance = Function.Instance.newBuilder().setFunctionMetaData(function1).setInstanceId(0).build();
FunctionRuntimeInfo functionRuntimeInfo = new FunctionRuntimeInfo().setFunctionInstance(instance).setRuntimeSpawner(functionActioner.getRuntimeSpawner(instance, function1.getPackageLocation().getPackagePath()));
functionRuntimeManager.functionRuntimeInfos.put("test-tenant/test-namespace/func-1:0", functionRuntimeInfo);
functionRuntimeManager.processAssignment(assignment2);
// make sure nothing is called
verify(functionActioner, times(0)).startFunction(any(FunctionRuntimeInfo.class));
verify(functionActioner, times(0)).terminateFunction(any(FunctionRuntimeInfo.class));
verify(functionActioner, times(0)).stopFunction(any(FunctionRuntimeInfo.class));
assertEquals(functionRuntimeManager.workerIdToAssignments.get("worker-2").get("test-tenant/test-namespace/func-1:0"), assignment2);
assertNull(functionRuntimeManager.functionRuntimeInfos.get("test-tenant/test-namespace/func-1:0"));
/**
* Test transfer from other worker to me *
*/
Function.Assignment assignment3 = Function.Assignment.newBuilder().setWorkerId("worker-1").setInstance(Function.Instance.newBuilder().setFunctionMetaData(function1).setInstanceId(0).build()).build();
functionRuntimeManager.processAssignment(assignment3);
// make sure nothing is called
verify(functionActioner, times(0)).startFunction(any(FunctionRuntimeInfo.class));
verify(functionActioner, times(0)).terminateFunction(any(FunctionRuntimeInfo.class));
verify(functionActioner, times(0)).stopFunction(any(FunctionRuntimeInfo.class));
assertEquals(functionRuntimeManager.workerIdToAssignments.get("worker-1").get("test-tenant/test-namespace/func-1:0"), assignment3);
assertNull(functionRuntimeManager.workerIdToAssignments.get("worker-2"));
assertEquals(functionRuntimeManager.functionRuntimeInfos.get("test-tenant/test-namespace/func-1:0").getFunctionInstance(), functionRuntimeInfo.getFunctionInstance());
assertNotNull(functionRuntimeManager.functionRuntimeInfos.get("test-tenant/test-namespace/func-1:0").getRuntimeSpawner());
assertEquals(functionRuntimeManager.functionRuntimeInfos.get("test-tenant/test-namespace/func-1:0").getRuntimeSpawner().getInstanceConfig().getFunctionDetails(), function1.getFunctionDetails());
assertEquals(functionRuntimeManager.functionRuntimeInfos.get("test-tenant/test-namespace/func-1:0").getRuntimeSpawner().getInstanceConfig().getInstanceId(), instance.getInstanceId());
assertTrue(functionRuntimeManager.functionRuntimeInfos.get("test-tenant/test-namespace/func-1:0").getRuntimeSpawner().getRuntimeFactory() instanceof KubernetesRuntimeFactory);
assertNotNull(functionRuntimeManager.functionRuntimeInfos.get("test-tenant/test-namespace/func-1:0").getRuntimeSpawner().getRuntime());
verify(kubernetesRuntime, times(1)).reinitialize();
}
}
use of org.apache.pulsar.functions.runtime.kubernetes.KubernetesRuntimeFactory in project pulsar by yahoo.
the class FunctionsStatsGenerator method generate.
public static void generate(PulsarWorkerService workerService, SimpleTextOutputStream out) {
// only when worker service is initialized, we generate the stats. otherwise we will get bunch of NPE.
if (workerService != null && workerService.isInitialized()) {
try {
out.write(workerService.getWorkerStatsManager().getStatsAsString());
} catch (IOException e) {
log.warn("Encountered error when generating metrics for worker {}", workerService.getWorkerConfig().getWorkerId(), e);
}
// kubernetes runtime factory doesn't support stats collection through worker service
if (workerService.getFunctionRuntimeManager().getRuntimeFactory() instanceof KubernetesRuntimeFactory) {
return;
}
Map<String, FunctionRuntimeInfo> functionRuntimes = workerService.getFunctionRuntimeManager().getFunctionRuntimeInfos();
for (Map.Entry<String, FunctionRuntimeInfo> entry : functionRuntimes.entrySet()) {
String fullyQualifiedInstanceName = entry.getKey();
FunctionRuntimeInfo functionRuntimeInfo = entry.getValue();
RuntimeSpawner functionRuntimeSpawner = functionRuntimeInfo.getRuntimeSpawner();
if (functionRuntimeSpawner != null) {
Runtime functionRuntime = functionRuntimeSpawner.getRuntime();
if (functionRuntime != null) {
try {
String prometheusMetrics = functionRuntime.getPrometheusMetrics();
if (prometheusMetrics != null) {
out.write(prometheusMetrics);
}
} catch (IOException e) {
log.warn("Failed to collect metrics for function instance {}", fullyQualifiedInstanceName, e);
}
}
}
}
}
}
Aggregations