Skip to content

Commit

Permalink
DROOLS-1565 Implement a KieScanner listener (apache#1272)
Browse files Browse the repository at this point in the history
  • Loading branch information
tarilabs authored and mariofusco committed May 19, 2017
1 parent 74a8579 commit 2decba9
Show file tree
Hide file tree
Showing 10 changed files with 440 additions and 19 deletions.
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@


public interface InternalKieScanner extends KieScanner { public interface InternalKieScanner extends KieScanner {


enum Status {
STARTING, SCANNING, UPDATING, RUNNING, STOPPED, SHUTDOWN
}

void setKieContainer(KieContainer kieContainer); void setKieContainer(KieContainer kieContainer);


KieModule loadArtifact(ReleaseId releaseId); KieModule loadArtifact(ReleaseId releaseId);
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.kie.api.builder.KieScannerFactoryService; import org.kie.api.builder.KieScannerFactoryService;
import org.kie.api.builder.ReleaseId; import org.kie.api.builder.ReleaseId;
import org.kie.api.builder.model.KieModuleModel; import org.kie.api.builder.model.KieModuleModel;
import org.kie.api.event.kiescanner.KieScannerEventListener;
import org.kie.api.io.Resource; import org.kie.api.io.Resource;
import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieContainer;
import org.kie.internal.utils.ServiceRegistryImpl; import org.kie.internal.utils.ServiceRegistryImpl;
Expand All @@ -39,6 +40,8 @@
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
Expand Down Expand Up @@ -244,6 +247,14 @@ public Status getStatus() {
} }


public long getPollingInterval() { return 0; } public long getPollingInterval() { return 0; }

public void addListener(KieScannerEventListener listener) { }

public void removeListener(KieScannerEventListener listener) { }

public Collection<KieScannerEventListener> getListeners() {
return Collections.emptyList();
}
} }


public KieModule addKieModule(Resource resource, Resource... dependencies) { public KieModule addKieModule(Resource resource, Resource... dependencies) {
Expand Down
4 changes: 4 additions & 0 deletions kie-ci/pom.xml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!-- Replacement for above excluded 'commons-logging:commons-logging' --> <!-- Replacement for above excluded 'commons-logging:commons-logging' -->
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
Expand Down
65 changes: 51 additions & 14 deletions kie-ci/src/main/java/org/kie/scanner/KieRepositoryScannerImpl.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@
import org.kie.api.builder.KieScanner; import org.kie.api.builder.KieScanner;
import org.kie.api.builder.Message; import org.kie.api.builder.Message;
import org.kie.api.builder.ReleaseId; import org.kie.api.builder.ReleaseId;
import org.kie.api.builder.Results;
import org.kie.api.builder.model.KieModuleModel; import org.kie.api.builder.model.KieModuleModel;
import org.kie.api.event.kiescanner.KieScannerEventListener;
import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieContainer;
import org.kie.scanner.event.KieScannerEventSupport;
import org.kie.scanner.management.KieScannerMBean; import org.kie.scanner.management.KieScannerMBean;
import org.kie.scanner.management.KieScannerMBeanImpl; import org.kie.scanner.management.KieScannerMBeanImpl;
import org.kie.scanner.management.MBeanUtils; import org.kie.scanner.management.MBeanUtils;
Expand All @@ -42,6 +45,7 @@
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
Expand All @@ -50,6 +54,7 @@
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;



import static org.drools.compiler.kie.builder.impl.KieBuilderImpl.buildKieModule; import static org.drools.compiler.kie.builder.impl.KieBuilderImpl.buildKieModule;
import static org.drools.compiler.kie.builder.impl.KieBuilderImpl.setDefaultsforEmptyKieModule; import static org.drools.compiler.kie.builder.impl.KieBuilderImpl.setDefaultsforEmptyKieModule;
import static org.kie.scanner.ArtifactResolver.getResolverFor; import static org.kie.scanner.ArtifactResolver.getResolverFor;
Expand All @@ -73,7 +78,29 @@ public class KieRepositoryScannerImpl implements InternalKieScanner {
private KieScannerMBean mbean; private KieScannerMBean mbean;


private long pollingInterval; private long pollingInterval;

private KieScannerEventSupport listeners = new KieScannerEventSupport();

@Override
public void addListener(KieScannerEventListener listener) {
listeners.addEventListener(listener);
}


@Override
public void removeListener(KieScannerEventListener listener) {
listeners.removeEventListener(listener);
}

@Override
public Collection<KieScannerEventListener> getListeners() {
return listeners.getEventListeners();
}

private void changeStatus( Status status ) {
this.status = status;
listeners.fireKieScannerStatusChangeEventImpl(status);
}

public synchronized void setKieContainer(KieContainer kieContainer) { public synchronized void setKieContainer(KieContainer kieContainer) {
if (this.kieContainer != null) { if (this.kieContainer != null) {
throw new RuntimeException("Cannot change KieContainer on an already initialized KieScanner"); throw new RuntimeException("Cannot change KieContainer on an already initialized KieScanner");
Expand All @@ -90,7 +117,7 @@ public synchronized void setKieContainer(KieContainer kieContainer) {
usedDependencies = indexArtifacts(artifactResolver); usedDependencies = indexArtifacts(artifactResolver);


KieScannersRegistry.register(this); KieScannersRegistry.register(this);
status = Status.STOPPED; changeStatus( Status.STOPPED );


if( MBeanUtils.isMBeanEnabled() ) { if( MBeanUtils.isMBeanEnabled() ) {
mbean = new KieScannerMBeanImpl(this); mbean = new KieScannerMBeanImpl(this);
Expand Down Expand Up @@ -244,7 +271,7 @@ public synchronized void stop() {
timer = null; timer = null;
} }
this.pollingInterval = 0; this.pollingInterval = 0;
status = Status.STOPPED; changeStatus( Status.STOPPED );
} }


public synchronized long getPollingInterval() { public synchronized long getPollingInterval() {
Expand All @@ -254,12 +281,12 @@ public synchronized long getPollingInterval() {
public void shutdown() { public void shutdown() {
if( getStatus() != Status.SHUTDOWN ) { if( getStatus() != Status.SHUTDOWN ) {
stop(); // making sure it is stopped stop(); // making sure it is stopped
status = Status.SHUTDOWN; changeStatus( Status.SHUTDOWN );
} }
} }


private void startScanTask(long pollingInterval) { private void startScanTask(long pollingInterval) {
status = Status.RUNNING; changeStatus( Status.RUNNING );
this.pollingInterval = pollingInterval; this.pollingInterval = pollingInterval;
timer = new Timer(true); timer = new Timer(true);
timer.schedule(new ScanTask(), pollingInterval, pollingInterval); timer.schedule(new ScanTask(), pollingInterval, pollingInterval);
Expand All @@ -273,7 +300,7 @@ public void run() {
return; return;
} }
scanNow(); scanNow();
status = Status.RUNNING; changeStatus( Status.RUNNING );
} }
} }
} }
Expand All @@ -285,47 +312,56 @@ public synchronized void scanNow() {
// Polling can be started so remember the original state. // Polling can be started so remember the original state.
final Status originalStatus = status; final Status originalStatus = status;
try { try {
status = Status.SCANNING; changeStatus( Status.SCANNING );
Map<DependencyDescriptor, Artifact> updatedArtifacts = scanForUpdates(); Map<DependencyDescriptor, Artifact> updatedArtifacts = scanForUpdates();
if (updatedArtifacts.isEmpty()) { if (updatedArtifacts.isEmpty()) {
status = originalStatus; changeStatus( originalStatus );
return; return;
} }
status = Status.UPDATING; changeStatus( Status.UPDATING );


boolean allUpdatesSucceeded = true;
// build the dependencies first // build the dependencies first
Map.Entry<DependencyDescriptor, Artifact> containerEntry = null; Map.Entry<DependencyDescriptor, Artifact> containerEntry = null;
for (Map.Entry<DependencyDescriptor, Artifact> entry : updatedArtifacts.entrySet()) { for (Map.Entry<DependencyDescriptor, Artifact> entry : updatedArtifacts.entrySet()) {
if (entry.getKey().isSameArtifact(kieContainer.getContainerReleaseId())) { if (entry.getKey().isSameArtifact(kieContainer.getContainerReleaseId())) {
containerEntry = entry; containerEntry = entry;
} else { } else {
updateKieModule(entry.getKey(), entry.getValue()); allUpdatesSucceeded = updateKieModule(entry.getKey(), entry.getValue()) && allUpdatesSucceeded;
} }
} }
if (containerEntry != null) { if (containerEntry != null) {
updateKieModule(containerEntry.getKey(), containerEntry.getValue()); allUpdatesSucceeded = updateKieModule(containerEntry.getKey(), containerEntry.getValue()) && allUpdatesSucceeded;
} }


log.info("The following artifacts have been updated: " + updatedArtifacts); if ( allUpdatesSucceeded ) {
log.error("Some errors occured while updating the following artifacts: " + updatedArtifacts);
} else {
log.info("The following artifacts have been updated: " + updatedArtifacts);
}


// show we catch exceptions here and shutdown the scanner if one happens? // show we catch exceptions here and shutdown the scanner if one happens?


} finally { } finally {
status = originalStatus; changeStatus( originalStatus );
} }
} }


private void updateKieModule(DependencyDescriptor oldDependency, Artifact artifact) { private boolean updateKieModule(DependencyDescriptor oldDependency, Artifact artifact) {
ReleaseId newReleaseId = new DependencyDescriptor(artifact).getReleaseId(); ReleaseId newReleaseId = new DependencyDescriptor(artifact).getReleaseId();
ZipKieModule kieModule = createZipKieModule(newReleaseId, artifact.getFile()); ZipKieModule kieModule = createZipKieModule(newReleaseId, artifact.getFile());
if (kieModule != null) { if (kieModule != null) {
addDependencies(kieModule, artifactResolver, artifactResolver.getArtifactDependecies(newReleaseId.toString())); addDependencies(kieModule, artifactResolver, artifactResolver.getArtifactDependecies(newReleaseId.toString()));
ResultsImpl messages = build(kieModule); ResultsImpl messages = build(kieModule);
if ( messages.filterMessages(Message.Level.ERROR).isEmpty()) { if ( messages.filterMessages(Message.Level.ERROR).isEmpty()) {
kieContainer.updateDependencyToVersion(oldDependency.getArtifactReleaseId(), newReleaseId); Results updateMessages = kieContainer.updateDependencyToVersion(oldDependency.getArtifactReleaseId(), newReleaseId);
oldDependency.setArtifactVersion(artifact.getVersion()); oldDependency.setArtifactVersion(artifact.getVersion());
messages.getMessages().addAll( updateMessages.getMessages() ); // append all update Results into build Results to notify listeners
} }
listeners.fireKieScannerUpdateResultsEventImpl(messages);
return !messages.hasMessages(Message.Level.ERROR);
} }
return false;
} }


private Map<DependencyDescriptor, Artifact> scanForUpdates() { private Map<DependencyDescriptor, Artifact> scanForUpdates() {
Expand Down Expand Up @@ -388,4 +424,5 @@ private boolean isKJar(File jar) {
public synchronized KieScannerMBean getMBean() { public synchronized KieScannerMBean getMBean() {
return this.mbean; return this.mbean;
} }

} }
38 changes: 38 additions & 0 deletions kie-ci/src/main/java/org/kie/scanner/MavenRepository.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@


package org.kie.scanner; package org.kie.scanner;


import org.apache.commons.io.FileUtils;
import org.apache.maven.model.DeploymentRepository; import org.apache.maven.model.DeploymentRepository;
import org.apache.maven.model.DistributionManagement; import org.apache.maven.model.DistributionManagement;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.apache.maven.settings.Server; import org.apache.maven.settings.Server;
import org.drools.compiler.kie.builder.impl.InternalKieModule; import org.drools.compiler.kie.builder.impl.InternalKieModule;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.collection.CollectRequest; import org.eclipse.aether.collection.CollectRequest;
Expand All @@ -33,6 +36,8 @@
import org.eclipse.aether.installation.InstallRequest; import org.eclipse.aether.installation.InstallRequest;
import org.eclipse.aether.installation.InstallationException; import org.eclipse.aether.installation.InstallationException;
import org.eclipse.aether.repository.Authentication; import org.eclipse.aether.repository.Authentication;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.LocalRepositoryManager;
import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.repository.RepositoryPolicy; import org.eclipse.aether.repository.RepositoryPolicy;
import org.eclipse.aether.resolution.ArtifactRequest; import org.eclipse.aether.resolution.ArtifactRequest;
Expand Down Expand Up @@ -412,4 +417,37 @@ public static String toFileName( ReleaseId releaseId,


return releaseId.getArtifactId() + "-" + releaseId.getVersion(); return releaseId.getArtifactId() + "-" + releaseId.getVersion();
} }

/**
* Utility method specifically suggested for testing purposes only.
* @param repository
*/
public void removeLocalArtifact(ReleaseId releaseId) {
// Taken by analogy of build-helper-maven-plugin
Artifact artifact = new DefaultArtifact(releaseId.getGroupId(), releaseId.getArtifactId(), null, releaseId.getVersion());

LocalRepository localRepo = new LocalRepository( getMavenRepositoryConfiguration().getLocalRepository() );

DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
LocalRepositoryManager localRepositoryManager = aether.getSystem().newLocalRepositoryManager( session, localRepo );
session.setLocalRepositoryManager( localRepositoryManager );
session.setOffline( true );

String pathForLocalArtifact = localRepositoryManager.getPathForLocalArtifact(artifact);

File localArtifactDir = new File( localRepo.getBasedir(), pathForLocalArtifact ) // File .jar
.getParentFile() // Directory of specific version, corresponding in ReleaseId
;

if (!localArtifactDir.exists()) {
log.warn("The expected local maven repo dir for {} does not exist {}, nothing to delete.", releaseId, localArtifactDir);
return;
}
log.info("Erasing directory from local maven repository {}", localArtifactDir);
try {
FileUtils.deleteDirectory(localArtifactDir);
} catch (Exception e) {
log.error("Error while trying to erase directory from local maven repository {}", localArtifactDir);
}
}
} }
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ public MavenRepositoryConfiguration( Settings settings ) {
this.remoteRepositoriesForRequest = initRemoteRepositoriesForRequest(); this.remoteRepositoriesForRequest = initRemoteRepositoriesForRequest();
this.artifactRepositoriesForRequest = initArtifactRepositories(); this.artifactRepositoriesForRequest = initArtifactRepositories();
} }

protected String getLocalRepository() {
return settings.getLocalRepository();
}


public List<Proxy> getProxies() { public List<Proxy> getProxies() {
return settings.getProxies(); return settings.getProxies();
Expand Down
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates.
*
* 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 org.kie.scanner.event;

import java.util.Iterator;

import org.drools.core.event.AbstractEventSupport;
import org.kie.api.builder.Results;
import org.kie.api.builder.KieScanner.Status;
import org.kie.api.event.kiescanner.KieScannerEventListener;
import org.kie.api.event.kiescanner.KieScannerStatusChangeEvent;
import org.kie.api.event.kiescanner.KieScannerUpdateResultsEvent;

public class KieScannerEventSupport extends AbstractEventSupport<KieScannerEventListener> {

public void fireKieScannerStatusChangeEventImpl(final Status status) {
final Iterator<KieScannerEventListener> iter = getEventListenersIterator();

if (iter.hasNext()) {
KieScannerStatusChangeEvent event = new KieScannerStatusChangeEventImpl(status);

do {
iter.next().onKieScannerStatusChangeEvent(event);
} while (iter.hasNext());
}
}

public void fireKieScannerUpdateResultsEventImpl(final Results results) {
final Iterator<KieScannerEventListener> iter = getEventListenersIterator();

if (iter.hasNext()) {
KieScannerUpdateResultsEvent event = new KieScannerUpdateResultsEventImpl(results);

do {
iter.next().onKieScannerUpdateResultsEvent(event);
} while (iter.hasNext());
}
}


}
Loading

0 comments on commit 2decba9

Please sign in to comment.