/** * {@inheritDoc} */ @Override public void run() { Collection<ImmutableType> changedClassTypes = execute(); createInstrumentationChangedEvent(changedClassTypes); }
/** * {@inheritDoc} */ @Override protected Collection<ImmutableType> execute() { // always update configuration getConfigurationHolder().update(getEnvironment(), getAgentId()); Collection<ImmutableType> changedClassTypes = new HashSet<>(); // first process all removed and added assignments changedClassTypes.addAll(super.processRemovedAssignments(profileUpdateEvent.getRemovedSensorAssignments())); changedClassTypes.addAll(super.processAddedAssignments(profileUpdateEvent.getAddedSensorAssignments())); return changedClassTypes; }
/** * @return Returns environment based on the {@link ConfigurationHolder}. */ protected Environment getEnvironment() { return getConfigurationHolder().getEnvironment(); }
environmentUpdateJob.setEnvironmentUpdateEvent(event); environmentUpdateJob.setAgentCacheEntry(agentCacheEntry);
/** * {@inheritDoc} */ @Override protected Collection<ImmutableType> execute() { // always update with new Environment getConfigurationHolder().update(environmentUpdateEvent.getAfter(), getAgentId()); Collection<ImmutableType> changedClassTypes = new HashSet<>(); // then process removed and added assignments changedClassTypes.addAll(super.processRemovedAssignments(environmentUpdateEvent.getRemovedSensorAssignments(functionalAssignmentFactory))); changedClassTypes.addAll(super.processAddedAssignments(environmentUpdateEvent.getAddedSensorAssignments(functionalAssignmentFactory))); return changedClassTypes; }
/** * {@inheritDoc} */ @Override protected Collection<ImmutableType> execute() { Collection<ImmutableType> changedClassTypes = new HashSet<>(); // add current instrumentation changedClassTypes.addAll(getClassCache().getLookupService().findInstrumentedTypes()); // first remove all existing instrumentation points getClassCache().getInstrumentationService().removeInstrumentationPoints(); // then update configuration holder ConfigurationHolder configurationHolder = getConfigurationHolder(); configurationHolder.update(environment, getAgentId()); // if we are initialized analyze the complete class cache if (configurationHolder.isInitialized()) { // then add instrumentation points Collection<IInstrumentationApplier> instrumentationAppliers = configurationHolder.getInstrumentationAppliers(); Collection<? extends ImmutableClassType> instrumentedTypes = getClassCache().getInstrumentationService().addInstrumentationPoints(getAgentConfiguration(), instrumentationAppliers); changedClassTypes.addAll(instrumentedTypes); } return changedClassTypes; }
@Test public void noChanges() { job.setProfileUpdateEvent(event); job.run(); verifyZeroInteractions(classCache, environment, classCacheSearchNarrower, agentConfiguration, instrumentationService, eventPublisher); }
@Test public void noEnvironment() { when(configurationHolder.isInitialized()).thenReturn(false); job.setEnvironment(null); job.run(); verify(instrumentationService, times(1)).removeInstrumentationPoints(); verify(configurationHolder, times(1)).update(null, PLATFORM_ID); verifyNoMoreInteractions(instrumentationService, eventPublisher); }
@Test public void onlyConfigurationUpdate() throws RemoteException, BusinessException { job.setEnvironmentUpdateEvent(event); job.run(); verify(configurationHolder, times(1)).update(updateEnvironment, PLATFORM_ID); verify(agentConfiguration, times(0)).setInitialInstrumentationResults(Matchers.anyMap()); verify(agentConfiguration, times(0)).setClassCacheExistsOnCmr(Matchers.anyBoolean()); verifyZeroInteractions(classCache, environment, classCacheSearchNarrower, agentConfiguration, instrumentationService, eventPublisher); }
/** * Process the removed assignments. All instrumentation points affected by the any of these * assignments are first completely removed. All classes that have any point removed will be * re-analyzed against complete configuration in order to reset the possible points coming not * from removed assignments. * * @param classSensorAssignments * Collection of removed {@link AbstractClassSensorAssignment}s. * @return Returns a {@link Collection} of {@link ImmutableClassType} which have been removed. */ protected Collection<ImmutableClassType> processRemovedAssignments(Collection<? extends AbstractClassSensorAssignment<?>> classSensorAssignments) { Collection<ImmutableClassType> changedClassTypes = new ArrayList<>(); // process all class sensor assignments for removal for (AbstractClassSensorAssignment<?> assignment : classSensorAssignments) { // narrow the search Collection<? extends ImmutableClassType> classTypes = classCacheSearchNarrower.narrowByClassSensorAssignment(getClassCache(), assignment); // get the applier IInstrumentationApplier instrumentationApplier = configurationResolver.getInstrumentationApplier(assignment, getEnvironment()); changedClassTypes.addAll(getClassCache().getInstrumentationService().removeInstrumentationPoints(classTypes, Collections.singleton(instrumentationApplier))); } // if no class was affected just return if (CollectionUtils.isNotEmpty(changedClassTypes)) { // if any class was affected re-check those classes against complete configuration // because we removed all instrumentation points Collection<IInstrumentationApplier> instrumentationAppliers = getConfigurationHolder().getInstrumentationAppliers(); getClassCache().getInstrumentationService().addInstrumentationPoints(changedClassTypes, getAgentConfiguration(), instrumentationAppliers); } return changedClassTypes; }
@Test @SuppressWarnings({ "unchecked", "rawtypes" }) public void successful() throws InterruptedException, ExecutionException, TimeoutException { cacheMap.put(1L, cacheEntry); when(event.isProfileActive()).thenReturn(true); when(event.getProfileId()).thenReturn("id_1"); when(configurationHolder.isInitialized()).thenReturn(true); when(environment.getProfileIds()).thenReturn(Sets.newHashSet("id_1")); when(objectFactory.getObject()).thenReturn(updateJob); when(executor.submit(updateJob)).thenReturn((Future) future); eventListener.onApplicationEvent(event); verify(event).isProfileActive(); verify(event).getProfileId(); verify(nextGenInstrumentationManager).getAgentCacheMap(); verify(cacheEntry).getConfigurationHolder(); verify(configurationHolder).getEnvironment(); verify(configurationHolder).isInitialized(); verify(environment, times(2)).getProfileIds(); verify(objectFactory).getObject(); verify(executor).submit(updateJob); verify(updateJob).setAgentCacheEntry(cacheEntry); verify(updateJob).setProfileUpdateEvent(event); verify(future).get(1L, TimeUnit.MINUTES); verifyNoMoreInteractions(event, cacheEntry, configurationHolder, environment, updateJob, future, nextGenInstrumentationManager, objectFactory, executor); }
/** * Process the added assignments. New instrumentation points will be added to all the classes in * the class cache that fit to the given assignments. * * @param classSensorAssignments * Collection of added {@link AbstractClassSensorAssignment}s. * @return Returns a {@link Collection} of {@link ImmutableClassType} which have been added. */ protected Collection<ImmutableClassType> processAddedAssignments(Collection<? extends AbstractClassSensorAssignment<?>> classSensorAssignments) { Collection<ImmutableClassType> changedClassTypes = new ArrayList<>(); // process all class sensor assignments for adding for (AbstractClassSensorAssignment<?> assignment : classSensorAssignments) { // narrow the search Collection<? extends ImmutableClassType> classTypes = classCacheSearchNarrower.narrowByClassSensorAssignment(getClassCache(), assignment); // get the applier IInstrumentationApplier instrumentationApplier = configurationResolver.getInstrumentationApplier(assignment, getEnvironment()); // execute Collection<? extends ImmutableClassType> instrumentedClassTypes = getClassCache().getInstrumentationService().addInstrumentationPoints(classTypes, getAgentConfiguration(), Collections.singleton(instrumentationApplier)); changedClassTypes.addAll(instrumentedClassTypes); } return changedClassTypes; }
@BeforeMethod public void init() throws Exception { MockitoAnnotations.initMocks(this); job.log = LoggerFactory.getLogger(EnvironmentMappingUpdateJob.class); job.setAgentCacheEntry(agentCacheEntry); when(configurationHolder.getEnvironment()).thenReturn(environment); when(configurationHolder.getInstrumentationAppliers()).thenReturn(Collections.singletonList(holdedInstrumentationApplier)); when(agentCacheEntry.getConfigurationHolder()).thenReturn(configurationHolder); when(agentCacheEntry.getClassCache()).thenReturn(classCache); when(agentCacheEntry.getId()).thenReturn(PLATFORM_ID); when(classCache.getInstrumentationService()).thenReturn(instrumentationService); when(classCache.getLookupService()).thenReturn(lookupService); when(classType.isClass()).thenReturn(true); when(classType.castToClass()).thenReturn(immutableClassType); }
if (CollectionUtils.isNotEmpty(changedTypes)) { if (log.isInfoEnabled()) { log.info("Updated instrumentation definition of {} class(es) for the agent [ID: {}]", changedTypes.size(), getAgentId()); List<InstrumentationDefinition> instrumentationDefinitions = new ArrayList<>(getClassCache().getInstrumentationService().getInstrumentationResults(changedTypes)); ClassInstrumentationChangedEvent event = new ClassInstrumentationChangedEvent(this, getAgentId(), instrumentationDefinitions); eventPublisher.publishEvent(event);
@Test @SuppressWarnings({ "unchecked", "rawtypes" }) public void successful() throws InterruptedException, ExecutionException, TimeoutException { cacheMap.put(1L, cacheEntry); when(configurationHolder.isInitialized()).thenReturn(true); when(environment.getId()).thenReturn("id"); when(event.getEnvironmentId()).thenReturn("id"); when(objectFactory.getObject()).thenReturn(updateJob); when(executor.submit(updateJob)).thenReturn((Future) future); eventListener.onApplicationEvent(event); verify(nextGenInstrumentationManager).getAgentCacheMap(); verify(cacheEntry).getConfigurationHolder(); verify(configurationHolder).isInitialized(); verify(configurationHolder).getEnvironment(); verify(environment).getId(); verify(event).getEnvironmentId(); verify(objectFactory).getObject(); verify(updateJob).setAgentCacheEntry(cacheEntry); verify(updateJob).setEnvironmentUpdateEvent(event); verify(executor).submit(updateJob); verify(future).get(1, TimeUnit.MINUTES); verifyNoMoreInteractions(nextGenInstrumentationManager, cacheEntry, configurationHolder, environment, event, objectFactory, updateJob, executor, future); }
@Test public void removedAssignmentNoChange() throws RemoteException { Collection<ClassType> types = ImmutableList.of(classTypeOne, classTypeTwo); doReturn(instrumentationApplier).when(configurationResolver).getInstrumentationApplier(sensorAssignment, environment); doReturn(types).when(classCacheSearchNarrower).narrowByClassSensorAssignment(classCache, sensorAssignment); doReturn(Collections.emptyList()).when(instrumentationService).removeInstrumentationPoints(eq(types), Matchers.<Collection<IInstrumentationApplier>> any()); doReturn(Collections.singleton(sensorAssignment)).when(event).getRemovedSensorAssignments(); job.setProfileUpdateEvent(event); job.run(); ArgumentCaptor<Collection> captor = ArgumentCaptor.forClass(Collection.class); verify(instrumentationService, times(1)).removeInstrumentationPoints(eq(types), captor.capture()); assertThat((Collection<IInstrumentationApplier>) captor.getValue(), hasSize(1)); assertThat(((Collection<IInstrumentationApplier>) captor.getValue()).iterator().next(), is(instrumentationApplier)); verifyNoMoreInteractions(instrumentationService); verifyZeroInteractions(environment, eventPublisher); } }
@Test @SuppressWarnings({ "unchecked", "rawtypes" }) public void yesEnvironment() { when(configurationHolder.isInitialized()).thenReturn(true); when(configurationHolder.getAgentConfiguration()).thenReturn(updateConfiguration); doReturn(Collections.singletonList(classType)).when(instrumentationService).addInstrumentationPoints(any(AgentConfig.class), any(Collection.class)); job.setEnvironment(updateEnvironment); job.run(); verify(instrumentationService, times(1)).removeInstrumentationPoints(); verify(configurationHolder, times(1)).update(updateEnvironment, PLATFORM_ID); Collection<IInstrumentationApplier> appliers = configurationHolder.getInstrumentationAppliers(); verify(instrumentationService, times(1)).addInstrumentationPoints(updateConfiguration, appliers); ArgumentCaptor<Collection> typeCaptor = ArgumentCaptor.forClass(Collection.class); verify(instrumentationService).getInstrumentationResults(typeCaptor.capture()); assertThat((Collection<Type>) typeCaptor.getValue(), hasItems((Type) classType)); verify(eventPublisher).publishEvent(any(ClassInstrumentationChangedEvent.class)); verifyNoMoreInteractions(instrumentationService, updateConfiguration, updateEnvironment, eventPublisher); } }
@Test public void removedAssignmentNoChange() { Collection<ClassType> types = Collections.singleton(classType); doReturn(instrumentationApplier).when(configurationResolver).getInstrumentationApplier(sensorAssignment, environment); doReturn(types).when(classCacheSearchNarrower).narrowByClassSensorAssignment(classCache, sensorAssignment); doReturn(Collections.emptyList()).when(instrumentationService).removeInstrumentationPoints(eq(types), Matchers.<Collection<IInstrumentationApplier>> any()); doReturn(Collections.singletonList(sensorAssignment)).when(event).getRemovedSensorAssignments(functionalAssignmentFactory); job.setEnvironmentUpdateEvent(event); job.run(); verify(configurationHolder, times(1)).update(updateEnvironment, PLATFORM_ID); ArgumentCaptor<Collection> captor = ArgumentCaptor.forClass(Collection.class); verify(instrumentationService, times(1)).removeInstrumentationPoints(types, Collections.singleton(instrumentationApplier)); verifyNoMoreInteractions(instrumentationService); verifyZeroInteractions(environment, agentConfiguration, eventPublisher); } }
@Test @SuppressWarnings({ "unchecked", "rawtypes" }) public void resolverThrowsBusinessException() throws BusinessException, InterruptedException, ExecutionException, TimeoutException { cacheMap.put(1L, cacheEntry); when(cacheEntry.getId()).thenReturn(10L); when(configurationResolver.getEnvironmentForAgent(any(List.class), any(String.class))).thenThrow(BusinessException.class); when(cachedEnvironment.getId()).thenReturn("id"); when(newEnvironment.getId()).thenReturn("newId"); when(objectFactory.getObject()).thenReturn(updateJob); when(executor.submit(updateJob)).thenReturn((Future) future); eventListener.onApplicationEvent(event); verify(configurationResolver).getEnvironmentForAgent(any(List.class), any(String.class)); verify(objectFactory).getObject(); verify(updateJob).setAgentCacheEntry(cacheEntry); verify(executor).submit(updateJob); verify(future).get(1L, TimeUnit.MINUTES); verifyNoMoreInteractions(configurationResolver, objectFactory, updateJob, executor, future); verifyZeroInteractions(cachedEnvironment, newEnvironment); }
/** * @return Returns agent configuration based on the {@link ConfigurationHolder}. */ protected AgentConfig getAgentConfiguration() { return getConfigurationHolder().getAgentConfiguration(); }