/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* 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.wso2.carbon.component.mgt.core.util;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.equinox.internal.provisional.configurator.Configurator;
import org.eclipse.equinox.internal.provisional.p2.director.ProvisioningPlan;
import org.eclipse.equinox.internal.provisional.p2.engine.*;
import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.internal.provisional.p2.metadata.ILicense;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.IUPropertyQuery;
import org.eclipse.equinox.internal.provisional.p2.query.Collector;
import org.eclipse.equinox.internal.provisional.p2.query.Query;
import org.wso2.carbon.component.mgt.core.ProvisioningException;
import org.wso2.carbon.component.mgt.core.ResolutionResult;
import org.wso2.carbon.component.mgt.core.internal.ServiceHolder;
import org.wso2.carbon.component.mgt.core.profile.ProfileModificationAction;
import org.wso2.carbon.component.mgt.core.query.IUQuery;
import org.wso2.carbon.component.mgt.core.query.InstalledIUQuery;
import org.wso2.carbon.component.mgt.core.query.QueryContext;
import java.util.*;
/**
* Contains utility method which can be used for Profile Management. i.e Install/Uninstall/Revert operation on the system,
* Querying installed features
*/
public class ProvisioningUtils {
/**
* Performs an Installable Units Query.
*
* @param iuQuery instance of an IUQuery on which the query is to be performed.
* @return array of InstallableUnits
*/
public static IInstallableUnit[] performIUQuery(IUQuery iuQuery) {
if (iuQuery != null) {
Collector collector = iuQuery.perform();
IInstallableUnit[] collectedIUs = (IInstallableUnit[]) collector.toArray(IInstallableUnit.class);
return sort(collectedIUs);
}
return new IInstallableUnit[0];
}
/**
* Review the given provisioning action
*
* @param profileModificationAction should contains the appropriate provActionType and features to be
* installed and feature to be uninstalled
* @return an instance of ResolutionResult and it contains proposed ProvisioningPlan and the status.
* Depending on this status, client can decide whether to proceed with the provisioning action.
* @throws ProvisioningException if an exception occurs while reviewing the action
*/
public static ResolutionResult reviewProvisioningAction(ProfileModificationAction profileModificationAction)
throws ProvisioningException {
return profileModificationAction.reviewProfileChangeAction(ProvisioningUtils.getProfile());
}
/**
* Performs the given ProvisioningPlan
*
* @param resolutionResult an instance of ResolutionResult and it contains proposed ProvisioningPlan and the status.
* Depending on this status, client can decide whether to proceed with the provisioning action.
* @param applyConfiguration - if true, apply config without restarting
* @throws ProvisioningException if an exception occurs while performing the action
*/
public static void performProvisioningAction(ResolutionResult
resolutionResult, boolean applyConfiguration) throws ProvisioningException {
int severity = resolutionResult.getSummaryStatus().getSeverity();
if (severity != IStatus.ERROR) {
IStatus status = performProvisioningAction(resolutionResult.getProvisioningPlan(),
applyConfiguration);
if (status.getSeverity() == IStatus.ERROR) {
ResolutionResult rs = new ResolutionResult();
rs.addSummaryStatus(status);
String summaryReport = rs.getSummaryReport();
throw new ProvisioningException(summaryReport);
}
} else {
throw new ProvisioningException(resolutionResult.getSummaryReport());
}
}
public static void performProvisioningAction(ResolutionResult resolutionResult)
throws ProvisioningException {
performProvisioningAction(resolutionResult, false);
}
public static ILicense[] getLicensingInformation(ProvisioningPlan provisioningPlan) throws ProvisioningException {
ArrayList<ILicense> licenseArrayList = new ArrayList<ILicense>();
IInstallableUnit[] installableUnits = provisioningPlan.getProfileChangeRequest().getAddedInstallableUnits();
boolean found;
for (IInstallableUnit iu : installableUnits) {
found = false;
ILicense license = IUPropertyUtils.getLicense(iu);
for (ILicense addedLicense : licenseArrayList) {
if (addedLicense.equals(license)) {
found = true;
break;
}
}
if (!found) {
licenseArrayList.add(license);
}
}
return licenseArrayList.toArray(new ILicense[licenseArrayList.size()]);
}
public static IInstallableUnit[] getAllInstalledIUs(QueryContext queryContext) {
queryContext.setQueryable(getProfile());
Query query = new IUPropertyQuery(IInstallableUnit.PROP_TYPE_GROUP, Boolean.TRUE.toString());
queryContext.setQuery(query);
InstalledIUQuery installedIUQuery = new InstalledIUQuery(queryContext);
IInstallableUnit[] groupPropertyTrueIUs = ProvisioningUtils.performIUQuery(installedIUQuery);
query = new IUPropertyQuery(IInstallableUnit.PROP_TYPE_GROUP, Boolean.FALSE.toString());
queryContext.setQuery(query);
installedIUQuery = new InstalledIUQuery(queryContext);
IInstallableUnit[] groupPropertyFalseIUs = ProvisioningUtils.performIUQuery(installedIUQuery);
IInstallableUnit[] allInstalledIUs =
new IInstallableUnit[groupPropertyFalseIUs.length + groupPropertyTrueIUs.length];
System.arraycopy(groupPropertyTrueIUs, 0, allInstalledIUs, 0, groupPropertyTrueIUs.length);
System.arraycopy(groupPropertyFalseIUs, 0, allInstalledIUs, groupPropertyTrueIUs.length, groupPropertyFalseIUs.length);
return allInstalledIUs;
}
/**
* Returns an instance of the SELF Profile. A SELF Profile contains information about installed IUs in the system
*
* @return SELF profile
*/
public static IProfile getProfile() {
IProfileRegistry profileRegistry;
try {
profileRegistry = ServiceHolder.getProfileRegistry();
return profileRegistry.getProfile(IProfileRegistry.SELF);
} catch (ProvisioningException e) {
return null;
}
}
public static IProfile getProfile(String id, long timestamp) {
IProfileRegistry profileRegistry;
try {
profileRegistry = ServiceHolder.getProfileRegistry();
return profileRegistry.getProfile(id, timestamp);
} catch (ProvisioningException e) {
return null;
}
}
public static IInstallableUnit[] sort(IInstallableUnit[] ius) {
Arrays.sort(ius, new Comparator<IInstallableUnit>() {
public int compare(IInstallableUnit arg0, IInstallableUnit arg1) {
return arg0.toString().compareTo(arg1.toString());
}
});
return ius;
}
public static boolean isIUInstalled(IInstallableUnit iu, HashMap<String, IInstallableUnit> installedIUMap) {
IInstallableUnit installedIU = installedIUMap.get(iu.getId());
return installedIU != null && installedIU.getVersion().compareTo(iu.getVersion()) >= 0;
}
public static long[] getProfileTimestamps(String profileID) throws ProvisioningException {
IProfileRegistry profileRegistry = ServiceHolder.getProfileRegistry();
return profileRegistry.listProfileTimestamps(profileID);
}
private static IStatus performProvisioningAction(ProvisioningPlan
provisioningPlan, boolean applyConfiguration) throws ProvisioningException {
PhaseSet set = new DefaultPhaseSet();
ProvisioningContext context = new ProvisioningContext();
IProgressMonitor monitor = new NullProgressMonitor();
IEngine engine = ServiceHolder.getP2Engine();
//The previously used profile instance should be used in this operation as well.
IProfile profile = provisioningPlan.getProfileChangeRequest().getProfile();
if (provisioningPlan.getInstallerPlan() != null) {
// If the phase set calls for download and install, then we want to download everything atomically before
// applying the install plan. This way, we can be sure to install the install handler only if we know
// we will be able to get everything else.
List<Operand> allOperands = new ArrayList<Operand>();
allOperands.addAll(Arrays.asList(provisioningPlan.getOperands()));
allOperands.addAll(Arrays.asList(provisioningPlan.getInstallerPlan().getOperands()));
PhaseSet download = new DownloadPhaseSet();
IStatus downloadStatus = engine.perform(profile, download,
allOperands.toArray(new Operand[allOperands.size()]), context, monitor);
if (!downloadStatus.isOK()) {
return downloadStatus;
}
// we pre-downloaded if necessary. Now perform the plan against the original phase set.
IStatus installerPlanStatus = engine.perform(profile, set,
provisioningPlan.getInstallerPlan().getOperands(), context, monitor);
if (!installerPlanStatus.isOK()) {
return installerPlanStatus;
}
}
IStatus status = engine.perform(profile, set, provisioningPlan.getOperands(), context, monitor);
if (applyConfiguration) {
// Applying configuration without restarting the server. But still there are fixes to be done
try {
Configurator configurator = ServiceHolder.getConfigurator();
configurator.applyConfiguration();
} catch (Exception e) {
throw new ProvisioningException(e.getMessage(), e);
}
}
return status;
}
}