Merge branch 'product-iots-37-new' into 'master'

Modify the Feature Specification Structure and Modify {deviceType}/features API

Closes product-iots#37

See merge request entgra/carbon-device-mgt!63
revert-70aa11f8
Charitha Goonetilleke 6 years ago
commit 44ab68478f

@ -14,40 +14,41 @@
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
* *
* * Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. * Version 2.0 (the "License"); you may not use this file except
* * in compliance with the License.
* Entgra (pvt) Ltd. licenses this file to you under the Apache License, * You may obtain a copy of the License at
* 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 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.jaxrs.service.api; package org.wso2.carbon.device.mgt.jaxrs.service.api;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Info;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Extension;
import io.swagger.annotations.Tag;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses; import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.ResponseHeader; import io.swagger.annotations.ResponseHeader;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.wso2.carbon.apimgt.annotations.api.Scope; import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes; import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList; import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList;
@ -61,9 +62,9 @@ import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.List;
@SwaggerDefinition( @SwaggerDefinition(
info = @Info( info = @Info(
@ -279,8 +280,18 @@ public interface DeviceTypeManagementService {
value = "The device type name, such as ios, android, windows or fire-alarm.", value = "The device type name, such as ios, android, windows or fire-alarm.",
required = true) required = true)
@PathParam("type") @PathParam("type")
@Size(max = 45) @Size(max = 45) String type,
String type, @ApiParam(
name = "featureType",
value = "Type of the feature, such as operation or policy"
)
@QueryParam("featureType")
String featureType,
@ApiParam(
name = "hidden",
value = "true for hidden operations and false for non hidden operations"
)
String hidden,
@ApiParam( @ApiParam(
name = "If-Modified-Since", name = "If-Modified-Since",
value = "Checks if the requested variant was modified, since the specified date-time.\n" + value = "Checks if the requested variant was modified, since the specified date-time.\n" +

@ -14,27 +14,28 @@
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
* *
* * Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. * Version 2.0 (the "License"); you may not use this file except
* * in compliance with the License.
* Entgra (pvt) Ltd. licenses this file to you under the Apache License, * You may obtain a copy of the License at
* 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 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*
*/ */
package org.wso2.carbon.device.mgt.jaxrs.service.impl; package org.wso2.carbon.device.mgt.jaxrs.service.impl;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.DeviceManagementException;
@ -55,6 +56,7 @@ import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam; import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -107,27 +109,42 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ
@Override @Override
@Path("/{type}/features") @Path("/{type}/features")
public Response getFeatures(@PathParam("type") @Size(max = 45) String type, public Response getFeatures(@PathParam("type") @Size(max = 45) String type,
@QueryParam("featureType") String featureType,
@QueryParam("hidden") String hidden,
@HeaderParam("If-Modified-Since") String ifModifiedSince) { @HeaderParam("If-Modified-Since") String ifModifiedSince) {
List<Feature> features = new ArrayList<>(); List<Feature> features;
DeviceManagementProviderService dms; DeviceManagementProviderService dms;
try { try {
if (StringUtils.isEmpty(type)) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Type cannot be empty.").build()).build();
}
dms = DeviceMgtAPIUtils.getDeviceManagementService(); dms = DeviceMgtAPIUtils.getDeviceManagementService();
FeatureManager fm; FeatureManager fm = dms.getFeatureManager(type);
try {
fm = dms.getFeatureManager(type); if (fm == null) {
} catch (DeviceTypeNotFoundException e) {
return Response.status(Response.Status.NOT_FOUND).entity( return Response.status(Response.Status.NOT_FOUND).entity(
new ErrorResponse.ErrorResponseBuilder() new ErrorResponse.ErrorResponseBuilder().setMessage("No feature manager is " +
.setMessage("No device type found with name '" + type + "'").build()).build(); "registered with the given type '" + type + "'").build()).build();
} }
if (fm != null) {
features = fm.getFeatures(); if (StringUtils.isEmpty(hidden)) {
features = fm.getFeatures(featureType);
} else {
features = fm.getFeatures(featureType, Boolean.valueOf(hidden));
} }
} catch (DeviceManagementException e) { } catch (DeviceManagementException e) {
String msg = "Error occurred while retrieving the list of features of '" + type + "' device type"; String msg = "Error occurred while retrieving the list of [" + type + "] features with params " +
"{featureType: " + featureType + ", hidden: " + hidden + "}";
log.error(msg, e); log.error(msg, e);
return Response.serverError().entity( return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
} catch (DeviceTypeNotFoundException e) {
String msg = "No device type found with name '" + type + "'";
log.error(msg, e);
return Response.status(Response.Status.NOT_FOUND).entity(
new ErrorResponse.ErrorResponseBuilder()
.setMessage(msg).build()).build();
} }
return Response.status(Response.Status.OK).entity(features).build(); return Response.status(Response.Status.OK).entity(features).build();
} }

@ -113,7 +113,7 @@ public class DeviceTypeManagementServiceTest {
public void testGetDeviceTypeFeatures() throws Exception { public void testGetDeviceTypeFeatures() throws Exception {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService); .toReturn(this.deviceManagementProviderService);
Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, MODIFIED_SINCE); Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, null, "false", MODIFIED_SINCE);
Assert.assertNotNull(response, "The response object is null."); Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"The response status should be 200."); "The response status should be 200.");
@ -126,8 +126,9 @@ public class DeviceTypeManagementServiceTest {
FeatureManager featureManager = Mockito.mock(FeatureManager.class); FeatureManager featureManager = Mockito.mock(FeatureManager.class);
Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString())).thenReturn Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString())).thenReturn
(featureManager); (featureManager);
Mockito.when((featureManager).getFeatures()).thenThrow(new DeviceManagementException()); Mockito.when((featureManager).getFeatures(Mockito.anyString())).thenThrow(new DeviceManagementException());
Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, MODIFIED_SINCE); Mockito.when((featureManager).getFeatures(Mockito.anyString(), Mockito.anyBoolean())).thenThrow(new DeviceManagementException());
Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, null, "false", MODIFIED_SINCE);
Assert.assertNotNull(response, "The response object is null."); Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500."); "The response status should be 500.");
@ -140,11 +141,10 @@ public class DeviceTypeManagementServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService); .toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString())).thenReturn(null); Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString())).thenReturn(null);
Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, MODIFIED_SINCE); Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, null, "false", MODIFIED_SINCE);
Assert.assertNotNull(response, "The response object is null."); Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(),
"The response status should be 200."); "The response status should be 404.");
Assert.assertEquals(response.getEntity().toString(), "[]", "The response should be [].");
Mockito.reset(deviceManagementProviderService); Mockito.reset(deviceManagementProviderService);
} }

@ -15,32 +15,92 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.device.mgt.common; package org.wso2.carbon.device.mgt.common;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import io.swagger.annotations.*; import io.swagger.annotations.*;
@ApiModel(value = "Feature", description = "This class carries all information related to a devices enrollment" + @ApiModel(
" status.") value = "Feature",
description = "This class carries all information related to a device feature."
)
public class Feature implements Serializable { public class Feature implements Serializable {
@ApiModelProperty(name = "id", value = "Feature Id.", required = true ) @ApiModelProperty(
name = "id",
value = "Feature Id.",
required = true
)
private int id; private int id;
@ApiModelProperty(name = "code", value = "The code of the feature. For example the code to lock a device" +
" is DEVICE_LOCK.", required = true ) @ApiModelProperty(
name = "code",
value = "The code of the feature. For example the code to lock a device is DEVICE_LOCK.",
required = true
)
private String code; private String code;
@ApiModelProperty(name = "name", value = "A name that describes a feature.", required = true )
@ApiModelProperty(
name = "name",
value = "A name that describes a feature.",
required = true
)
private String name; private String name;
@ApiModelProperty(name = "description", value = "Provides a description of the features..", required = true )
@ApiModelProperty(
name = "description",
value = "Provides a description of the features.",
required = true
)
private String description; private String description;
@ApiModelProperty(name = "deviceType", value = "Provide the device type for the respective feature. " +
"Features allow you to perform operations on any device type, " + @ApiModelProperty(
"such as android, iOS or windows..", required = true ) name = "type",
value = "Type of the feature.",
required = true
)
private String type;
@ApiModelProperty(
name = "hidden",
value = "If the feature is hidden from the UI."
)
private boolean hidden;
@ApiModelProperty(
name = "deviceType",
value = "Provide the device type for the respective feature. Features allow you to perform operations " +
"on any device type, such as android, iOS or windows.",
required = true
)
private String deviceType; private String deviceType;
@ApiModelProperty(name = "metadataEntries", value = "Properties related to features.", required = true ) @ApiModelProperty(
name = "metadataEntries",
value = "Properties related to features.",
required = true
)
private List<MetadataEntry> metadataEntries; private List<MetadataEntry> metadataEntries;
@XmlElement @XmlElement
@ -96,9 +156,27 @@ public class Feature implements Serializable {
this.description = description; this.description = description;
} }
@XmlAttribute
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isHidden() {
return hidden;
}
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
public static class MetadataEntry implements Serializable { public static class MetadataEntry implements Serializable {
private int id; private int id;
private String name;
private Object value; private Object value;
public int getId() { public int getId() {
@ -109,6 +187,14 @@ public class Feature implements Serializable {
this.id = id; this.id = id;
} }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getValue() { public Object getValue() {
return value; return value;
} }

@ -14,7 +14,24 @@
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.device.mgt.common; package org.wso2.carbon.device.mgt.common;
@ -30,6 +47,10 @@ public interface FeatureManager {
List<Feature> getFeatures() throws DeviceManagementException; List<Feature> getFeatures() throws DeviceManagementException;
List<Feature> getFeatures(String type) throws DeviceManagementException;
List<Feature> getFeatures(String type, boolean isHidden) throws DeviceManagementException;
boolean removeFeature(String name) throws DeviceManagementException; boolean removeFeature(String name) throws DeviceManagementException;
boolean addSupportedFeaturesToDB() throws DeviceManagementException; boolean addSupportedFeaturesToDB() throws DeviceManagementException;

@ -14,8 +14,26 @@
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
* *
* Entgra (Pvt) Ltd. 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.device.mgt.extensions.device.type.template.config; package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessType;
@ -33,41 +51,46 @@ import java.util.List;
* <p>The following schema fragment specifies the expected content contained within this class. * <p>The following schema fragment specifies the expected content contained within this class.
* *
* <pre> * <pre>
* &lt;complexType name="Feature"> * <xs:element name="Feature">
* &lt;complexContent> * <xs:complexType>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * <xs:sequence>
* &lt;sequence> * <xs:element name="Name" type="xs:string" />
* &lt;element name="Name" type="{http://www.w3.org/2001/XMLSchema}string"/> * <xs:element name="Description" type="xs:string" />
* &lt;element name="Description" type="{http://www.w3.org/2001/XMLSchema}string"/> * <xs:element name="Operation" type="{}Operation" />
* &lt;element name="Operation" type="{}Operation"/> * </xs:sequence>
* &lt;/sequence> * <xs:attribute name="type" type="xs:string" />
* &lt;attribute name="code" type="{http://www.w3.org/2001/XMLSchema}string" /> * <xs:attribute name="code" type="xs:string" />
* &lt;/restriction> * </xs:complexType>
* &lt;/complexContent> * </xs:element>
* &lt;/complexType>
* </pre> * </pre>
*
*
*/ */
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Feature", propOrder = { @XmlType(name = "Feature", propOrder = {
"name", "name",
"description", "description",
"operation", "metaData" "operation",
"metaData"
}) })
public class Feature { public class Feature {
@XmlElement(name = "Name", required = true) @XmlElement(name = "Name", required = true)
protected String name; protected String name;
@XmlElement(name = "Description", required = true) @XmlElement(name = "Description", required = true)
protected String description; protected String description;
@XmlElement(name = "Operation", required = true)
@XmlElement(name = "Operation")
protected Operation operation; protected Operation operation;
@XmlAttribute(name = "type", required = true)
protected String type;
@XmlAttribute(name = "code") @XmlAttribute(name = "code")
protected String code; protected String code;
@XmlElementWrapper(name = "MetaData") @XmlElementWrapper(name = "MetaData")
@XmlElement(name = "Property", required = true) @XmlElement(name = "Property", required = true)
protected List<String> metaData; private List<String> metaData;
/** /**
* Gets the value of the name property. * Gets the value of the name property.
@ -172,4 +195,12 @@ public class Feature {
public void setMetaData(List<String> metaData) { public void setMetaData(List<String> metaData) {
this.metaData = metaData; this.metaData = metaData;
} }
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
} }

@ -32,15 +32,15 @@ import java.util.List;
* <p>The following schema fragment specifies the expected content contained within this class. * <p>The following schema fragment specifies the expected content contained within this class.
* *
* <pre> * <pre>
* &lt;complexType name="Features"> * <complexType name="Features">
* &lt;complexContent> * <complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence> * <sequence>
* &lt;element name="Feature" type="{}Feature"/> * <element name="Feature" type="{}Feature"/>
* &lt;/sequence> * </sequence>
* &lt;/restriction> * </restriction>
* &lt;/complexContent> * </complexContent>
* &lt;/complexType> * </complexType>
* </pre> * </pre>
* *
* *

@ -0,0 +1,76 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
/**
* Java class for filter complex type.
*
* The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <xs:element name="uiParam" maxOccurs="unbounded">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="property" type="xs:string" />
* <xs:element name="value" type="xs:string" />
* <xs:element name="description" type="xs:string" />
* </xs:sequence>
* </xs:complexType>
* </xs:element>
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
public class Filter {
@XmlElement(name = "property", required = true)
private String property;
@XmlElement(name = "value", required = true)
private String value;
@XmlElement(name = "description", required = true)
private String description;
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

@ -14,7 +14,24 @@
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.device.mgt.extensions.device.type.template.config; package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
@ -27,26 +44,24 @@ import java.util.List;
/** /**
* <p>Java class for FormParameters complex type. * <p>Java class for fromParams complex type.
* *
* <p>The following schema fragment specifies the expected content contained within this class. * <p>The following schema fragment specifies the expected content contained within this class.
* *
* <pre> * <pre>
* &lt;complexType name="FormParameters"> * <complexType name="formParams">
* &lt;complexContent> * <complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence> * <sequence>
* &lt;element name="Parameter" type="{http://www.w3.org/2001/XMLSchema}string"/> * <element name="Parameter" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;/sequence> * </sequence>
* &lt;/restriction> * </restriction>
* &lt;/complexContent> * </complexContent>
* &lt;/complexType> * </complexType>
* </pre> * </pre>
*
*
*/ */
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "FormParameters", propOrder = { @XmlType(name = "formParams", propOrder = {
"parameter" "parameter"
}) })
public class FormParameters { public class FormParameters {
@ -56,7 +71,7 @@ public class FormParameters {
public List<String> getParameter() { public List<String> getParameter() {
if (parameter == null) { if (parameter == null) {
parameter = new ArrayList<String>(); parameter = new ArrayList<>();
} }
return this.parameter; return this.parameter;
} }

@ -14,8 +14,26 @@
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.device.mgt.extensions.device.type.template.config; package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessType;
@ -26,164 +44,71 @@ import javax.xml.bind.annotation.XmlType;
/** /**
* <p>Java class for Operation complex type. * Java class for Operation complex type.
* *
* <p>The following schema fragment specifies the expected content contained within this class. * The following schema fragment specifies the expected content contained within this class.
* *
* <pre> * <pre>
* &lt;complexType name="Operation"> * <xs:element name="Operation">
* &lt;complexContent> * <xs:complexType>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * <xs:sequence>
* &lt;sequence> * <xs:element name="params" type="{}Params"/>
* &lt;element name="QueryParameters" type="{}QueryParameters"/> * <xs:element name="metadata" type="{}OperationMetadata"/>
* &lt;element name="FormParameters" type="{}FormParameters"/> * </xs:sequence>
* &lt;/sequence> * <xs:attribute name="hidden" type="xs:boolean"/>
* &lt;attribute name="context" type="{http://www.w3.org/2001/XMLSchema}string" /> * <xs:attribute name="icon" type="xs:string"/>
* &lt;attribute name="method" type="{http://www.w3.org/2001/XMLSchema}string" /> * </xs:complexType>
* &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" /> * </xs:element>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre> * </pre>
*
*
*/ */
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Operation", propOrder = { @XmlType(name = "Operation", propOrder = {
"queryParameters", "params",
"formParameters" "metadata"
}) })
public class Operation { public class Operation {
@XmlElement(name = "QueryParameters") @XmlElement(name = "params")
protected QueryParameters queryParameters; private Params params;
@XmlElement(name = "FormParameters")
protected FormParameters formParameters;
@XmlAttribute(name = "context")
protected String context;
@XmlAttribute(name = "method")
protected String method;
@XmlAttribute(name = "type")
protected String type;
/**
* Gets the value of the Content Type property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getType() {
return type;
}
/** @XmlElement(name = "metadata", required = true)
* Sets the value of the Content Type property. private OperationMetadata metadata;
*
* @param type
* allowed object is
* {@link String }
*
*/
public void setType(String type) {
this.type = type;
}
/** @XmlAttribute(name = "hidden", required = true)
* Gets the value of the queryParameters property. private boolean hidden;
*
* @return @XmlAttribute(name = "icon")
* possible object is private String icon;
* {@link QueryParameters }
*
*/
public QueryParameters getQueryParameters() {
return queryParameters;
}
/** public Params getParams() {
* Sets the value of the queryParameters property. return params;
*
* @param value
* allowed object is
* {@link QueryParameters }
*
*/
public void setQueryParameters(QueryParameters value) {
this.queryParameters = value;
} }
/** public void setParams(Params params) {
* Gets the value of the formParameters property. this.params = params;
*
* @return
* possible object is
* {@link FormParameters }
*
*/
public FormParameters getFormParameters() {
return formParameters;
} }
/** public OperationMetadata getMetadata() {
* Sets the value of the formParameters property. return metadata;
*
* @param value
* allowed object is
* {@link FormParameters }
*
*/
public void setFormParameters(FormParameters value) {
this.formParameters = value;
} }
/** public void setMetadata(OperationMetadata metadata) {
* Gets the value of the context property. this.metadata = metadata;
*
* @return
* possible object is
* {@link String }
*
*/
public String getContext() {
return context;
} }
/** public String getIcon() {
* Sets the value of the context property. return icon;
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setContext(String value) {
this.context = value;
} }
/** public void setIcon(String icon) {
* Gets the value of the method property. this.icon = icon;
*
* @return
* possible object is
* {@link String }
*
*/
public String getMethod() {
return method;
} }
/** public boolean isHidden() {
* Sets the value of the method property. return hidden;
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setMethod(String value) {
this.method = value;
} }
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
} }

@ -0,0 +1,120 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlType;
import java.util.List;
/**
* Java class for metadata complex type.
*
* The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <xs:element name="metadata">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="uri" type="xs:string" />
* <xs:element name="method" type="xs:string" />
* <xs:element name="contentType" type="xs:string" />
* <xs:element name="permission" type="xs:string" />
* <xs:element name="filters">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="property" type="xs:string" />
* <xs:element name="value" type="xs:string" />
* <xs:element name="description" type="xs:string" />
* </xs:sequence>
* </xs:complexType>
* </xs:element>
* </xs:sequence>
* </xs:complexType>
* </xs:element>
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "metadata", propOrder = {
"uri",
"method",
"contentType",
"permission",
"filterList"
})
public class OperationMetadata {
@XmlElement(name = "uri", required = true)
private String uri;
@XmlElement(name = "method", required = true)
private String method;
@XmlElement(name = "contentType")
private String contentType;
@XmlElement(name = "permission")
private String permission;
@XmlElementWrapper(name = "filters")
@XmlElement(name = "filter")
private List<Filter> filterList;
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getPermission() {
return permission;
}
public void setPermission(String permission) {
this.permission = permission;
}
public List<Filter> getFilterList() {
return filterList;
}
public void setFilters(List<Filter> filterList) {
this.filterList = filterList;
}
}

@ -0,0 +1,78 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* Java class for params complex type.
*
* The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <xs:element name="params">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="queryParams" type="{}QueryParameters"/>
* <xs:element name="formParams" type="{}FormParameters"/>
* <xs:element name="uiParams" type="{}UIParameters"/>
* </xs:sequence>
* </xs:complexType>
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "params")
public class Params {
@XmlElement(name = "queryParams")
private QueryParameters queryParameters;
@XmlElement(name = "formParams")
private FormParameters formParameters;
@XmlElement(name = "uiParams")
private UIParameters uiParameters;
public QueryParameters getQueryParameters() {
return queryParameters;
}
public void setQueryParameters(QueryParameters queryParameters) {
this.queryParameters = queryParameters;
}
public FormParameters getFormParameters() {
return formParameters;
}
public void setFormParameters(FormParameters formParameters) {
this.formParameters = formParameters;
}
public UIParameters getUiParameters() {
return uiParameters;
}
public void setUiParameters(UIParameters uiParameters) {
this.uiParameters = uiParameters;
}
}

@ -14,8 +14,26 @@
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
* *
* Entgra (Pvt) Ltd. 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.device.mgt.extensions.device.type.template.config; package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessType;
@ -27,26 +45,24 @@ import java.util.List;
/** /**
* <p>Java class for QueryParameters complex type. * Java class for queryParams complex type.
* *
* <p>The following schema fragment specifies the expected content contained within this class. * The following schema fragment specifies the expected content contained within this class.
* *
* <pre> * <pre>
* &lt;complexType name="QueryParameters"> * <complexType name="queryParams">
* &lt;complexContent> * <complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence> * <sequence>
* &lt;element name="Parameter" type="{http://www.w3.org/2001/XMLSchema}string"/> * <element name="Parameter" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;/sequence> * </sequence>
* &lt;/restriction> * </restriction>
* &lt;/complexContent> * </complexContent>
* &lt;/complexType> * </complexType>
* </pre> * </pre>
*
*
*/ */
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "QueryParameters", propOrder = { @XmlType(name = "queryParams", propOrder = {
"parameter" "parameter"
}) })
public class QueryParameters { public class QueryParameters {
@ -56,7 +72,7 @@ public class QueryParameters {
public List<String> getParameter() { public List<String> getParameter() {
if (parameter == null) { if (parameter == null) {
parameter = new ArrayList<String>(); parameter = new ArrayList<>();
} }
return this.parameter; return this.parameter;
} }

@ -0,0 +1,134 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import java.util.List;
/**
* Java class for uiParams complex type.
*
* The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <xs:element name="uiParam" maxOccurs="unbounded">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="type" type="xs:string" />
* <xs:element name="name" type="xs:string" />
* <xs:element name="id" type="xs:string" />
* <xs:element name="values">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="value" type="xs:string" />
* </xs:sequence>
* </xs:complexType>
* </xs:element>
* </xs:sequence>
* <xs:attribute name="optional" type="xs:string" />
* </xs:complexType>
* </xs:element>
* </pre>
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
public class UIParameter {
@XmlElement(name = "id", required = true)
protected String id;
@XmlAttribute(name = "optional", required = true)
private boolean optional;
@XmlElement(name = "type", required = true)
protected String type;
@XmlElement(name = "name")
protected String name;
@XmlElement(name = "label")
private String label;
@XmlElement(name = "helper")
private String helper;
@XmlElementWrapper(name = "values")
@XmlElement(name = "value")
protected List<String> value;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getHelper() {
return helper;
}
public void setHelper(String helper) {
this.helper = helper;
}
public List<String> getValue() {
return value;
}
public void setValue(List<String> value) {
this.value = value;
}
public boolean isOptional() {
return optional;
}
public void setOptional(boolean optional) {
this.optional = optional;
}
}

@ -0,0 +1,48 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlElement;
import java.util.List;
/**
* Java class for uiParams complex type.
*
* The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <xs:element name="uiParams">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="uiParam" type="{}UIParameter"/>
* </xs:sequence>
* </xs:complexType>
* </xs:element>
* </pre>
*
*/
public class UIParameters {
@XmlElement(name = "uiParam")
private List<UIParameter> uiParams;
public List<UIParameter> getUiParameterList() {
return this.uiParams;
}
}

@ -16,12 +16,35 @@
* under the License. * under the License.
* *
*/ */
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.device.mgt.extensions.device.type.template.feature; package org.wso2.carbon.device.mgt.extensions.device.type.template.feature;
import org.apache.commons.lang.StringUtils;
import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.Feature; import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager; import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Operation; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Operation;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.OperationMetadata;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Params;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.UIParameter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -37,10 +60,15 @@ public class ConfigurationBasedFeatureManager implements FeatureManager {
private List<Feature> features = new ArrayList<>(); private List<Feature> features = new ArrayList<>();
private static final String METHOD = "method"; private static final String METHOD = "method";
private static final String URI = "uri"; private static final String URI = "uri";
private static final String OPERATION_META = "operationMeta";
private static final String CONTENT_TYPE = "contentType"; private static final String CONTENT_TYPE = "contentType";
private static final String PERMISSION = "permission";
private static final String ICON = "icon";
private static final String FILTERS = "filters";
private static final String PATH_PARAMS = "pathParams"; private static final String PATH_PARAMS = "pathParams";
private static final String QUERY_PARAMS = "queryParams"; private static final String QUERY_PARAMS = "queryParams";
private static final String FORM_PARAMS = "formParams"; private static final String FORM_PARAMS = "formParams";
private static final String UI_PARAMS = "uiParams";
private static final Pattern PATH_PARAM_REGEX = Pattern.compile("\\{(.*?)\\}"); private static final Pattern PATH_PARAM_REGEX = Pattern.compile("\\{(.*?)\\}");
public ConfigurationBasedFeatureManager( public ConfigurationBasedFeatureManager(
@ -50,6 +78,7 @@ public class ConfigurationBasedFeatureManager implements FeatureManager {
deviceFeature.setCode(feature.getCode()); deviceFeature.setCode(feature.getCode());
deviceFeature.setName(feature.getName()); deviceFeature.setName(feature.getName());
deviceFeature.setDescription(feature.getDescription()); deviceFeature.setDescription(feature.getDescription());
deviceFeature.setType(feature.getType());
Operation operation = feature.getOperation(); Operation operation = feature.getOperation();
List<Feature.MetadataEntry> metadataEntries = null; List<Feature.MetadataEntry> metadataEntries = null;
if (feature.getMetaData() != null) { if (feature.getMetaData() != null) {
@ -64,31 +93,53 @@ public class ConfigurationBasedFeatureManager implements FeatureManager {
} }
} }
if (operation != null) { if (operation != null) {
Map<String, Object> apiParams = new HashMap<>(); deviceFeature.setHidden(operation.isHidden());
apiParams.put(METHOD, operation.getMethod().toUpperCase()); Map<String, Object> operationMeta = new HashMap<>();
apiParams.put(URI, operation.getContext()); OperationMetadata metadata = operation.getMetadata();
apiParams.put(CONTENT_TYPE, operation.getType());
List<String> pathParams = new ArrayList<>(); List<String> pathParams = new ArrayList<>();
List<String> queryParams = new ArrayList<>();
List<String> formParams = new ArrayList<>(); if (metadata != null) {
setPathParams(operation.getContext(), pathParams); operationMeta.put(METHOD, metadata.getMethod().toUpperCase());
apiParams.put(PATH_PARAMS, pathParams); operationMeta.put(URI, metadata.getUri());
if (operation.getQueryParameters() != null) { if (StringUtils.isNotEmpty(metadata.getContentType())) {
queryParams = operation.getQueryParameters().getParameter(); operationMeta.put(CONTENT_TYPE, metadata.getContentType());
}
if (StringUtils.isNotEmpty(metadata.getPermission())) {
operationMeta.put(PERMISSION, metadata.getPermission());
}
if (metadata.getFilterList() != null && metadata.getFilterList().size() > 0) {
operationMeta.put(FILTERS, metadata.getFilterList());
}
operationMeta.put(ICON, operation.getIcon());
setPathParams(metadata.getUri(), pathParams);
} }
apiParams.put(QUERY_PARAMS, queryParams); operationMeta.put(PATH_PARAMS, pathParams);
if (operation.getFormParameters() != null) {
formParams = operation.getFormParameters().getParameter(); Params params = operation.getParams();
if (params != null) {
List<String> queryParams = params.getQueryParameters() != null ?
params.getQueryParameters().getParameter() : new ArrayList<>();
List<String> formParams = params.getFormParameters() != null ?
params.getFormParameters().getParameter() : new ArrayList<>();
List<UIParameter> uiParams = params.getUiParameters() != null ?
params.getUiParameters().getUiParameterList() : new ArrayList<>();
operationMeta.put(QUERY_PARAMS, queryParams);
operationMeta.put(UI_PARAMS, uiParams);
operationMeta.put(FORM_PARAMS, formParams);
} }
apiParams.put(FORM_PARAMS, formParams);
if (metadataEntries == null) { if (metadataEntries == null) {
metadataEntries = new ArrayList<>(); metadataEntries = new ArrayList<>();
} }
Feature.MetadataEntry metadataEntry = new Feature.MetadataEntry(); Feature.MetadataEntry metadataEntry = new Feature.MetadataEntry();
metadataEntry.setId(-1); metadataEntry.setId(0);
metadataEntry.setValue(apiParams); metadataEntry.setName(OPERATION_META);
metadataEntry.setValue(operationMeta);
metadataEntries.add(metadataEntry); metadataEntries.add(metadataEntry);
deviceFeature.setMetadataEntries(metadataEntries); deviceFeature.setMetadataEntries(metadataEntries);
} else {
deviceFeature.setHidden(true);
} }
this.features.add(deviceFeature); this.features.add(deviceFeature);
} }
@ -120,6 +171,49 @@ public class ConfigurationBasedFeatureManager implements FeatureManager {
return features; return features;
} }
@Override
public List<Feature> getFeatures(String type) throws DeviceManagementException {
if (StringUtils.isEmpty(type)) {
return this.getFeatures();
}
if (features == null) {
return null;
} else {
List<Feature> filteredFeatures = new ArrayList<>();
for (Feature feature : this.getFeatures()) {
if (type.equals(feature.getType())) {
filteredFeatures.add(feature);
}
}
return filteredFeatures;
}
}
@Override
public List<Feature> getFeatures(String type, boolean isHidden) throws DeviceManagementException {
if (features == null) {
return null;
} else {
List<Feature> filteredFeatures = new ArrayList<>();
if (StringUtils.isEmpty(type)) {
for (Feature feature : this.getFeatures()) {
if (isHidden == feature.isHidden()) {
filteredFeatures.add(feature);
}
}
return filteredFeatures;
} else {
for (Feature feature : this.getFeatures()) {
if (isHidden == feature.isHidden() && type.equals(feature.getType())) {
filteredFeatures.add(feature);
}
}
return filteredFeatures;
}
}
}
@Override @Override
public boolean removeFeature(String name) throws DeviceManagementException { public boolean removeFeature(String name) throws DeviceManagementException {
return false; return false;

@ -92,256 +92,474 @@
</DataSource> </DataSource>
<Features> <Features>
<Feature code="DEVICE_RING"> <Feature type="operation" code="DEVICE_RING">
<Name>Ring</Name> <Name>Ring</Name>
<Description>Ring the device</Description> <Description>Ring the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/ring" method="POST" type="application/json"> <Operation hidden="false" icon="fw-dial-up">
<params/>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/ring</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/ring</permission>
</metadata>
</Operation> </Operation>
<MetaData>
<Property>test</Property>
</MetaData>
</Feature> </Feature>
<Feature code="DEVICE_LOCK"> <Feature type="operation" code="DEVICE_LOCK">
<Name>Device Lock</Name> <Name>Device Lock</Name>
<Description>Lock the device</Description> <Description>Lock the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/lock-devices" method="POST" type="application/json"> <Operation hidden="false" icon="fw-lock">
<params>
<uiParams>
<uiParam optional="true">
<type>text</type>
<id>lock-message</id>
<label>Message to be sent to the device</label>
</uiParam>
<uiParam optional="true">
<type>checkbox</type>
<id>hard-lock</id>
<label>Hard lock enabled</label>
</uiParam>
</uiParams>
</params>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/lock-devices</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/ring</permission>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="DEVICE_LOCATION"> <Feature type="operation" code="DEVICE_LOCATION">
<Name>Location</Name> <Name>Location</Name>
<Description>Request coordinates of device location</Description> <Description>Request coordinates of device location</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/location" method="POST" type="application/json"> <Operation hidden="false" icon="fw-map-location">
<params/>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/location</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/location</permission>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="CLEAR_PASSWORD"> <Feature type="operation" code="CLEAR_PASSWORD">
<Name>Clear Password</Name> <Name>Clear Password</Name>
<Description>Clear current password</Description> <Description>Clear current password (This functionality is only working with profile owners from Android 7.0 API 24 onwards.)</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/clear-password" method="POST" type="application/json"> <Operation hidden="false" icon="fw-clear">
<params/>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/clear-password</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/clear-passwor</permission>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="DEVICE_REBOOT"> <Feature type="operation" code="DEVICE_REBOOT">
<Name>Reboot</Name> <Name>Reboot</Name>
<Description>Reboot the device</Description> <Description>Reboot the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/reboot" method="POST" type="application/json"> <Operation hidden="false" icon="fw-refresh">
<params/>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/reboot</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/reboot</permission>
<filters>
<filter>
<property>ownership</property>
<value>COPE</value>
<description>This feature is only available in COPE/COSU</description>
</filter>
</filters>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="UPGRADE_FIRMWARE"> <Feature type="operation" code="UPGRADE_FIRMWARE">
<Name>Upgrade Firmware</Name> <Name>Upgrade Firmware</Name>
<Description>Upgrade Firmware</Description> <Description>Upgrade Firmware</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/upgrade-firmware" method="POST" type="application/json"> <Operation hidden="false" icon="fw-hardware">
<params>
<uiParams>
<uiParam optional="true">
<type>checkbox</type>
<id>immediate</id>
<label>Instant Upgrade</label>
<helper>Once enabled, device firmware upgrade process will start instantly.</helper>
</uiParam>
<uiParam optional="false">
<type>text</type>
<id>schedule</id>
<label>Enter the date and time to schedule firmware upgrade.</label>
</uiParam>
<uiParam optional="true">
<type>text</type>
<id>server</id>
<label>Enter firmware upgrade server URL (ie. http://abc.com or http://abc.com/ota)</label>
</uiParam>
</uiParams>
</params>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/reboot</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/upgrade-firmware</permission>
<filters>
<filter>
<property>ownership</property>
<value>COPE</value>
<description>This feature is only available in COPE/COSU</description>
</filter>
</filters>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="DEVICE_MUTE"> <Feature type="operation" code="DEVICE_MUTE">
<Name>Mute</Name> <Name>Mute</Name>
<Description>Enable mute in the device</Description> <Description>Enable mute in the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/mute" method="POST" type="application/json"> <Operation hidden="false" icon="fw-mute">
<params/>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/mute</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/mute</permission>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="NOTIFICATION"> <Feature type="operation" code="NOTIFICATION">
<Name>Message</Name> <Name>Message</Name>
<Description>Send message</Description> <Description>Send message</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/send-notification" method="POST" type="application/json"> <Operation hidden="false" icon="fw-message">
<params>
<uiParams>
<uiParam optional="false">
<type>text</type>
<id>messageTitle</id>
<label>Title Here...</label>
</uiParam>
<uiParam optional="false">
<type>text</type>
<id>messageText</id>
<label>Message Here...</label>
</uiParam>
</uiParams>
</params>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/send-notification</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/send-notification</permission>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="CHANGE_LOCK_CODE"> <Feature type="operation" code="CHANGE_LOCK_CODE">
<Name>Change Lock-code</Name> <Name>Change Lock-code</Name>
<Description>Change current lock code</Description> <Description>Change current lock code (This functionality is only working with profile owners from Android 7.0 API 24 onwards.)</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/change-lock-code" method="POST" type="application/json"> <Operation hidden="false" icon="fw-security">
<params/>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/change-lock-code</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/change-lock-code</permission>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="ENTERPRISE_WIPE"> <Feature type="operation" code="FILE_TRANSFER">
<Name>File Transfer</Name>
<Description>Transfer file to the device</Description>
<Operation hidden="false" icon="fw-save">
<params>
<uiParams>
<uiParam optional="false">
<type>radio</type>
<name>directionSelection</name>
<id>upload</id>
<values>
<value>To device</value>
</values>
</uiParam>
<uiParam optional="false">
<type>radio</type>
<name>directionSelection</name>
<id>download</id>
<values>
<value>From device</value>
</values>
</uiParam>
<uiParam optional="false">
<type>select</type>
<name>protocolSelection</name>
<id>protocol</id>
<values>
<value>HTTP</value>
<value>FTP</value>
<value>SFTP</value>
</values>
<label>Protocol</label>
</uiParam>
<uiParam optional="false">
<type>text</type>
<id>fileURL</id>
<label>URL to upload file from device</label>
</uiParam>
<uiParam optional="false">
<type>info</type>
<id>defaultFileLocation</id>
<label>File will be saved in Default download directory if not specified.</label>
</uiParam>
<uiParam optional="false">
<type>text</type>
<id>fileLocation</id>
<label>File location in the device</label>
</uiParam>
<uiParam optional="false">
<type>checkbox</type>
<id>authentication</id>
<label>Authentication required</label>
</uiParam>
<uiParam optional="false">
<type>text</type>
<id>userName</id>
<label>Username</label>
</uiParam>
<uiParam optional="false">
<type>password</type>
<id>ftpPassword</id>
<label>Password (Ignore if not needed)</label>
</uiParam>
</uiParams>
</params>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/file-transfer</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/file-transfer</permission>
</metadata>
</Operation>
</Feature>
<Feature type="operation" code="ENTERPRISE_WIPE">
<Name>Enterprise Wipe</Name> <Name>Enterprise Wipe</Name>
<Description>Remove enterprise applications</Description> <Description>Remove enterprise applications</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/enterprise-wipe" method="POST" type="application/json"> <Operation hidden="false" icon="fw-block">
<params/>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/enterprise-wipe</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/enterprise-wipe</permission>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="WIPE_DATA"> <Feature type="operation" code="WIPE_DATA">
<Name>Wipe Data</Name> <Name>Wipe Data</Name>
<Description>Factory reset the device</Description> <Description>Factory reset the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/wipe" method="POST" type="application/json"> <Operation hidden="false" icon="fw-delete">
<params>
<uiParams>
<uiParam optional="false">
<type>text</type>
<id>pin</id>
<label>Enter PIN code* of the device.</label>
</uiParam>
</uiParams>
</params>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/wipe</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/wipe</permission>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="WIFI"> <Feature type="policy" code="WIFI">
<Name>Wifi</Name> <Name>Wifi</Name>
<Description>Setting up wifi configuration</Description> <Description>Setting up wifi configuration</Description>
</Feature> </Feature>
<Feature code="CAMERA"> <Feature type="policy" code="GLOBAL_PROXY">
<Name>Global Proxy</Name>
<Description>Setting up a network-independent global HTTP proxy on a device.</Description>
</Feature>
<Feature type="policy" code="CAMERA">
<Name>Camera</Name> <Name>Camera</Name>
<Description>Enable or disable camera</Description> <Description>Enable or disable camera</Description>
</Feature> </Feature>
<Feature code="EMAIL"> <Feature type="policy" code="EMAIL">
<Name>Email</Name> <Name>Email</Name>
<Description>Configure email settings</Description> <Description>Configure email settings</Description>
</Feature> </Feature>
<Feature code="DEVICE_INFO"> <Feature type="operation" code="DEVICE_INFO">
<Name>Device info</Name> <Name>Device info</Name>
<Description>Request device information</Description> <Description>Request device information</Description>
</Feature> </Feature>
<Feature code="APPLICATION_LIST"> <Feature type="operation" code="APPLICATION_LIST">
<Name>Application List</Name> <Name>Application List</Name>
<Description>Request list of current installed applications</Description> <Description>Request list of current installed applications</Description>
</Feature> </Feature>
<Feature code="INSTALL_APPLICATION"> <Feature type="operation" code="INSTALL_APPLICATION">
<Name>Install App</Name> <Name>Install App</Name>
<Description>Install App</Description> <Description>Install App</Description>
</Feature> </Feature>
<Feature code="UNINSTALL_APPLICATION"> <Feature type="operation" code="UNINSTALL_APPLICATION">
<Name>Uninstall App</Name> <Name>Uninstall App</Name>
<Description>Uninstall App</Description> <Description>Uninstall App</Description>
</Feature> </Feature>
<Feature code="BLACKLIST_APPLICATIONS"> <Feature type="policy" code="BLACKLIST_APPLICATIONS">
<Name>Blacklist app</Name> <Name>Blacklist app</Name>
<Description>Blacklist applications</Description> <Description>Blacklist applications</Description>
</Feature> </Feature>
<Feature code="ENCRYPT_STORAGE"> <Feature type="policy" code="ENCRYPT_STORAGE">
<Name>Encrypt Storage</Name> <Name>Encrypt Storage</Name>
<Description>Encrypt storage</Description> <Description>Encrypt storage</Description>
</Feature> </Feature>
<Feature code="PASSCODE_POLICY"> <Feature type="policy" code="PASSCODE_POLICY">
<Name>Password Policy</Name> <Name>Password Policy</Name>
<Description>Set passcode policy</Description> <Description>Set passcode policy</Description>
</Feature> </Feature>
<Feature code="VPN"> <Feature type="policy" code="VPN">
<Name>Configure VPN</Name> <Name>Configure VPN</Name>
<Description>Configure VPN settings</Description> <Description>Configure VPN settings</Description>
</Feature> </Feature>
<Feature code="DISALLOW_ADJUST_VOLUME"> <Feature type="policy" code="DISALLOW_ADJUST_VOLUME">
<Name>Disallow user to change volume</Name> <Name>Disallow user to change volume</Name>
<Description>Allow or disallow user to change volume"</Description> <Description>Allow or disallow user to change volume"</Description>
</Feature> </Feature>
<Feature code="DISALLOW_CONFIG_BLUETOOTH"> <Feature type="policy" code="DISALLOW_CONFIG_BLUETOOTH">
<Name>Disallow bluetooth configuration</Name> <Name>Disallow bluetooth configuration</Name>
<Description>Allow or disallow bluetooth configuration</Description> <Description>Allow or disallow bluetooth configuration</Description>
</Feature> </Feature>
<Feature code="DISALLOW_CONFIG_CELL_BROADCASTS"> <Feature type="policy" code="DISALLOW_CONFIG_CELL_BROADCASTS">
<Name>Disallow user to change cell broadcast configurations</Name> <Name>Disallow user to change cell broadcast configurations</Name>
<Description>Allow or disallow user to change cell broadcast configurations</Description> <Description>Allow or disallow user to change cell broadcast configurations</Description>
</Feature> </Feature>
<Feature code="DISALLOW_CONFIG_CREDENTIALS"> <Feature type="policy" code="DISALLOW_CONFIG_CREDENTIALS">
<Name>Disallow user to change user credentials</Name> <Name>Disallow user to change user credentials</Name>
<Description>Allow or disallow user to change user credentials</Description> <Description>Allow or disallow user to change user credentials</Description>
</Feature> </Feature>
<Feature code="DISALLOW_CONFIG_MOBILE_NETWORKS"> <Feature type="policy" code="DISALLOW_CONFIG_MOBILE_NETWORKS">
<Name>Disallow user to change mobile networks configurations</Name> <Name>Disallow user to change mobile networks configurations</Name>
<Description>Allow or disallow user to change mobile networks configurations</Description> <Description>Allow or disallow user to change mobile networks configurations</Description>
</Feature> </Feature>
<Feature code="DISALLOW_CONFIG_TETHERING"> <Feature type="policy" code="DISALLOW_CONFIG_TETHERING">
<Name>Disallow user to change tethering configurations</Name> <Name>Disallow user to change tethering configurations</Name>
<Description>Allow or disallow user to change tethering configurations</Description> <Description>Allow or disallow user to change tethering configurations</Description>
</Feature> </Feature>
<Feature code="DISALLOW_CONFIG_VPN"> <Feature type="policy" code="DISALLOW_CONFIG_VPN">
<Name>Disallow user to change VPN configurations</Name> <Name>Disallow user to change VPN configurations</Name>
<Description>Allow or disallow user to change VPN configurations</Description> <Description>Allow or disallow user to change VPN configurations</Description>
</Feature> </Feature>
<Feature code="DISALLOW_CONFIG_WIFI"> <Feature type="policy" code="DISALLOW_CONFIG_WIFI">
<Name>Disallow user to change WIFI configurations</Name> <Name>Disallow user to change WIFI configurations</Name>
<Description>Allow or disallow user to change WIFI configurations</Description> <Description>Allow or disallow user to change WIFI configurations</Description>
</Feature> </Feature>
<Feature code="DISALLOW_APPS_CONTROL"> <Feature type="policy" code="DISALLOW_APPS_CONTROL">
<Name>Disallow user to change app control</Name> <Name>Disallow user to change app control</Name>
<Description>Allow or disallow user to change app control</Description> <Description>Allow or disallow user to change app control</Description>
</Feature> </Feature>
<Feature code="DISALLOW_CREATE_WINDOWS"> <Feature type="policy" code="DISALLOW_CREATE_WINDOWS">
<Name>Disallow window creation</Name> <Name>Disallow window creation</Name>
<Description>Allow or disallow window creation</Description> <Description>Allow or disallow window creation</Description>
</Feature> </Feature>
<Feature code="DISALLOW_APPS_CONTROL"> <Feature type="policy" code="DISALLOW_APPS_CONTROL">
<Name>Disallow user to change app control configurations</Name> <Name>Disallow user to change app control configurations</Name>
<Description>Allow or disallow user to change app control configurations</Description> <Description>Allow or disallow user to change app control configurations</Description>
</Feature> </Feature>
<Feature code="DISALLOW_CROSS_PROFILE_COPY_PASTE"> <Feature type="policy" code="DISALLOW_CROSS_PROFILE_COPY_PASTE">
<Name>Disallow cross profile copy paste</Name> <Name>Disallow cross profile copy paste</Name>
<Description>Allow or disallow cross profile copy paste</Description> <Description>Allow or disallow cross profile copy paste</Description>
</Feature> </Feature>
<Feature code="DISALLOW_DEBUGGING_FEATURES"> <Feature type="policy" code="DISALLOW_DEBUGGING_FEATURES">
<Name>Disallow debugging features</Name> <Name>Disallow debugging features</Name>
<Description>Allow or disallow debugging features</Description> <Description>Allow or disallow debugging features</Description>
</Feature> </Feature>
<Feature code="DISALLOW_FACTORY_RESET"> <Feature type="policy" code="DISALLOW_FACTORY_RESET">
<Name>Disallow factory reset</Name> <Name>Disallow factory reset</Name>
<Description>Allow or disallow factory reset</Description> <Description>Allow or disallow factory reset</Description>
</Feature> </Feature>
<Feature code="DISALLOW_ADD_USER"> <Feature type="policy" code="DISALLOW_ADD_USER">
<Name>Disallow add user</Name> <Name>Disallow add user</Name>
<Description>Allow or disallow add user</Description> <Description>Allow or disallow add user</Description>
</Feature> </Feature>
<Feature code="DISALLOW_INSTALL_APPS"> <Feature type="policy" code="DISALLOW_INSTALL_APPS">
<Name>Disallow install apps</Name> <Name>Disallow install apps</Name>
<Description>Allow or disallow install apps</Description> <Description>Allow or disallow install apps</Description>
</Feature> </Feature>
<Feature code="DISALLOW_INSTALL_UNKNOWN_SOURCES"> <Feature type="policy" code="DISALLOW_INSTALL_UNKNOWN_SOURCES">
<Name>Disallow install unknown sources</Name> <Name>Disallow install unknown sources</Name>
<Description>Allow or disallow install unknown sources</Description> <Description>Allow or disallow install unknown sources</Description>
</Feature> </Feature>
<Feature code="DISALLOW_MODIFY_ACCOUNTS"> <Feature type="policy" code="DISALLOW_MODIFY_ACCOUNTS">
<Name>Disallow modify account</Name> <Name>Disallow modify account</Name>
<Description>Allow or disallow modify account</Description> <Description>Allow or disallow modify account</Description>
</Feature> </Feature>
<Feature code="DISALLOW_MOUNT_PHYSICAL_MEDIA"> <Feature type="policy" code="DISALLOW_MOUNT_PHYSICAL_MEDIA">
<Name>Disallow mount physical media</Name> <Name>Disallow mount physical media</Name>
<Description>Allow or disallow mount physical media</Description> <Description>Allow or disallow mount physical media</Description>
</Feature> </Feature>
<Feature code="DISALLOW_NETWORK_RESET"> <Feature type="policy" code="DISALLOW_NETWORK_RESET">
<Name>Disallow network reset</Name> <Name>Disallow network reset</Name>
<Description>Allow or disallow network reset</Description> <Description>Allow or disallow network reset</Description>
</Feature> </Feature>
<Feature code="DISALLOW_OUTGOING_BEAM"> <Feature type="policy" code="DISALLOW_OUTGOING_BEAM">
<Name>Disallow outgoing beam</Name> <Name>Disallow outgoing beam</Name>
<Description>Allow or disallow outgoing beam</Description> <Description>Allow or disallow outgoing beam</Description>
</Feature> </Feature>
<Feature code="DISALLOW_OUTGOING_CALLS"> <Feature type="policy" code="DISALLOW_OUTGOING_CALLS">
<Name>Disallow outgoing calls</Name> <Name>Disallow outgoing calls</Name>
<Description>Allow or disallow outgoing calls</Description> <Description>Allow or disallow outgoing calls</Description>
</Feature> </Feature>
<Feature code="DISALLOW_REMOVE_USER"> <Feature type="policy" code="DISALLOW_REMOVE_USER">
<Name>Disallow remove users</Name> <Name>Disallow remove users</Name>
<Description>Allow or disallow remove users</Description> <Description>Allow or disallow remove users</Description>
</Feature> </Feature>
<Feature code="DISALLOW_SAFE_BOOT"> <Feature type="policy" code="DISALLOW_SAFE_BOOT">
<Name>Disallow safe boot</Name> <Name>Disallow safe boot</Name>
<Description>Allow or disallow safe boot</Description> <Description>Allow or disallow safe boot</Description>
</Feature> </Feature>
<Feature code="DISALLOW_SHARE_LOCATION"> <Feature type="policy" code="DISALLOW_SHARE_LOCATION">
<Name>Disallow share location</Name> <Name>Disallow share location</Name>
<Description>Allow or disallow share location</Description> <Description>Allow or disallow share location</Description>
</Feature> </Feature>
<Feature code="DISALLOW_SMS"> <Feature type="policy" code="DISALLOW_SMS">
<Name>Disallow sms</Name> <Name>Disallow sms</Name>
<Description>Allow or disallow sms</Description> <Description>Allow or disallow sms</Description>
</Feature> </Feature>
<Feature code="DISALLOW_UNINSTALL_APPS"> <Feature type="policy" code="DISALLOW_UNINSTALL_APPS">
<Name>Disallow uninstall app</Name> <Name>Disallow uninstall app</Name>
<Description>Allow or disallow uninstall app</Description> <Description>Allow or disallow uninstall app</Description>
</Feature> </Feature>
<Feature code="DISALLOW_UNMUTE_MICROPHONE"> <Feature type="policy" code="DISALLOW_UNMUTE_MICROPHONE">
<Name>Disallow unmute mic</Name> <Name>Disallow unmute mic</Name>
<Description>Allow or disallow unmute mic</Description> <Description>Allow or disallow unmute mic</Description>
</Feature> </Feature>
<Feature code="DISALLOW_USB_FILE_TRANSFER"> <Feature type="policy" code="DISALLOW_USB_FILE_TRANSFER">
<Name>Disallow usb file transfer</Name> <Name>Disallow usb file transfer</Name>
<Description>Allow or disallow usb file transfer</Description> <Description>Allow or disallow usb file transfer</Description>
</Feature> </Feature>
<Feature code="ALLOW_PARENT_PROFILE_APP_LINKING"> <Feature type="policy" code="ALLOW_PARENT_PROFILE_APP_LINKING">
<Name>Disallow parent profile app linking</Name> <Name>Disallow parent profile app linking</Name>
<Description>Allow or disallow parent profile app linking</Description> <Description>Allow or disallow parent profile app linking</Description>
</Feature> </Feature>
<Feature code="ENSURE_VERIFY_APPS"> <Feature type="policy" code="ENSURE_VERIFY_APPS">
<Name>Disallow ensure verify apps</Name> <Name>Disallow ensure verify apps</Name>
<Description>Allow or disallow ensure verify apps</Description> <Description>Allow or disallow ensure verify apps</Description>
</Feature> </Feature>
<Feature code="AUTO_TIME"> <Feature type="policy" code="AUTO_TIME">
<Name>Disallow auto timing</Name> <Name>Disallow auto timing</Name>
<Description>Allow or disallow auto timing</Description> <Description>Allow or disallow auto timing</Description>
</Feature> </Feature>
<Feature code="REMOVE_DEVICE_OWNER"> <Feature type="policy" code="REMOVE_DEVICE_OWNER">
<Name>Remove device owner</Name> <Name>Remove device owner</Name>
<Description>Remove device owner</Description> <Description>Remove device owner</Description>
</Feature> </Feature>
<Feature code="LOGCAT"> <Feature type="policy" code="LOGCAT">
<Name>Fetch device logcat</Name> <Name>Fetch device logcat</Name>
<Description>Fetch device logcat</Description> <Description>Fetch device logcat</Description>
</Feature> </Feature>
<Feature code="DEVICE_UNLOCK"> <Feature type="operation" hidden="false" code="DEVICE_UNLOCK">
<Name>Unlock the device</Name> <Name>Unlock the device</Name>
<Description>Unlock the device</Description> <Description>Unlock the device</Description>
</Feature> </Feature>

@ -19,15 +19,15 @@
--> -->
<DeviceTypeConfiguration name="android_sense"> <DeviceTypeConfiguration name="android_sense">
<Features> <Features>
<Feature code="keywords"> <Feature type="operation" code="keywords">
<Name>Add Keywords</Name> <Name>Add Keywords</Name>
<Description>Send keywords to the device</Description> <Description>Send keywords to the device</Description>
</Feature> </Feature>
<Feature code="threshold"> <Feature type="operation" code="threshold">
<Name>Add Threshold</Name> <Name>Add Threshold</Name>
<Description>Send Threshold to the device</Description> <Description>Send Threshold to the device</Description>
</Feature> </Feature>
<Feature code="remove_words"> <Feature type="operation" code="remove_words">
<Name>Remove words</Name> <Name>Remove words</Name>
<Description>Remove Threshold from the device</Description> <Description>Remove Threshold from the device</Description>
</Feature> </Feature>

@ -19,13 +19,19 @@
--> -->
<DeviceTypeConfiguration name="arduino"> <DeviceTypeConfiguration name="arduino">
<Features> <Features>
<Feature code="bulb"> <Feature type="operation" code="bulb">
<Name>Control Bulb</Name> <Name>Control Bulb</Name>
<Description>Control Bulb on Arduino Uno</Description> <Description>Control Bulb on Arduino Uno</Description>
<Operation context="/arduino/device/{deviceId}/bulb" method="POST"> <Operation hidden="true">
<QueryParameters> <params>
<Parameter>state</Parameter> <queryParams>
</QueryParameters> <Parameter>state</Parameter>
</queryParams>
</params>
<metadata>
<uri>/arduino/device/{deviceId}/bulb</uri>
<method>POST</method>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
</Features> </Features>

@ -21,13 +21,19 @@
<DeviceDetails table-id="DEFECTIVE_DEVICE"/> <DeviceDetails table-id="DEFECTIVE_DEVICE"/>
<Features> <Features>
<Feature code="bulb"> <Feature type="operation" code="bulb">
<Name>Control Bulb</Name> <Name>Control Bulb</Name>
<Description>Control Bulb on Arduino Uno</Description> <Description>Control Bulb on Arduino Uno</Description>
<Operation context="/arduino/device/{deviceId}/bulb" method="POST"> <Operation hidden="true">
<QueryParameters> <params>
<Parameter>state</Parameter> <queryParams>
</QueryParameters> <Parameter>state</Parameter>
</queryParams>
</params>
<metadata>
<uri>/arduino/device/{deviceId}/bulb</uri>
<method>POST</method>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
</Features> </Features>

@ -27,13 +27,19 @@
</DeviceDetails> </DeviceDetails>
<Features> <Features>
<Feature code="bulb"> <Feature type="operation" code="bulb">
<Name>Control Bulb</Name> <Name>Control Bulb</Name>
<Description>Control Bulb on Arduino Uno</Description> <Description>Control Bulb on Arduino Uno</Description>
<Operation context="/arduino/device/{deviceId}/bulb" method="POST"> <Operation hidden="false">
<QueryParameters> <params>
<Parameter>state</Parameter> <queryParams>
</QueryParameters> <Parameter>state</Parameter>
</queryParams>
</params>
<metadata>
<uri>/arduino/device/{deviceId}/bulb</uri>
<method>POST</method>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
</Features> </Features>

@ -19,13 +19,19 @@
--> -->
<DeviceTypeConfiguration name="raspberrypi"> <DeviceTypeConfiguration name="raspberrypi">
<Features> <Features>
<Feature code="bulb"> <Feature type="operation" code="bulb">
<Name>Control Bulb</Name> <Name>Control Bulb</Name>
<Description>Control Bulb on Raspberrypi</Description> <Description>Control Bulb on Raspberrypi</Description>
<Operation context="/raspberrypi/device/{deviceId}/bulb" method="POST"> <Operation hidden="false">
<QueryParameters> <params>
<Parameter>state</Parameter> <queryParams>
</QueryParameters> <Parameter>state</Parameter>
</queryParams>
</params>
<metadata>
<uri>/raspberrypi/device/{deviceId}/bulb</uri>
<method>POST</method>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
</Features> </Features>

@ -31,16 +31,23 @@
<!--END--> <!--END-->
<Features> <Features>
<Feature code="abc"> <Feature type="operation" hidden="true" code="abc">
<Name>abc</Name> <Name>abc</Name>
<Description>this is a feature</Description> <Description>this is a feature</Description>
<Operation context="/bulb/{state}" method="PUT" type="application/json"> <Operation hidden="true">
<QueryParameters> <params>
<Parameter>deviceId</Parameter> <queryParams>
</QueryParameters> <Parameter>deviceId</Parameter>
<FormParameters> </queryParams>
<Parameter>test</Parameter> <formParams>
</FormParameters> <Parameter>test</Parameter>
</formParams>
</params>
<metadata>
<uri>/bulb/{state}</uri>
<method>POST</method>
<contentType>application/json</contentType>
</metadata>
</Operation> </Operation>
</Feature> </Feature>
</Features> </Features>

@ -16,6 +16,24 @@
* under the License. * under the License.
*/ */
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.
*/
var operationModule = function () { var operationModule = function () {
var log = new Log("/app/modules/business-controllers/operation.js"); var log = new Log("/app/modules/business-controllers/operation.js");
var utility = require('/app/modules/utility.js').utility; var utility = require('/app/modules/utility.js').utility;
@ -38,8 +56,9 @@ var operationModule = function () {
} }
privateMethods.getOperationsFromFeatures = function (deviceType, operationType) { privateMethods.getOperationsFromFeatures = function (deviceType, operationType) {
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/device-types/" + deviceType + "/features"; var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/device-types/"
var featuresList = serviceInvokers.XMLHttp.get(url, function (responsePayload) { + deviceType + "/features?featureType=" + operationType + "&hidden=false";
return serviceInvokers.XMLHttp.get(url, function (responsePayload) {
var features = JSON.parse(responsePayload.responseText); var features = JSON.parse(responsePayload.responseText);
var featureList = []; var featureList = [];
var feature; var feature;
@ -51,20 +70,40 @@ var operationModule = function () {
feature["contentType"] = features[i].contentType; feature["contentType"] = features[i].contentType;
feature["deviceType"] = deviceType; feature["deviceType"] = deviceType;
feature["params"] = []; feature["params"] = [];
var featuresEntry = utility.getDeviceTypeConfig(deviceType)["deviceType"]["features"];
if (featuresEntry) {
var featureEntry = featuresEntry[features[i].code];
if (featureEntry) {
var permissionEntry = featureEntry["permission"];
if (permissionEntry) {
feature["permission"] = permissionEntry
}
}
}
var metaData = features[i].metadataEntries; var metaData = features[i].metadataEntries;
if (metaData) { if (metaData) {
for (var j = 0; j < metaData.length; j++) { for (var j = 0; j < metaData.length; j++) {
feature["params"].push(metaData[j].value); if (metaData[j].name === "operationMeta") {
var operationMeta = metaData[j].value;
var params = {};
params["method"] = operationMeta.method;
params["pathParams"] = operationMeta.pathParams;
params["queryParams"] = operationMeta.queryParams;
params["formParams"] = operationMeta.formParams ? operationMeta.formParams : [];
params["uri"] = operationMeta.uri;
params["contentType"] = operationMeta.contentType;
feature["params"].push(params);
feature["permission"] = operationMeta.permission;
if (operationMeta.icon) {
//Check if icon is a path or font
if (operationMeta.icon.indexOf("path:") === 0) {
feature["icon"] = operationMeta.icon.replace("path:", "");
} else {
feature["iconFont"] = operationMeta.icon;
}
}
if (operationMeta.uiParams && operationMeta.uiParams.length > 0) {
feature["uiParams"] = operationMeta.uiParams;
}
if (operationMeta.filters) {
feature["filters"] = operationMeta.filters;
}
if (operationMeta.ownershipDescription) {
feature["ownershipDescription"] = operationMeta.ownershipDescription;
}
continue;
}
feature["metadata"].push(metaData[j].value);
} }
featureList.push(feature); featureList.push(feature);
} }
@ -76,39 +115,27 @@ var operationModule = function () {
return response; return response;
} }
); );
return featuresList;
}; };
publicMethods.getControlOperations = function (device) { publicMethods.getControlOperations = function (device) {
var deviceType = device.type; var deviceType = device.type;
var operations = privateMethods.getOperationsFromFeatures(deviceType, "operation"); var operations = privateMethods.getOperationsFromFeatures(deviceType, "operation");
var features = utility.getDeviceTypeConfig(deviceType).deviceType.features;
for (var op in operations) { for (var op in operations) {
var iconIdentifier = operations[op].operation; if (operations.hasOwnProperty(op)) {
if (features && features[iconIdentifier]) { operations[op]["isDisabled"] = false;
var icon = features[iconIdentifier].icon; if (device && operations[op].filters && operations[op].filters.length > 0) {
//TODO: need improve this check to get feature availability from agent side var filters = operations[op].filters;
var filter = features[iconIdentifier].filter; for (var filter in filters) {
if (device && filter && filter.property && device[filter.property] !== filter.value) { if (filters.hasOwnProperty(filter)) {
operations[op]["isDisabled"] = true; if (device[filters[filter].property] !== filters[filter].value) {
operations[op]["disabledText"] = filter.text; operations[op]["isDisabled"] = true;
} else { operations[op]["disabledText"] = operations[op]["disabledText"] ?
operations[op]["isDisabled"] = false; operations[op]["disabledText"] + ", " + filters[filter].description :
} filters[filter].description;
if (icon) { }
operations[op]["iconFont"] = icon; }
} else if (iconPath) { }
var iconPath = utility.getOperationIcon(deviceType, iconIdentifier);
operations[op]["icon"] = iconPath;
}
var formParams = features[iconIdentifier].formParams;
if (formParams) {
operations[op]["uiParams"] = formParams;
} }
// var icon = utility.getOperationIcon(deviceType, iconIdentifier);
// if (icon) {
// log.error("icon found : " + icon );
// operations[op]["icon"] = icon;
} }
} }
return operations; return operations;

@ -15,6 +15,24 @@
specific language governing permissions and limitations specific language governing permissions and limitations
under the License. under the License.
}} }}
{{!
Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
Entgra (Pvt) Ltd. 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.
}}
{{unit "cdmf.unit.ui.title" pageTitle="Device Management"}} {{unit "cdmf.unit.ui.title" pageTitle="Device Management"}}
{{unit "cdmf.unit.data-tables-extended"}} {{unit "cdmf.unit.data-tables-extended"}}
@ -181,7 +199,7 @@
<ul class="tiles"> <ul class="tiles">
{{#unless group}} {{#unless group}}
<li> <li>
<a href="#" style="width: 100px;height: 80px;;" <a href="#"
data-click-event="remove-form" data-click-event="remove-form"
class="btn square-element add-devices-to-group-link" class="btn square-element add-devices-to-group-link"
data-toggle="modal" data-target="#modalDemo"> data-toggle="modal" data-target="#modalDemo">
@ -194,7 +212,7 @@
</li> </li>
{{/unless}} {{/unless}}
<li> <li>
<a href="#" style="width: 100px;height: 80px;" <a href="#"
data-click-event="remove-form" data-click-event="remove-form"
class="btn square-element remove-device-link" class="btn square-element remove-device-link"
data-toggle="modal" data-target="#modalDemo"> data-toggle="modal" data-target="#modalDemo">
@ -225,9 +243,27 @@
</li> </li>
{{/if}} {{/if}}
<!--/update enrollment--> <!--/update enrollment-->
<!-- Add operation for selected devices -->
<li>
<a href="#" data-click-event="remove-form"
class="btn square-element add-operation-link"
data-toggle="modal" data-target="#modalDemo">
<span class="icon fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-dgm-action fw-stack-1x"></i>
</span>
Add Operation
</a>
</li>
<!-- Add operation for selected devices -->
</ul> </ul>
</th> </th>
</tr> </tr>
<tr id="device-type-operations-bar" class="bulk-action-row sub-action hidden">
<th colspan="7">
<div id="device-type-operations"></div>
</th>
</tr>
</thead> </thead>
<tbody id="ast-container"> <tbody id="ast-container">
@ -508,7 +544,6 @@
</div> </div>
</div> </div>
</div> </div>
<div id="no-device-selected" class="hide"> <div id="no-device-selected" class="hide">
<div class="modal-content"> <div class="modal-content">
<div class="row"> <div class="row">
@ -525,7 +560,39 @@
</div> </div>
</div> </div>
</div> </div>
<div id="multiple-device-types-selected" class="hide">
<div class="modal-content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Adding operations to devices of multiple device types is not supported.
Please select one or more devices in the same device type.</h3>
<br/>
<div class="buttons">
<a href="#" id="multiple-device-types-selected-link"
class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="no-features-available" class="hide">
<div class="modal-content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>No compatible operations are available for the selected device type.</h3>
<br/>
<div class="buttons">
<a href="#" id="no-features-available-selected-link"
class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -588,7 +655,7 @@
{{#zone "bottomJs"}} {{#zone "bottomJs"}}
<script id="device-listing" data-server-url="{{serverUrl}}" data-current-user="{{@user.username}}" data-device-types="{{deviceTypes}}" <script id="device-listing" data-server-url="{{serverUrl}}" data-current-user="{{@user.username}}" data-device-types="{{deviceTypes}}"
data-portal-url="{{portalUrl}}" data-user-domain="{{userDomain}}" type="text/x-handlebars-template"></script> data-portal-url="{{portalUrl}}" data-user-domain="{{userDomain}}" data-api-context="{{apiContext}}" type="text/x-handlebars-template"></script>
{{js "js/listing.js"}} {{js "js/listing.js"}}
{{/zone}} {{/zone}}

@ -96,9 +96,11 @@ function onRequest(context) {
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"]; var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
var serverUrl = mdmProps["httpsURL"]; var serverUrl = mdmProps["httpsURL"];
var portalUrl = mdmProps["portalURL"]; var portalUrl = mdmProps["portalURL"];
var backendRestEndpoints = mdmProps["backendRestEndpoints"];
var userDomain = context.user.domain; var userDomain = context.user.domain;
viewModel.serverUrl = serverUrl; viewModel.serverUrl = serverUrl;
viewModel.portalUrl = portalUrl; viewModel.portalUrl = portalUrl;
viewModel.userDomain = userDomain; viewModel.userDomain = userDomain;
viewModel.apiContext = backendRestEndpoints["deviceMgt"];
return viewModel; return viewModel;
} }

@ -16,6 +16,24 @@
* under the License. * under the License.
*/ */
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.
*/
/** /**
* Following function would execute * Following function would execute
* when a user clicks on the list item * when a user clicks on the list item
@ -952,6 +970,121 @@ function attachDeviceEvents() {
hidePopup(); hidePopup();
}); });
}); });
/**
* Following click function would execute when a user clicks on "Add Operation" link
* on Device Management page in device mgt Console.
*/
$('a.add-operation-link').click(function () {
var operationsRow = $("#device-type-operations-bar");
if (!operationsRow.hasClass("hidden")) {
operationsRow.addClass("hidden");
$("#device-type-operations").html("");
return;
}
var deviceIdentifiers = getSelectedDevices();
if (deviceIdentifiers.length === 0) {
$(modalPopupContent).html($('#no-device-selected').html());
$("a#no-device-selected-link").click(function () {
hidePopup();
});
showPopup();
return;
}
var selectedDeviceType = deviceIdentifiers[0].type;
var deviceList = "";
var count = 1;
deviceIdentifiers.forEach(function (deviceIdentifier) {
if (selectedDeviceType !== deviceIdentifier.type) {
++count;
}
deviceList = !deviceList ? deviceIdentifier.id : deviceList + "," + deviceIdentifier.id;
});
// If multiple devices of multiple device types selected
if (count > 1) {
$(modalPopupContent).html($('#multiple-device-types-selected').html());
$("a#multiple-device-types-selected-link").click(function () {
hidePopup();
});
showPopup();
return;
}
var apiContext = $("#device-listing").data("api-context");
var serviceURL = apiContext + "/device-types/" + selectedDeviceType + "/features?featureType=operation" +
"&hidden=false";
invokerUtil.get(serviceURL, function (data) {
showOperationBar(JSON.parse(data), selectedDeviceType, deviceList);
});
});
}
function showOperationBar(features, deviceType, deviceList) {
var featureList = [];
var feature;
for (var i = 0; i < features.length; i++) {
feature = {};
feature.operation = features[i].code;
feature.name = features[i].name;
feature.description = features[i].description;
feature.deviceType = deviceType;
feature.params = [];
var metaData = features[i].metadataEntries;
if (metaData) {
for (var j = 0; j < metaData.length; j++) {
if (metaData[j].name === "operationMeta") {
var operationMeta = metaData[j].value;
var params = {};
params.method = operationMeta.method;
params.pathParams = operationMeta.pathParams;
params.queryParams = operationMeta.queryParams;
params.formParams = operationMeta.formParams ? operationMeta.formParams : [];
params.uri = operationMeta.uri;
params.contentType = operationMeta.contentType;
feature.params.push(params);
feature.permission = operationMeta.permission;
if (operationMeta.icon) {
if (operationMeta.icon.indexOf("path:") === 0) {
feature.icon = operationMeta.icon.replace("path:", "");
} else {
feature.iconFont = operationMeta.icon;
}
}
if (operationMeta.uiParams && operationMeta.uiParams.length > 0) {
feature.uiParams = operationMeta.uiParams;
}
continue;
}
feature.metadata.push(metaData[j].value);
}
featureList.push(feature);
}
}
if (featureList.length > 0) {
var baseUnitPath = context + "/public/cdmf.unit.device.type." + deviceType + ".operation-bar";
var operationBarScriptSrc = baseUnitPath + "/js/operation-bar.js";
var operationBarTemplateSrc = baseUnitPath + "/templates/operation-bar.hbs";
var operationBarCacheKey = deviceType + "-operation-bar";
$.template(operationBarCacheKey, operationBarTemplateSrc, function (template) {
var content = template({"controlOperations": featureList, "devices" : deviceList});
$("#device-type-operations").html(content);
var operationRow = $("#device-type-operations-bar");
var script = document.createElement("script");
script.type = "text/javascript";
script.src = operationBarScriptSrc;
operationRow.prepend(script);
operationRow.removeClass("hidden");
});
} else {
$(modalPopupContent).html($('#no-features-available').html());
$("a#no-features-available-selected-link").click(function () {
hidePopup();
});
showPopup();
}
} }
function removeDevices(deviceIdentifiers) { function removeDevices(deviceIdentifiers) {

@ -291,7 +291,7 @@ $.fn.datatables_extended = function (settings) {
thisTable = $(this).closest('.dataTables_wrapper').find('.dataTable').dataTable(); thisTable = $(this).closest('.dataTables_wrapper').find('.dataTable').dataTable();
if ($(button).html() == 'Select All') { if ($(button).html() == 'Select All') {
$(button).html('Deselect All'); $(button).html('Deselect All');
$('.bulk-action-row').removeClass('hidden'); $('.bulk-action-row:not(.sub-action)').removeClass('hidden');
thisTable.api().rows().every(function () { thisTable.api().rows().every(function () {
$(this.node()).addClass(rowSelectedClass); $(this.node()).addClass(rowSelectedClass);
}); });
@ -312,7 +312,7 @@ $.fn.datatables_extended = function (settings) {
var rowSelectedClass = 'DTTT_selected selected'; var rowSelectedClass = 'DTTT_selected selected';
$(this).toggleClass(rowSelectedClass); $(this).toggleClass(rowSelectedClass);
if ($('.table-selectable .DTTT_selected').length > 0) { if ($('.table-selectable .DTTT_selected').length > 0) {
$('.bulk-action-row').removeClass('hidden'); $('.bulk-action-row:not(.sub-action)').removeClass('hidden');
} else { } else {
$('.bulk-action-row').addClass('hidden'); $('.bulk-action-row').addClass('hidden');
} }

@ -356,7 +356,7 @@ $.fn.datatables_extended_serverside_paging = function (settings, url, dataFilter
if (!$(button).hasClass('disabled')) { if (!$(button).hasClass('disabled')) {
if ($(button).html() == 'Select All') { if ($(button).html() == 'Select All') {
$(button).html('Deselect All'); $(button).html('Deselect All');
$('.bulk-action-row').removeClass('hidden'); $('.bulk-action-row:not(.sub-action)').removeClass('hidden');
thisTable.api().rows().every(function () { thisTable.api().rows().every(function () {
$(this.node()).addClass(rowSelectedClass); $(this.node()).addClass(rowSelectedClass);
}); });
@ -378,7 +378,7 @@ $.fn.datatables_extended_serverside_paging = function (settings, url, dataFilter
var rowSelectedClass = 'DTTT_selected selected'; var rowSelectedClass = 'DTTT_selected selected';
$(this).toggleClass(rowSelectedClass); $(this).toggleClass(rowSelectedClass);
if ($('.table-selectable .DTTT_selected').length > 0) { if ($('.table-selectable .DTTT_selected').length > 0) {
$('.bulk-action-row').removeClass('hidden'); $('.bulk-action-row:not(.sub-action)').removeClass('hidden');
} else { } else {
$('.bulk-action-row').addClass('hidden'); $('.bulk-action-row').addClass('hidden');
} }

@ -385,7 +385,7 @@ var responsiveTextRatio = 0.2,
$('body').on('click', '[data-type=selectable]', function(){ $('body').on('click', '[data-type=selectable]', function(){
$(this).toggleClass(ROW_SELECTED_CLASS); $(this).toggleClass(ROW_SELECTED_CLASS);
if ($('.table-selectable .DTTT_selected').length > 0) { if ($('.table-selectable .DTTT_selected').length > 0) {
$('.bulk-action-row').removeClass('hidden'); $('.bulk-action-row:not(.sub-action)').removeClass('hidden');
} else { } else {
$('.bulk-action-row').addClass('hidden'); $('.bulk-action-row').addClass('hidden');
} }

Loading…
Cancel
Save