package org.ff4j.web.api.resources; import static org.ff4j.web.FF4jWebConstants.RESOURCE_CACHE; import static org.ff4j.web.FF4jWebConstants.RESOURCE_FEATURES; import static org.ff4j.web.FF4jWebConstants.RESOURCE_GROUPS; import static org.ff4j.web.FF4jWebConstants.STORE_CLEAR; import static org.ff4j.web.FF4jWebConstants.STORE_CREATESCHEMA; /* * #%L * ff4j-web * %% * Copyright (C) 2013 - 2014 Ff4J * %% * 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. * #L% */ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.security.RolesAllowed; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.ff4j.cache.FF4jCacheProxy; import org.ff4j.core.Feature; import org.ff4j.web.FF4jWebConstants; import org.ff4j.web.api.resources.domain.CacheApiBean; import org.ff4j.web.api.resources.domain.FeatureApiBean; import org.ff4j.web.api.resources.domain.FeatureStoreApiBean; import org.ff4j.web.api.resources.domain.GroupDescApiBean; import org.ff4j.web.api.resources.domain.PropertyStoreApiBean; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; /** * WebResource representing the store. * * @author <a href="mailto:cedrick.lunven@gmail.com">Cedrick LUNVEN</a> */ @Path("/ff4j/store") @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({FF4jWebConstants.ROLE_READ}) @Api(value = "/ff4j/store") public class FeatureStoreResource extends AbstractResource { /** * Allows to retrieve feature by its id. * * @param featId * target feature identifier * @return feature is exist */ @GET @ApiOperation( value= "Display information regarding to <b>Features</b>", notes= "other sub resources to be displayed", response=FeatureStoreApiBean.class) @ApiResponses(@ApiResponse(code = 200, message= "status of current ff4j bean")) @Produces(MediaType.APPLICATION_JSON) public FeatureStoreApiBean get() { return new FeatureStoreApiBean(ff4j.getFeatureStore()); } @GET @Path("/" + RESOURCE_FEATURES) @Produces(MediaType.APPLICATION_JSON) @ApiOperation(value= "Display information regarding <b>Features</b>", response=FeatureApiBean.class) @ApiResponses(@ApiResponse(code = 200, message= "get all features")) public List < FeatureApiBean> readFeatures() { Feature[] storeContent = getFeatureStore().readAll().values().toArray(new Feature[0]); List < FeatureApiBean > apiBean = new ArrayList<FeatureApiBean>(); for (Feature feature : storeContent) { apiBean.add(new FeatureApiBean(feature)); } return apiBean; } /** * Access groups part of the API. * * @return groups resource */ @GET @Path("/" + RESOURCE_GROUPS) @Produces(MediaType.APPLICATION_JSON) @ApiOperation(value= "Display information regarding <b>Groups</b>", response=GroupDescApiBean.class) @ApiResponses({@ApiResponse(code = 200, message="Groups resource", response=GroupDescApiBean.class)}) public List < GroupDescApiBean > readGroups() { Map< String, Feature > features = getFeatureStore().readAll(); Map< String , GroupDescApiBean > groups = new HashMap<String, GroupDescApiBean>(); if (features != null && !features.isEmpty()) { // Build groups from features for (Map.Entry<String,Feature> featureName : features.entrySet()) { String groupName = featureName.getValue().getGroup(); // Add current group to list if (groupName != null && !groupName.isEmpty()) { if (!groups.containsKey(groupName)) { groups.put(groupName, new GroupDescApiBean(groupName, new ArrayList<String>())); } groups.get(groupName).getFeatures().add(featureName.getKey()); } } } return new ArrayList<GroupDescApiBean>(groups.values()); } @POST @Path("/" + STORE_CLEAR) @ApiOperation(value= "Delete all <b>Features</b> in store") @ApiResponses(@ApiResponse(code = 200, message= "status of current ff4j bean", response=FeatureStoreApiBean.class)) @Produces(MediaType.APPLICATION_JSON) public FeatureStoreApiBean clearFeatures() { getFeatureStore().clear(); return new FeatureStoreApiBean(ff4j.getFeatureStore()); } @POST @Path("/" + STORE_CREATESCHEMA) @ApiOperation(value= "Create underlying DB schema for store") @ApiResponses(@ApiResponse(code = 200, message= "status of current ff4j bean", response=PropertyStoreApiBean.class)) @Produces(MediaType.APPLICATION_JSON) public FeatureStoreApiBean createSchema() { getFeatureStore().createSchema(); return new FeatureStoreApiBean(ff4j.getFeatureStore()); } /** * Allows to retrieve feature by its id. * * @param featId * target feature identifier * @return feature is exist */ @GET @Path("/" + RESOURCE_CACHE) @Produces(MediaType.APPLICATION_JSON) @ApiOperation(value= "Display information related to <b>Cache</b>") @ApiResponses({ @ApiResponse(code = 200, message= "status of current ff4j monitoring bean", response=CacheApiBean.class), @ApiResponse(code = 404, message= "no cache content provided") }) public Response getStatus() { FF4jCacheProxy cacheProxy = ff4j.getCacheProxy(); if (cacheProxy == null) { return Response.status(Response.Status.NOT_FOUND).entity("Current Store is not cached").build(); } return Response.ok(new CacheApiBean(getFeatureStore())).build(); } /** * POST Operation to clean cache. */ @POST @Path("/" + RESOURCE_CACHE) @Produces(MediaType.TEXT_PLAIN) @ApiOperation(value= "Clear Cache", response=Response.class) @ApiResponses({ @ApiResponse(code = 200, message= "cache is cleard"), @ApiResponse(code = 404, message= "no cache content provided") }) public Response clear() { FF4jCacheProxy cacheProxy = ff4j.getCacheProxy(); if (cacheProxy == null) { return Response.status(Response.Status.NOT_FOUND).entity("Current Store is not cached").build(); } cacheProxy.getCacheManager().clearFeatures(); return Response.ok("Cache has been cleared").build(); } }