diff options
Diffstat (limited to 'ONAP-PDP-REST')
4 files changed, 512 insertions, 15 deletions
diff --git a/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/XACMLPdpServletTest.java b/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/XACMLPdpServletTest.java index e8747f736..3f01f0f94 100644 --- a/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/XACMLPdpServletTest.java +++ b/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/XACMLPdpServletTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP-PDP-REST * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,10 +46,15 @@ import org.onap.policy.common.im.IntegrityMonitor; import org.onap.policy.common.im.IntegrityMonitorException; import org.onap.policy.common.logging.flexlogger.FlexLogger; import org.onap.policy.common.logging.flexlogger.Logger; +import org.onap.policy.rest.XACMLRestProperties; +import org.onap.policy.xacml.std.pap.StdPDPPolicy; +import org.onap.policy.xacml.std.pap.StdPDPStatus; import org.powermock.api.mockito.PowerMockito; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockServletConfig; + +import com.att.research.xacml.util.XACMLProperties; import com.mockrunner.mock.web.MockServletInputStream; import junit.framework.TestCase; @@ -81,10 +86,19 @@ public class XACMLPdpServletTest extends TestCase{ private static final String DEFAULT_DB_USER = "sa"; private static final String DEFAULT_DB_PWD = ""; - + private StdPDPStatus status; + private StdPDPPolicy foobarPolicy; + @Before public void setUp(){ - + status = new StdPDPStatus(); + foobarPolicy = new StdPDPPolicy(); + foobarPolicy.setId("foobar"); + foobarPolicy.setVersion("123"); + foobarPolicy.setName("nothing"); + status.addLoadedPolicy(foobarPolicy); + + properties = new Properties(); properties.put(IntegrityAuditProperties.DB_DRIVER, XACMLPdpServletTest.DEFAULT_DB_DRIVER); properties.put(IntegrityAuditProperties.DB_URL, "jdbc:h2:file:./sql/xacmlTest"); @@ -170,12 +184,13 @@ public class XACMLPdpServletTest extends TestCase{ } Mockito.doNothing().when(im).endTransaction(); } - + @Test public void testInit(){ LOGGER.info("XACMLPdpServletTest - testInit"); try { pdpServlet.init(servletConfig); + assertTrue(true); } catch (Exception e) { LOGGER.error("Exception Occured"+e); @@ -184,7 +199,60 @@ public class XACMLPdpServletTest extends TestCase{ } } + + @Test + public void testUebNotification() { + System.out.println("drewtest1"); + LOGGER.info("XACMLPdpServletTest - drewTest1"); + try { + + XACMLProperties.reloadProperties(); + System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, "src/test/resources/xacml.pdp.ueb.properties"); + XACMLProperties.getProperties(); + XACMLProperties.setProperty(XACMLRestProperties.PROP_NOTIFICATION_TYPE, "ueb"); + + pdpServlet.init(servletConfig); + + status.setStatus(com.att.research.xacml.api.pap.PDPStatus.Status.UPDATING_CONFIGURATION); + + XACMLPdpLoader.validatePolicies(properties, status); + XACMLPdpLoader.sendNotification(); + assertTrue(true); + } catch (Exception e) { + LOGGER.error("Exception Occured"+e); + fail(); + + } + + } + + @Test + public void testDmaapNotification() { + System.out.println("drewtest2"); + LOGGER.info("XACMLPdpServletTest - drewTest2"); + try { + + XACMLProperties.reloadProperties(); + System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, "src/test/resources/xacml.pdp.dmaap.properties"); + XACMLProperties.getProperties(); + XACMLProperties.setProperty(XACMLRestProperties.PROP_NOTIFICATION_TYPE, "dmaap"); + + pdpServlet.init(servletConfig); + + status.setStatus(com.att.research.xacml.api.pap.PDPStatus.Status.UPDATING_CONFIGURATION); + + XACMLPdpLoader.validatePolicies(properties, status); + XACMLPdpLoader.sendNotification(); + assertTrue(true); + } catch (Exception e) { + LOGGER.error("Exception Occured"+e); + fail(); + + } + + } + @Test public void testDoGetNoTypeError(){ LOGGER.info("XACMLPdpServletTest - testDoGetNoTypeError"); @@ -200,7 +268,7 @@ public class XACMLPdpServletTest extends TestCase{ fail(); } } - + @Test public void testDoGetConfigType(){ LOGGER.info("XACMLPdpServletTest - testDoGetConfigType"); @@ -218,7 +286,7 @@ public class XACMLPdpServletTest extends TestCase{ } } - + @Test public void testDoGetTypeHb(){ LOGGER.info("XACMLPdpServletTest - testDoGetTypeHb"); @@ -234,7 +302,7 @@ public class XACMLPdpServletTest extends TestCase{ fail(); } } - + @Test public void testDoGetTypeStatus(){ LOGGER.info("XACMLPdpServletTest - testDoGetTypeStatus"); @@ -250,7 +318,7 @@ public class XACMLPdpServletTest extends TestCase{ fail(); } } - + @Test public void testDoPost(){ LOGGER.info("XACMLPdpServletTest - testDoPost"); @@ -264,7 +332,7 @@ public class XACMLPdpServletTest extends TestCase{ fail(); } } - + @Test public void testDoPostToLong(){ LOGGER.info("XACMLPdpServletTest - testDoPostToLong"); @@ -281,7 +349,7 @@ public class XACMLPdpServletTest extends TestCase{ fail(); } } - + @Test public void testDoPostContentLengthNegative(){ LOGGER.info("XACMLPdpServletTest - testDoPostToLong"); @@ -298,7 +366,7 @@ public class XACMLPdpServletTest extends TestCase{ fail(); } } - + @Test public void testDoPostContentTypeNonValid(){ LOGGER.info("XACMLPdpServletTest - testDoPostToLong"); @@ -315,7 +383,7 @@ public class XACMLPdpServletTest extends TestCase{ fail(); } } - + @Test public void testDoPostContentTypeConfigurationError(){ LOGGER.info("XACMLPdpServletTest - testDoPostToLong"); @@ -332,7 +400,7 @@ public class XACMLPdpServletTest extends TestCase{ fail(); } } - + @Test public void testDoPutCacheEmpty(){ LOGGER.info("XACMLPdpServletTest - testDoPutCacheEmpty"); @@ -352,7 +420,7 @@ public class XACMLPdpServletTest extends TestCase{ fail(); } } - + @Test public void testDoPutConfigPolicies(){ LOGGER.info("XACMLPdpServletTest - testDoPutConfigPolicies"); @@ -413,7 +481,7 @@ public class XACMLPdpServletTest extends TestCase{ fail(); } } - + @Test public void testDestroy(){ LOGGER.info("XACMLPdpServletTest - testDestroy"); diff --git a/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/notifications/test/NotificationTest.java b/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/notifications/test/NotificationTest.java new file mode 100644 index 000000000..a18f93275 --- /dev/null +++ b/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/notifications/test/NotificationTest.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP-PDP-REST + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.policy.pdp.rest.notifications.test; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; +import org.onap.policy.api.NotificationType; +import org.onap.policy.pdp.rest.notifications.Notification; +import org.onap.policy.pdp.rest.notifications.Removed; +import org.onap.policy.pdp.rest.notifications.Updated; + +public class NotificationTest { + + + @Test + public void test() { + List<Removed> removedPolicies = new ArrayList<>(); + List<Updated> loadedPolicies = new ArrayList<>(); + + Updated u1 = new Updated(); + Removed r1 = new Removed(); + Notification n = new Notification(); + + u1.setPolicyName("update"); + u1.setVersionNo("1"); + u1.setMatches(null); + u1.setUpdateType(null); + + assertEquals("update", u1.getPolicyName()); + assertEquals("1", u1.getVersionNo()); + assertEquals(null, u1.getMatches()); + assertEquals(null, u1.getUpdateType()); + + loadedPolicies.add(u1); + + r1.setPolicyName("removed"); + r1.setVersionNo("1"); + assertEquals(r1.getPolicyName(),"removed"); + assertEquals(r1.getVersionNo(),"1"); + + removedPolicies.add(r1); + + n.setLoadedPolicies(loadedPolicies); + n.setRemovedPolicies(removedPolicies); + n.setNotificationType(NotificationType.BOTH); + + assertEquals(removedPolicies, n.getRemovedPolicies()); + assertEquals(loadedPolicies, n.getLoadedPolicies()); + assertEquals(NotificationType.BOTH, n.getNotificationType()); + + + + } +} diff --git a/ONAP-PDP-REST/src/test/resources/xacml.pdp.dmaap.properties b/ONAP-PDP-REST/src/test/resources/xacml.pdp.dmaap.properties new file mode 100644 index 000000000..5ec9fe307 --- /dev/null +++ b/ONAP-PDP-REST/src/test/resources/xacml.pdp.dmaap.properties @@ -0,0 +1,176 @@ +### +# ============LICENSE_START======================================================= +# ONAP-PDP-REST +# ================================================================================ +# Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +### + +# Default XACML Properties File for PDP RESTful servlet +# +# Standard API Factories +# +xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory +xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory +xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory +# NOT USED SEE BELOW xacml.pipFinderFactory=org.onap.policy.xacml.std.pip.StdPIPFinderFactory +xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory +# +# AT&T PDP Implementation Factories +# +xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory +xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory +xacml.att.functionDefinitionFactory=org.onap.policy.xacml.custom.OnapFunctionDefinitionFactory +# NOT USED SEE BELOW xacml.att.policyFinderFactory=org.onap.policy.pdp.std.StdPolicyFinderFactory +# creteUpdate Policy Implementation Class details. +createUpdatePolicy.impl.className=org.onap.policy.pdp.rest.api.services.CreateUpdatePolicyServiceImpl +# AAF Implementation class details +aafClient.impl.className=org.onap.policy.utils.AAFPolicyClientImpl +# +# AT&T RESTful PDP Implementation Factories +# +xacml.pipFinderFactory=org.onap.policy.pdp.rest.impl.XACMLPdpPIPFinderFactory +xacml.att.policyFinderFactory=org.onap.policy.pdp.rest.XACMLPdpPolicyFinderFactory +# +# When set to true, this flag tells the StdPolicyFinderFactory to combined all the root policy files into +# into one PolicySet and use the given Policy Algorithm. +# +xacml.att.policyFinderFactory.combineRootPolicies=urn:com:att:xacml:3.0:policy-combining-algorithm:combined-permit-overrides +# +# PDP RESTful API properties +# +# Set this to the address where the XACML-PAP-REST servlet is running +xacml.rest.pap.url=http://localhost:8070/pap/ + +#if multiple paps exist, the xacml.rest.pap.url can be removed and they can be defined like this: +#xacml.rest.pap.urls=http://localhost:9090/pap/,http://localhost:9091/pap/ + +# +# Give the running PDP an ID for the PAP. The url that its running as is a good choice. +# The PAP identifies PDP's using the URL of the PDP. +# +xacml.rest.pdp.id=http://localhost:8082/pdp/ + +# Give the port number used for the PDP + +xacml.jmx.port=0 + + +# Notification Properties +# Notifcation type: websocket, ueb or dmaap... if left blank websocket is the default +NOTIFICATION_TYPE=dmaap +NOTIFICATION_SERVERS= +NOTIFICATION_TOPIC= +NOTIFICATION_DELAY= +UEB_API_KEY= +UEB_API_SECRET= +DMAAP_AAF_LOGIN= +DMAAP_AAF_PASSWORD= + +# +# Set the directory where the PDP holds its Policy Cache and PIP Configuration +# +xacml.rest.pdp.config=config + +xacml.rest.pdp.webapps=/home/users/PolicyEngine/webapps/ConfigPAP/ +# +# Initialize register with PAP servlet +# +xacml.rest.pdp.register=true +# +# Sleep period in seconds between register attempts +# +xacml.rest.pdp.register.sleep=15 +# +# number of attempts to register. -1 means keep trying forever. +# +xacml.rest.pdp.register.retries=-1 +# +# max number of bytes in a POST of a XML/JSON request +# old value #32767 +xacml.rest.pdp.maxcontent=99999999 +# +# Set UserID here +xacml.rest.pdp.userid=testpdp +# Set Password here +xacml.rest.pdp.password=alpha456 + +# id PAP +xacml.rest.pap.userid=testpap +#if multiple paps have different logins, they can be defined like this: +#http\://localhost\:9090/pap/.xacml.rest.pap.userid=testpap + +# pass PAP +xacml.rest.pap.password=alpha123 +#http\://localhost\:9090/pap/.xacml.rest.pap.password=alpha123 + +# Delay for Notifications Don't change this. Value in milliSec. +xacml.rest.notification.delay=30 + +# Client interval to ping notification service. +CLIENT_INTERVAL=15000 + +# Buffer Size. +REQUEST_BUFFER_SIZE=15 + +#Properties for db access +#properties for MySql xacml database: PLEASE DO NOT REMOVE... NEEDED FOR APIs +javax.persistence.jdbc.driver=org.h2.Driver +javax.persistence.jdbc.url=jdbc:h2:file:./sql/xacmlTest +javax.persistence.jdbc.user=sa +javax.persistence.jdbc.password= + +#***Properties for IntegrityMonitor integration defined in XACMLRestProperties.java*** + +#The name of the PDP. Must be unique across the system +xacml.rest.pdp.resource.name=site_1.pdp_1 + +#***Properties for IntegrityMonitor integration defined in IntegrityMonitorProperties.java*** + +#Interval between forward progress counter updates in seconds +fp_monitor_interval=30 + +#Number of forward progress counter failures before failover +failed_counter_threshold=3 + +#Interval in seconds between test transactions if there is no other traffic +test_trans_interval=10 + +#Interval in seconds between updates of the forward progress counter in the DB +write_fpc_interval=5 + +#Name of the site +site_name=site_1 + +#Node type +node_type=pdp_xacml + +#Dependency groups are groups of resources upon which a node operational state is dependent upon). +#Each group is a comma-separated list of resource names and groups are separated by a semicolon. +#A group may contain one or more members. Resource names must match the resource names defined +#in the respective servers' properties files +dependency_groups=site_1.pdplp_1;site_1.astragw_1;site_1.brmsgw_1 + +# this can be DEVL, TEST, PROD +ENVIRONMENT=DEVL +xacml.rest.pep.idfile = client.properties + +#AAF Policy Name space +#Not Mandatory for Open Onap +policy.aaf.namespace = +policy.aaf.resource = +# Decision Response settings. +# can be either PERMIT or DENY. +decision.indeterminate.response=PERMIT
\ No newline at end of file diff --git a/ONAP-PDP-REST/src/test/resources/xacml.pdp.ueb.properties b/ONAP-PDP-REST/src/test/resources/xacml.pdp.ueb.properties new file mode 100644 index 000000000..e74966157 --- /dev/null +++ b/ONAP-PDP-REST/src/test/resources/xacml.pdp.ueb.properties @@ -0,0 +1,176 @@ +### +# ============LICENSE_START======================================================= +# ONAP-PDP-REST +# ================================================================================ +# Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +### + +# Default XACML Properties File for PDP RESTful servlet +# +# Standard API Factories +# +xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory +xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory +xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory +# NOT USED SEE BELOW xacml.pipFinderFactory=org.onap.policy.xacml.std.pip.StdPIPFinderFactory +xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory +# +# AT&T PDP Implementation Factories +# +xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory +xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory +xacml.att.functionDefinitionFactory=org.onap.policy.xacml.custom.OnapFunctionDefinitionFactory +# NOT USED SEE BELOW xacml.att.policyFinderFactory=org.onap.policy.pdp.std.StdPolicyFinderFactory +# creteUpdate Policy Implementation Class details. +createUpdatePolicy.impl.className=org.onap.policy.pdp.rest.api.services.CreateUpdatePolicyServiceImpl +# AAF Implementation class details +aafClient.impl.className=org.onap.policy.utils.AAFPolicyClientImpl +# +# AT&T RESTful PDP Implementation Factories +# +xacml.pipFinderFactory=org.onap.policy.pdp.rest.impl.XACMLPdpPIPFinderFactory +xacml.att.policyFinderFactory=org.onap.policy.pdp.rest.XACMLPdpPolicyFinderFactory +# +# When set to true, this flag tells the StdPolicyFinderFactory to combined all the root policy files into +# into one PolicySet and use the given Policy Algorithm. +# +xacml.att.policyFinderFactory.combineRootPolicies=urn:com:att:xacml:3.0:policy-combining-algorithm:combined-permit-overrides +# +# PDP RESTful API properties +# +# Set this to the address where the XACML-PAP-REST servlet is running +xacml.rest.pap.url=http://localhost:8070/pap/ + +#if multiple paps exist, the xacml.rest.pap.url can be removed and they can be defined like this: +#xacml.rest.pap.urls=http://localhost:9090/pap/,http://localhost:9091/pap/ + +# +# Give the running PDP an ID for the PAP. The url that its running as is a good choice. +# The PAP identifies PDP's using the URL of the PDP. +# +xacml.rest.pdp.id=http://localhost:8082/pdp/ + +# Give the port number used for the PDP + +xacml.jmx.port=0 + + +# Notification Properties +# Notifcation type: websocket, ueb or dmaap... if left blank websocket is the default +NOTIFICATION_TYPE=ueb +NOTIFICATION_SERVERS= +NOTIFICATION_TOPIC= +NOTIFICATION_DELAY= +UEB_API_KEY= +UEB_API_SECRET= +DMAAP_AAF_LOGIN= +DMAAP_AAF_PASSWORD= + +# +# Set the directory where the PDP holds its Policy Cache and PIP Configuration +# +xacml.rest.pdp.config=config + +xacml.rest.pdp.webapps=/home/users/PolicyEngine/webapps/ConfigPAP/ +# +# Initialize register with PAP servlet +# +xacml.rest.pdp.register=true +# +# Sleep period in seconds between register attempts +# +xacml.rest.pdp.register.sleep=15 +# +# number of attempts to register. -1 means keep trying forever. +# +xacml.rest.pdp.register.retries=-1 +# +# max number of bytes in a POST of a XML/JSON request +# old value #32767 +xacml.rest.pdp.maxcontent=99999999 +# +# Set UserID here +xacml.rest.pdp.userid=testpdp +# Set Password here +xacml.rest.pdp.password=alpha456 + +# id PAP +xacml.rest.pap.userid=testpap +#if multiple paps have different logins, they can be defined like this: +#http\://localhost\:9090/pap/.xacml.rest.pap.userid=testpap + +# pass PAP +xacml.rest.pap.password=alpha123 +#http\://localhost\:9090/pap/.xacml.rest.pap.password=alpha123 + +# Delay for Notifications Don't change this. Value in milliSec. +xacml.rest.notification.delay=30 + +# Client interval to ping notification service. +CLIENT_INTERVAL=15000 + +# Buffer Size. +REQUEST_BUFFER_SIZE=15 + +#Properties for db access +#properties for MySql xacml database: PLEASE DO NOT REMOVE... NEEDED FOR APIs +javax.persistence.jdbc.driver=org.h2.Driver +javax.persistence.jdbc.url=jdbc:h2:file:./sql/xacmlTest +javax.persistence.jdbc.user=sa +javax.persistence.jdbc.password= + +#***Properties for IntegrityMonitor integration defined in XACMLRestProperties.java*** + +#The name of the PDP. Must be unique across the system +xacml.rest.pdp.resource.name=site_1.pdp_1 + +#***Properties for IntegrityMonitor integration defined in IntegrityMonitorProperties.java*** + +#Interval between forward progress counter updates in seconds +fp_monitor_interval=30 + +#Number of forward progress counter failures before failover +failed_counter_threshold=3 + +#Interval in seconds between test transactions if there is no other traffic +test_trans_interval=10 + +#Interval in seconds between updates of the forward progress counter in the DB +write_fpc_interval=5 + +#Name of the site +site_name=site_1 + +#Node type +node_type=pdp_xacml + +#Dependency groups are groups of resources upon which a node operational state is dependent upon). +#Each group is a comma-separated list of resource names and groups are separated by a semicolon. +#A group may contain one or more members. Resource names must match the resource names defined +#in the respective servers' properties files +dependency_groups=site_1.pdplp_1;site_1.astragw_1;site_1.brmsgw_1 + +# this can be DEVL, TEST, PROD +ENVIRONMENT=DEVL +xacml.rest.pep.idfile = client.properties + +#AAF Policy Name space +#Not Mandatory for Open Onap +policy.aaf.namespace = +policy.aaf.resource = +# Decision Response settings. +# can be either PERMIT or DENY. +decision.indeterminate.response=PERMIT
\ No newline at end of file |