/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.wso2.carbon.governance.rest.api;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.governance.api.common.dataobjects.GovernanceArtifact;
import org.wso2.carbon.governance.api.exception.GovernanceException;
import org.wso2.carbon.governance.api.generic.GenericArtifactManager;
import org.wso2.carbon.governance.api.generic.dataobjects.DetachedGenericArtifact;
import org.wso2.carbon.governance.api.generic.dataobjects.GenericArtifact;
import org.wso2.carbon.governance.api.util.GovernanceArtifactConfiguration;
import org.wso2.carbon.governance.api.util.GovernanceUtils;
import org.wso2.carbon.governance.common.GovernanceConfiguration;
import org.wso2.carbon.governance.common.GovernanceConfigurationService;
import org.wso2.carbon.governance.rest.api.internal.PaginationInfo;
import org.wso2.carbon.governance.rest.api.model.AssetState;
import org.wso2.carbon.governance.rest.api.model.LCState;
import org.wso2.carbon.governance.rest.api.model.AssetStateChange;
import org.wso2.carbon.governance.rest.api.model.AssociationModel;
import org.wso2.carbon.governance.rest.api.model.TypedList;
import org.wso2.carbon.governance.rest.api.util.CommonConstants;
import org.wso2.carbon.governance.rest.api.util.Util;
import org.wso2.carbon.registry.common.ui.utils.TreeNodeBuilderUtil;
import org.wso2.carbon.registry.core.Association;
import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.pagination.PaginationContext;
import org.wso2.carbon.registry.core.secure.AuthorizationFailedException;
import org.wso2.carbon.registry.core.service.RegistryService;
import org.wso2.carbon.registry.core.session.UserRegistry;
import org.wso2.carbon.registry.core.utils.RegistryUtils;
import org.wso2.carbon.registry.resource.services.utils.AddResourceUtil;
import org.wso2.carbon.registry.resource.services.utils.CommonUtil;
import org.wso2.carbon.registry.resource.services.utils.GetTextContentUtil;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
//TODO - test this
//@RolesAllowed("GOV-REST")
public class Asset {
public static final String ENDPOINTS = "endpoints";
public static final String ENDPOINT = "endpoint";
public static final String ENDPOINT_LIFE_CYCLE = "EndpointLifeCycle";
public static final String ENDPOINT_LIFE_CYCLE_ACTION_DEACTIVATE = "Deactivate";
public static final String ENDPOINT_LIFE_CYCLE_ACTION_ACTIVATE = "Activate";
public static final String ENDPOINT_LIFE_CYCLE_STATE_ACTIVE = "Active";
public static final String ENDPOINT_MEDIA_TYPE = "application/vnd.wso2-endpoint+xml";
public static final String CONTENT_TYPE_WSDL = "wsdl";
public static final String CONTENT_TYPE_WADL = "wadl";
public static final String CONTENT_TYPE_SWAGGER = "swagger";
public static final String CONTENT_TYPE_SCHEMA = "schema";
public static final String CONTENT_TYPE_POLICY = "policy";
public static final String ATTR_CONTENT_TYPE = "content_type";
public static final String CONTENT_DISPOSITION = "Content-Disposition";
private final Log log = LogFactory.getLog(Asset.class);
private GovernanceConfiguration governanceConfiguration;
@GET
@Path("/types")
@Produces(MediaType.APPLICATION_JSON)
public Response getTypes() throws RegistryException {
return getAssetTypes();
}
@GET
@Path("{assetType : [a-zA-Z][a-zA-Z_0-9]*}")
@Produces(MediaType.APPLICATION_JSON)
public Response getAssets(@PathParam("assetType") String assetType, @Context UriInfo uriInfo,
@HeaderParam("X_TENANT") String tenant)
throws RegistryException {
return getGovernanceAssets(assetType, uriInfo, tenant);
}
@GET
@Path("{assetType : [a-zA-Z][a-zA-Z_0-9]*}/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getAsset(@PathParam("assetType") String assetType, @PathParam("id") String id)
throws RegistryException {
return getGovernanceAsset(assetType, id);
}
@GET
@Path("{assetType : [a-zA-Z][a-zA-Z_0-9]*}/{id}/content")
@Produces(MediaType.APPLICATION_JSON)
public Response getAssetRawContent(@PathParam("assetType") String assetType, @PathParam("id") String id)
throws RegistryException {
return getRawContentOfGovernanceAsset(assetType, id);
}
@GET
@Path("{assetType : [a-zA-Z][a-zA-Z_0-9]*}/endpoints")
@Produces(MediaType.APPLICATION_JSON)
public Response getAssetEndpoints(@PathParam("assetType") String assetType, @Context UriInfo uriInfo)
throws RegistryException {
return getGovernanceEndpointAssets(assetType, null, uriInfo);
}
@GET
@Path("{assetType : [a-zA-Z][a-zA-Z_0-9]*}/{id}/endpoints")
@Produces(MediaType.APPLICATION_JSON)
public Response getAssetEndpoints(@PathParam("assetType") String assetType, @PathParam("id") String id,
@Context UriInfo uriInfo) throws RegistryException {
return getGovernanceEndpointAssets(assetType, id, uriInfo);
}
@POST
@Path("{assetType : [a-zA-Z][a-zA-Z_0-9]*}")
@Consumes(MediaType.APPLICATION_JSON)
public Response createAsset(@PathParam("assetType") String assetType, GenericArtifact genericArtifact,
@Context UriInfo uriInfo) throws RegistryException {
return createGovernanceAsset(assetType, (DetachedGenericArtifact) genericArtifact, Util.getBaseURL(uriInfo));
}
@PUT
@Path("{assetType : [a-zA-Z][a-zA-Z_0-9]*}/{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response modifyAsset(@PathParam("assetType") String assetType, @PathParam("id") String id,
GenericArtifact genericArtifact, @Context UriInfo uriInfo) throws RegistryException {
return modifyGovernanceAsset(assetType, id, (DetachedGenericArtifact) genericArtifact, Util.getBaseURL(uriInfo));
}
@DELETE
@Path("{assetType : [a-zA-Z][a-zA-Z_0-9]*}/{id}")
public Response deleteAsset(@PathParam("assetType") String assetType, @PathParam("id") String id)
throws RegistryException {
return deleteGovernanceAsset(assetType, id);
}
@GET
@Path("{assetType : [a-zA-Z][a-zA-Z_0-9]*}/{id}/states")
@Produces(MediaType.APPLICATION_JSON)
public Response getAssetStates(@PathParam("assetType") String assetType, @PathParam("id") String id,
@Context UriInfo uriInfo) throws RegistryException {
String lc = uriInfo.getQueryParameters().getFirst("lc");
return getGovernanceAssetStates(assetType, id, lc);
}
@PUT
@Path("{assetType : [a-zA-Z][a-zA-Z_0-9]*}/{id}/states")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response updateLCState(@PathParam("assetType") String assetType, @PathParam("id") String id,
AssetStateChange stateChange,
@Context UriInfo uriInfo) throws RegistryException {
return updateLCState(assetType, id, stateChange);
}
//---- Endpoint REST API -----------------------
@GET
@Path("/endpoints")
@Produces(MediaType.APPLICATION_JSON)
public Response getEndpoints(@Context UriInfo uriInfo, @HeaderParam("X_TENANT") String tenant) throws RegistryException {
return getGovernanceAssets(ENDPOINTS, uriInfo, tenant);
}
@GET
@Path("/endpoints/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getEndpoint(@PathParam("id") String id) throws RegistryException {
return getGovernanceEndpoint(id);
}
@POST
@Path("/endpoints")
@Consumes(MediaType.APPLICATION_JSON)
public Response createEndpoint(GenericArtifact genericArtifact, @Context UriInfo uriInfo)
throws RegistryException {
return createGovernanceAsset(ENDPOINTS, (DetachedGenericArtifact) genericArtifact, Util.getBaseURL(uriInfo));
}
@POST
@Path("/endpoints/{assetType : [a-zA-Z][a-zA-Z_0-9]*}")
@Consumes(MediaType.APPLICATION_JSON)
public Response createEndpoint(@PathParam("assetType") String assetType,
GenericArtifact genericArtifact, @Context UriInfo uriInfo) throws RegistryException {
return createEndpointWithAssociation(assetType, null, uriInfo, genericArtifact);
}
@POST
@Path("/endpoints/{assetType : [a-zA-Z][a-zA-Z_0-9]*}/{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response createEndpoint(@PathParam("assetType") String assetType, @PathParam("id") String id,
GenericArtifact genericArtifact, @Context UriInfo uriInfo) throws RegistryException {
return createEndpointWithAssociation(assetType, id, uriInfo, genericArtifact);
}
@PUT
@Path("/endpoints/{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response modifyEndpoint(@PathParam("id") String id,
GenericArtifact genericArtifact, @Context UriInfo uriInfo) throws RegistryException {
//TODO - IMO it's incorrect to allow endpoint edit instead use create/delete through REST API WDYT ?
// return modifyGovernanceAsset(ENDPOINTS, id, (DetachedGenericArtifact) genericArtifact, Util.getBaseURL(uriInfo));
return Response.status(Response.Status.NOT_FOUND).build();
}
@DELETE
@Path("/endpoints/{id}")
public Response deleteEndpoint(@PathParam("id") String id) throws RegistryException {
return deleteGovernanceAsset("endpoints", id);
}
@GET
@Path("/endpoints/{id}/states")
@Produces(MediaType.APPLICATION_JSON)
public Response getEndpointStates(@PathParam("id") String id,
@Context UriInfo uriInfo) throws RegistryException {
String lc = uriInfo.getQueryParameters().getFirst("lc");
return getEndpointStates(id, lc);
}
@POST
@Path("/endpoints/activate/{id}")
public Response endpointActivate(@PathParam("id") String id,
@Context UriInfo uriInfo) throws RegistryException {
return endpointActivate(id);
}
@POST
@Path("/endpoints/deactivate/{id}")
public Response endpointDeactivate(@PathParam("id") String id,
@Context UriInfo uriInfo) throws RegistryException {
return endpointDeactivate(id);
}
@GET
@Path("{assetType : [a-zA-Z][a-zA-Z_0-9]*}/{id}/associations")
@Produces(MediaType.APPLICATION_JSON)
public Response getAssociations(@PathParam("assetType") String assetType, @PathParam("id") String id,
@Context UriInfo uriInfo) throws RegistryException {
return getGovernanceAssetAssociation(assetType, id, uriInfo);
}
protected Registry getUserRegistry() throws RegistryException {
CarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
RegistryService registryService = (RegistryService) carbonContext.
getOSGiService(RegistryService.class, null);
return registryService.getGovernanceUserRegistry(carbonContext.getUsername(), carbonContext.getTenantId());
}
private Response getEndpointStates(String id, String lc) throws RegistryException {
GenericArtifactManager manager = new GenericArtifactManager(getUserRegistry(), ENDPOINT);
GenericArtifact artifact = manager.getGenericArtifact(id);
if (artifact != null) {
String defaultState = artifact.getLifecycleState(ENDPOINT_LIFE_CYCLE);
if (defaultState != null && ENDPOINT_LIFE_CYCLE_STATE_ACTIVE.equals(defaultState)) {
runEndpointStateManagementJob(artifact);
}
return getGovernanceAssetStates(artifact, lc);
}
return Response.status(Response.Status.NOT_FOUND).build();
}
private Response endpointActivate(String id) throws RegistryException {
GenericArtifact artifact = getUniqueAsset(ENDPOINT, id);
if(artifact != null){
String currentState = artifact.getLifecycleState(ENDPOINT_LIFE_CYCLE);
//TODO - If there is a better way to update last update time only then change this line as it's very costly.
if ("Active".equals(currentState)) {
getUserRegistry().invokeAspect(artifact.getPath(), ENDPOINT_LIFE_CYCLE,
ENDPOINT_LIFE_CYCLE_ACTION_DEACTIVATE, Collections.<String, String>emptyMap());
}
getUserRegistry().invokeAspect(artifact.getPath(), ENDPOINT_LIFE_CYCLE,
ENDPOINT_LIFE_CYCLE_ACTION_ACTIVATE, Collections.<String, String>emptyMap());
return Response.ok().build();
} else {
return Response.status(Response.Status.NOT_FOUND).build();
}
}
private Response endpointDeactivate(String id) throws RegistryException {
GenericArtifact artifact = getUniqueAsset(ENDPOINT, id);
if(artifact != null){
String currentState = artifact.getLifecycleState(ENDPOINT_LIFE_CYCLE);
if ("Active".equals(currentState)) {
getUserRegistry().invokeAspect(artifact.getPath(), ENDPOINT_LIFE_CYCLE,
ENDPOINT_LIFE_CYCLE_ACTION_DEACTIVATE, Collections.<String, String>emptyMap());
}
return Response.ok().build();
} else {
return Response.status(Response.Status.NOT_FOUND).build();
}
}
private Response createEndpointWithAssociation(String assetType, String id, UriInfo uriInfo,
GenericArtifact genericArtifact) throws RegistryException {
String shortName = Util.getShortName(assetType);
if (validateAssetType(shortName)) {
GenericArtifactManager manager = getGenericArtifactManager(ENDPOINT);
GenericArtifact newArtifact = ((DetachedGenericArtifact) genericArtifact).makeRegistryAware(manager);
Response response = persistGovernanceAsset(ENDPOINTS, manager, newArtifact, Util.getBaseURL(uriInfo));
createEndpointAssociation(shortName, id, uriInfo, newArtifact);
return response;
}
return validationFail(shortName);
}
private void createEndpointAssociation(String shortName, String id, UriInfo uriInfo,
GovernanceArtifact genericArtifact) throws RegistryException {
GenericArtifact source = getUniqueAsset(shortName, id, uriInfo);
if (source != null) {
source.addBidirectionalAssociation(Util.ENDPOINT_ASSOCIATION_BELONG_TO, Util.ENDPOINT_ASSOCIATION_USE,
genericArtifact);
}
}
private String createQuery(UriInfo uriInfo) {
StringBuilder builder = new StringBuilder("");
MultivaluedMap<String, String> queryParam = uriInfo.getQueryParameters();
Util.excludePaginationParameters(queryParam);
Iterator<Map.Entry<String, List<String>>> iterator = queryParam.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, List<String>> entry = iterator.next();
String value = entry.getValue().get(0);
if (value != null && !"tenant".equals(entry.getKey())) {
builder.append(entry.getKey() + "=" + value);
}
if (iterator.hasNext()) {
builder.append("&");
}
}
if (log.isDebugEnabled()) {
log.debug("Query : " + builder.toString());
}
return builder.toString();
}
private Response getAssetTypes() throws RegistryException {
List<String> shortNames = new ArrayList<>();
List<GovernanceArtifactConfiguration> configurations = GovernanceUtils.findGovernanceArtifactConfigurations
(getUserRegistry());
for (GovernanceArtifactConfiguration configuration : configurations) {
shortNames.add(configuration.getSingularLabel());
}
return Response.ok().entity(shortNames).build();
}
private Response updateLCState(String assetType, String id, AssetStateChange stateChange) throws RegistryException {
String shortName = Util.getShortName(assetType);
if(validateAssetType(shortName)){
GenericArtifactManager manager = new GenericArtifactManager(getUserRegistry(), shortName);
GenericArtifact artifact = manager.getGenericArtifact(id);
if (artifact != null) {
//TODO - change to Gov level
if(stateChange.getParameters().size() > 0) {
getUserRegistry().invokeAspect(artifact.getPath(), stateChange.getLifecycle(), "itemClick", stateChange.getParameters());
}
getUserRegistry().invokeAspect(artifact.getPath(), stateChange.getLifecycle(),
stateChange.getAction(), stateChange.getParameters());
return getGovernanceAssetStates(artifact, null);
}
return Response.ok().build();
}
return validationFail(shortName);
}
private Response getGovernanceAssetStates(String assetType, String id, String lcName) throws RegistryException {
String shortName = Util.getShortName(assetType);
GenericArtifactManager manager = new GenericArtifactManager(getUserRegistry(), shortName);
GenericArtifact artifact = manager.getGenericArtifact(id);
return getGovernanceAssetStates(artifact, lcName);
}
private Response getGovernanceAssetStates(GenericArtifact artifact, String lcName) throws RegistryException {
if (artifact != null) {
// lc == null means user look for all LCs
AssetState assetState = new AssetState();
if (lcName != null) {
LCState lCState = getAssetState(artifact, lcName);
assetState.setLcState(lCState);
return Response.ok().entity(assetState).build();
} else {
String[] stateNames = artifact.getLifecycleNames();
if (stateNames != null) {
List<LCState> list = new ArrayList<>();
for (String name : stateNames) {
LCState lCState = getAssetState(artifact, name);
list.add(lCState);
}
assetState.setLcStates(list);
return Response.ok().entity(assetState).build();
}
}
}
return Response.ok().entity(null).build();
}
private LCState getAssetState(GenericArtifact artifact, String name) throws RegistryException {
UserRegistry userRegistry = (UserRegistry) getUserRegistry();
Resource resource = userRegistry.get(artifact.getPath());
String artifactLCState = resource.getProperty("registry.lifecycle." + name + ".state");
String[] aspects = userRegistry.getAspectActions(artifact.getPath(), name);
LCState LCState = new LCState(artifactLCState, name);
for (String action:aspects ) {
LCState.addActions(action);
}
return LCState;
}
private Response modifyGovernanceAsset(String assetType, String id, DetachedGenericArtifact genericArtifact,
String baseURL) throws RegistryException {
String shortName = Util.getShortName(assetType);
try {
GenericArtifactManager manager = getGenericArtifactManager(shortName);
GenericArtifact artifact = genericArtifact.makeRegistryAware(manager);
artifact.setId(id);
manager.updateGenericArtifact(artifact);
//Use 'generateLink' method with four parameters.
//Fix for REGISTRY-3129
URI link = new URL(Util.generateLink(assetType, id, baseURL, false)).toURI();
return Response.created(link).build();
} catch (MalformedURLException | URISyntaxException e) {
throw new GovernanceException(e);
}
}
private Response createGovernanceAsset(String assetType, DetachedGenericArtifact genericArtifact,
String baseURL) throws RegistryException {
String shortName = Util.getShortName(assetType);
if (validateAssetType(shortName)){
if (isContentType(shortName, genericArtifact)) {
String[][] propertyArray = new String[2][2];
propertyArray[0][0] = CommonConstants.VERSION;
propertyArray[0][1] = genericArtifact.getAttribute(CommonConstants.OVERVIEW_VERSION);
propertyArray[1][0] = CommonConstants.RESOURCE_SOURCE;
propertyArray[1][1] = CommonConstants.GOVERNANCE_API;
Registry registry = getUserRegistry();
// overview_path(storage path) is not mandatory for known asset types such as wsdl, wadl, swagger,etc...
// For unknown asset types '/_system/governance/' will be appended by the system
boolean isSuccessful = importResourceWithRegistry(registry,
genericArtifact.getAttribute(CommonConstants.OVERVIEW_PATH) + genericArtifact
.getAttribute(CommonConstants.OVERVIEW_VERSION),
genericArtifact.getAttribute(CommonConstants.OVERVIEW_NAME),
genericArtifact.getAttribute(CommonConstants.OVERVIEW_TYPE), null,
genericArtifact.getAttribute(CommonConstants.OVERVIEW_URL), null, propertyArray);
if (isSuccessful) {
return Response.status(Response.Status.CREATED).build();
} else {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
} else {
try {
GenericArtifactManager manager = getGenericArtifactManager(shortName);
GenericArtifact artifact = genericArtifact.makeRegistryAware(manager);
manager.addGenericArtifact(artifact);
URI link = new URL(Util.generateLink(assetType, artifact.getId(), baseURL, false)).toURI();
return Response.created(link).build();
} catch (MalformedURLException | URISyntaxException e) {
throw new GovernanceException(e);
}
}
}
return validationFail(shortName);
}
/**
* Adding content type rxt resource to registry.
*
* @param registry registry instance.
* @param parentPath storage path if have any.
* @param resourceName user defend resource name.
* @param mediaType registry media type.
* @param description resource description if have any.
* @param fetchURL resource URL.
* @param symlinkLocation symlink location if have any.
* @param properties resource properties.
* @return isSuccessful is successful or not.
* @throws RegistryException
*/
private boolean importResourceWithRegistry(Registry registry, String parentPath, String resourceName,
String mediaType, String description, String fetchURL, String symlinkLocation, String[][] properties)
throws RegistryException {
if (RegistryUtils.isRegistryReadOnly(registry.getRegistryContext())) {
return false;
}
// Fix for file importation security verification - FileSystemImportationSecurityHotFixTestCase
if (StringUtils.isNotBlank(fetchURL) && fetchURL.toLowerCase().startsWith("file:")) {
String msg = "The source URL must not be file in the server's local file system";
throw new RegistryException(msg);
}
// Adding Source URL as property to end of the properties array.
String[][] newProperties = CommonUtil.setProperties(properties, "sourceURL", fetchURL);
// Data is directed to below AddResourceUtil.addResource from ImportResourceUtil.importResource
// Hence resource upload path will now go through put.
try {
AddResourceUtil.addResource(CommonUtil.calculatePath(parentPath, resourceName), mediaType, description,
GetTextContentUtil.getByteContent(fetchURL), symlinkLocation, registry, newProperties);
} catch (Exception e) {
throw new GovernanceException("Error occurred while adding the resource.", e);
}
return true;
}
private void createContentAsset(String shortName, DetachedGenericArtifact genericArtifact)
throws GovernanceException {
//TODO
}
private boolean isContentType(String shortName, DetachedGenericArtifact genericArtifact)
throws GovernanceException {
String name = shortName.toLowerCase();
if (shortName != null && !shortName.isEmpty()) {
if (CONTENT_TYPE_WSDL.equals(name) || CONTENT_TYPE_WADL.equals(name) || CONTENT_TYPE_SWAGGER.equals(name) ||
CONTENT_TYPE_SCHEMA.equals(name) || CONTENT_TYPE_POLICY.equals(name)) {
return true;
} else {
String contentType = genericArtifact.getAttribute(ATTR_CONTENT_TYPE);
if (contentType != null && contentType.toLowerCase().equals("true")) {
return true;
}
}
}
return false;
}
private Response persistGovernanceAsset(String assetType, GenericArtifactManager manager, GenericArtifact
genericArtifact, String baseURL) throws RegistryException {
try {
manager.addGenericArtifact(genericArtifact);
URI link = new URL(Util.generateLink(assetType, genericArtifact.getId(), baseURL, false)).toURI();
return Response.created(link).build();
} catch (MalformedURLException | URISyntaxException e) {
throw new GovernanceException(e);
}
}
private Response deleteGovernanceAsset(String assetType, String id) throws RegistryException {
String shortName = Util.getShortName(assetType);
if (validateAssetType(shortName)) {
GenericArtifactManager manager = getGenericArtifactManager(shortName);
GenericArtifact artifact = getUniqueAsset(shortName, id);
if (artifact != null) {
manager.removeGenericArtifact(artifact.getId());
return Response.noContent().build();
} else {
return Response.status(Response.Status.NOT_FOUND).build();
}
}
return validationFail(shortName);
}
private Response getGovernanceAssets(String assetType, UriInfo uriInfo, String tenantHeader)
throws RegistryException {
String shortName = Util.getShortName(assetType);
if (validateAssetType(shortName)) {
PaginationInfo pagination = Util.getPaginationInfo(uriInfo.getQueryParameters(), tenantHeader);
String query = createQuery(uriInfo);
pagination.setQuery(query);
List<GenericArtifact> artifacts = getAssetList(shortName, query, pagination);
if (artifacts.size() > 0) {
if (artifacts.size() >= pagination.getCount()) {
pagination.setMorePages(true);
}
TypedList<GenericArtifact> typedList = new TypedList<>(GenericArtifact.class, shortName, artifacts, pagination);
return Response.ok().entity(typedList).build();
} else {
return Response.status(Response.Status.NOT_FOUND).build();
}
} else {
return validationFail(shortName);
}
}
private Response getGovernanceEndpointAssets(String assetType, String id,
UriInfo uriInfo) throws RegistryException {
String shortName = Util.getShortName(assetType);
if (validateAssetType(shortName)) {
GenericArtifact currentAsset = getUniqueAsset(shortName, id, uriInfo);
if (currentAsset != null) {
List<GovernanceArtifact> endpoints = new ArrayList<>();
Association[] associations = getUserRegistry().getAssociations(currentAsset.getPath(),
Util.ENDPOINT_ASSOCIATION_BELONG_TO);
if (associations.length > 0) {
for (Association association : associations) {
GovernanceArtifact artifact = GovernanceUtils.retrieveGovernanceArtifactByPath
(getUserRegistry(), association.getDestinationPath());
if(ENDPOINT_MEDIA_TYPE.equals(artifact.getMediaType())) {
endpoints.add(artifact);
}
}
TypedList<GovernanceArtifact> typedList = new TypedList<>(GovernanceArtifact.class, ENDPOINT,
endpoints, null);
return Response.ok().entity(typedList).build();
}
}
return Response.status(Response.Status.NOT_FOUND).build();
} else {
return validationFail(shortName);
}
}
private Response getGovernanceAsset(String assetType, String id) throws RegistryException {
String shortName = Util.getShortName(assetType);
if (validateAssetType(shortName)) {
GenericArtifact artifact = getUniqueAsset(shortName, id);
if (artifact != null) {
TypedList<GenericArtifact> typedList = new TypedList<>(GenericArtifact.class, shortName,
Arrays.asList(artifact), null);
return Response.ok().entity(typedList).build();
// Check whether artifact is actually does not exists or we are getting null because of anonymous user.
} else if (isAnonymousUser()) {
return handleStatusCode(id);
} else {
return Response.status(Response.Status.NOT_FOUND).build();
}
} else {
return validationFail(shortName);
}
}
private Response handleStatusCode(String id) throws RegistryException {
String artifactPath = GovernanceUtils.getArtifactPath(getUserRegistry(), id);
try {
getUserRegistry().get(artifactPath);
} catch (AuthorizationFailedException e) {
return Response.status(401).header("WWW-Authenticate", "Basic Realm=\"WSO2-Registry\"").build();
}
return Response.status(Response.Status.NOT_FOUND).build();
}
private boolean isAnonymousUser() {
return CarbonConstants.REGISTRY_ANONNYMOUS_USERNAME.equals
(CarbonContext.getThreadLocalCarbonContext().getUsername());
}
private Response getRawContentOfGovernanceAsset(String assetType, String id) throws RegistryException {
String shortName = Util.getShortName(assetType);
if (validateAssetType(shortName)) {
GenericArtifact artifact = getUniqueAsset(shortName, id);
if (artifact != null) {
Resource resource = getUserRegistry().get(artifact.getPath());
String mediaType = getMediaTypeForDownloading(artifact.getMediaType());
if ("wsdl".equals(shortName) || "wadl".equals(shortName) || "schema".equals(shortName) || "policy".equals(shortName)){
return Response.ok(changeContent(resource.getContentStream(), getUserRegistry(), artifact.getPath())).type(mediaType).
header(CONTENT_DISPOSITION, "filename=" + getFileName(shortName, artifact)).build();
} else {
return Response.ok(resource.getContentStream()).type(mediaType).
header(CONTENT_DISPOSITION, "filename=" + getFileName(shortName, artifact)).build();
}
// Check whether artifact is actually does not exists or we are getting null because of anonymous user.
} else if (isAnonymousUser()) {
return handleStatusCode(id);
} else {
return Response.status(Response.Status.NOT_FOUND).build();
}
} else {
return validationFail(shortName);
}
}
private String getMediaTypeForDownloading(String mediaType) {
return mediaType.substring(0, mediaType.indexOf('/') + 1) + mediaType.substring(mediaType.indexOf('+') + 1);
}
private String getFileName(String shortName, GenericArtifact artifact) throws RegistryException {
if (isContentType(shortName)) {
return artifact.getPath().substring(artifact.getPath().lastIndexOf('/') + 1);
} else {
GovernanceArtifactConfiguration config = GovernanceUtils.
findGovernanceArtifactConfiguration(shortName, getUserRegistry());
return artifact.getAttribute(config.getArtifactNameAttribute());
}
}
public String changeContent(InputStream content, Registry registry, String currentPath) throws GovernanceException {
String myString = null;
List<String> references = new ArrayList<>();
try {
myString = IOUtils.toString(content, "UTF-8");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// Use the factory to create a builder
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(myString));
Document doc = builder.parse(is);
NodeList list = doc.getElementsByTagName("*");
for (int i = 0; i < list.getLength(); i++) {
Element element = (Element) list.item(i);
if (element.hasAttribute("schemaLocation")) {
references.add(element.getAttribute("schemaLocation"));
}
}
CarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
for (String links : references) {
String link = RegistryUtils.getAbsolutePath(registry.getRegistryContext(), links);
String registryUrl = TreeNodeBuilderUtil.calculateAbsolutePath(currentPath, link);
if (registry.resourceExists(registryUrl)) {
GovernanceArtifact artifact = GovernanceUtils.retrieveGovernanceArtifactByPath(registry, registryUrl);
//Here we are calculating relative path to governance rest api
String newLink = "./../../" + Util.getResourceName(getBelongToAssetShortName(artifact)) + "/" +
artifact.getId() + "/content?tenant=" + carbonContext.getTenantDomain();
myString = myString.replace(links, newLink);
}
}
} catch (ParserConfigurationException | SAXException | IOException e) {
//ignore exception due to swagger and other types
} catch (RegistryException e) {
log.warn("Error occurred while reading resource from the regsitry ");
}
return myString;
}
private boolean isContentType(String shortName) throws RegistryException {
GovernanceArtifactConfiguration config = GovernanceUtils.findGovernanceArtifactConfiguration(shortName,
getUserRegistry());
if (config.getExtension() != null) {
return true;
} else {
return false;
}
}
private GenericArtifactManager getGenericArtifactManager(String shortName) throws RegistryException {
return new GenericArtifactManager(getUserRegistry(), shortName);
}
private List<GenericArtifact> getAssetList(String assetType, String query, PaginationInfo pagination)
throws RegistryException {
Registry registry = getUserRegistry();
GenericArtifactManager artifactManager = new GenericArtifactManager(registry, assetType);
if (pagination != null) {
PaginationContext.init(pagination.getStart(), pagination.getCount(), pagination.getSortOrder(),
pagination.getSortBy(), pagination.getLimit());
}
GenericArtifact[] genericArtifacts = artifactManager.findGovernanceArtifacts(query);
PaginationContext.destroy();
return Arrays.asList(genericArtifacts);
}
private GenericArtifact getUniqueAsset(String assetType, String id) throws RegistryException {
Registry registry = getUserRegistry();
GenericArtifactManager artifactManager = new GenericArtifactManager(registry, assetType);
return artifactManager.getGenericArtifact(id);
}
private GenericArtifact getUniqueAsset(String shortName, String id, UriInfo uriInfo) throws RegistryException {
if (id != null) {
return getUniqueAsset(shortName, id);
} else {
String query = createQuery(uriInfo);
List<GenericArtifact> artifacts = getAssetList(shortName, query, null);
if (artifacts.size() == 1) {
return artifacts.get(0);
}
}
return null;
}
private boolean validateAssetType(String assetType) throws RegistryException {
if (assetType != null) {
Registry registry = getUserRegistry();
for (GovernanceArtifactConfiguration artifactConfiguration :
GovernanceUtils.findGovernanceArtifactConfigurations(registry)) {
if (artifactConfiguration.getKey().equals(assetType)) {
return true;
}
}
}
return false;
}
private Response validationFail(String assetType) {
return Response.status(Response.Status.NOT_FOUND).entity("Asset type " + assetType + " not found.").build();
}
private Response getGovernanceEndpoint(String id) throws RegistryException {
String shortName = Util.getShortName(ENDPOINTS);
if (validateAssetType(shortName)) {
GenericArtifact artifact = getUniqueAsset(shortName, id);
if (artifact != null) {
GovernanceArtifact belongToAsset = getBelongtoAsset(artifact);
if (belongToAsset != null) {
includeBelongToAssetInfo(artifact, belongToAsset);
}
if (artifact != null) {
TypedList<GenericArtifact> typedList = new TypedList<>(GenericArtifact.class, shortName,
Arrays.asList(artifact), null);
return Response.ok().entity(typedList).build();// Check whether artifact is actually does not exists or we are getting null because of anonymous user.
// Check whether artifact is actually does not exists or we are getting null because of anonymous user.
} else if (isAnonymousUser()) {
return handleStatusCode(id);
}
}
return Response.status(Response.Status.NOT_FOUND).build();
} else {
return validationFail(shortName);
}
}
private void includeBelongToAssetInfo(GenericArtifact artifact, GovernanceArtifact belongToAsset)
throws RegistryException {
String belongToAssetID = getBelongToAssetID(belongToAsset);
String belongToAssetShortName = getBelongToAssetShortName(belongToAsset);
artifact.addAttribute(Util.TEMP_BELONG_TO_ASSET_ID, belongToAssetID);
artifact.addAttribute(Util.TEMP_BELONG_TO_ASSET_SHORT_NAME, belongToAssetShortName);
}
private String getBelongToAssetShortName(GovernanceArtifact belongToAsset) throws RegistryException {
String mediaType = belongToAsset.getMediaType();
GovernanceArtifactConfiguration configuration = GovernanceUtils
.findGovernanceArtifactConfigurationByMediaType(mediaType, getUserRegistry());
if (configuration != null) {
return configuration.getKey();
}
return null;
}
private String getBelongToAssetID(GovernanceArtifact belongToAsset) {
return belongToAsset.getId();
}
private GovernanceArtifact getBelongtoAsset(GovernanceArtifact artifact) throws RegistryException {
Association[] associations = getUserRegistry().getAssociations(artifact.getPath(),
Util.ENDPOINT_ASSOCIATION_BELONG_TO);
if (associations.length > 0) {
Association association = associations[0];
if (association != null) {
String sourcePath = association.getSourcePath();
GovernanceArtifact source = GovernanceUtils.retrieveGovernanceArtifactByPath(getUserRegistry(),
sourcePath);
return (GovernanceArtifact) source;
}
}
return null;
}
private void runEndpointStateManagementJob(GenericArtifact artifact) throws RegistryException {
GovernanceConfiguration configuration = getGovernanceConfiguration();
if (isEndpointStateManagementEnabled(configuration)) {
long defaultEndpointActiveTime = getDefaultEndpointActiveTime(configuration);
long currentActiveDuration = getCurrentActiveDuration(artifact);
if (currentActiveDuration > defaultEndpointActiveTime) {
//make endpoint inactive
getUserRegistry().invokeAspect(artifact.getPath(), ENDPOINT_LIFE_CYCLE,
ENDPOINT_LIFE_CYCLE_ACTION_DEACTIVATE,
Collections.<String, String>emptyMap());
}
}
}
private long getCurrentActiveDuration(GenericArtifact artifact) throws RegistryException {
/*
TODO -
Following last modified time based duration calculation is not accurate instead use one of following
approaches.
1. Register getLifeCycleManagementService as a OSGi service and get current duration.
2. In case 1. is not efficient use new Cache foe endpoint mgt.
*/
Resource resource = getUserRegistry().get(artifact.getPath());
long lastUpdateMS = resource.getLastModified().getTime();
long currentMS = System.currentTimeMillis();
long durationSeconds = TimeUnit.MILLISECONDS.toSeconds(currentMS - lastUpdateMS);
return durationSeconds;
}
private long getDefaultEndpointActiveTime(GovernanceConfiguration configuration) {
return configuration.getDefaultEndpointActiveDuration();
}
private boolean isEndpointStateManagementEnabled(GovernanceConfiguration configuration) {
return configuration.isEndpointStateManagementEnabled();
}
private GovernanceConfiguration getGovernanceConfiguration() {
if (governanceConfiguration == null) {
GovernanceConfigurationService service = (GovernanceConfigurationService) PrivilegedCarbonContext.
getThreadLocalCarbonContext().getOSGiService(GovernanceConfigurationService.class, null);
governanceConfiguration = service.getGovernanceConfiguration();
}
return governanceConfiguration;
}
/**
* This method is used to get all associations.
*
* @param assetType association type
* @param id artifact id
* @param uriInfo uri information
* @return all associations.
* @throws RegistryException
*/
private Response getGovernanceAssetAssociation(String assetType, String id, UriInfo uriInfo)
throws RegistryException {
String shortName = Util.getShortName(assetType);
if (validateAssetType(shortName)) {
GenericArtifact currentAsset = getUniqueAsset(shortName, id, uriInfo);
if (currentAsset != null) {
List<AssociationModel> associationsList = new ArrayList<>();
Association[] associations = getUserRegistry()
.getAllAssociations(currentAsset.getPath());
if (associations.length > 0) {
for (org.wso2.carbon.registry.core.Association association : associations) {
String artifactPath = association.getDestinationPath();
GovernanceArtifact artifact = GovernanceUtils.retrieveGovernanceArtifactByPath
(getUserRegistry(), artifactPath);
String artifactShortName = GovernanceUtils.getArtifactConfigurationByMediaType
(getUserRegistry(), artifact.getMediaType()).getKey();
String baseURI = Util.getBaseURL(uriInfo);
String selfLink = Util.generateLink(artifactShortName, artifact.getId(), baseURI);
AssociationModel associationModel = new AssociationModel();
associationModel.setAssociationType(association.getAssociationType());
associationModel.setAssociationPath(association.getDestinationPath());
associationModel.setAssociationArtifactType(artifactShortName);
associationModel.setSelfLink(selfLink);
associationsList.add(associationModel);
}
return Response.ok().entity(associationsList).build();
}
}
return Response.status(Response.Status.NOT_FOUND).build();
} else {
return validationFail(shortName);
}
}
}