Skip to content

Commit 9df1071

Browse files
author
Alena Prokharchyk
committed
Resource metadata support for S2SVpnConnection
Conflicts: server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java server/src/com/cloud/tags/TaggedResourceManagerImpl.java setup/db/db/schema-421to430.sql
1 parent d5fcc6e commit 9df1071

9 files changed

Lines changed: 199 additions & 50 deletions

File tree

api/src/com/cloud/server/ResourceTag.java

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,12 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
2424

2525
// FIXME - extract enum to another interface as its used both by resourceTags and resourceMetaData code
2626
public enum ResourceObjectType {
27-
UserVm(true, true),
28-
Template(true, true),
29-
ISO(true, false),
30-
Volume(true, true),
31-
Snapshot(true, false),
32-
Network(true, true),
33-
Nic(false, true),
34-
LoadBalancer(true, true),
35-
PortForwardingRule(true, true),
36-
FirewallRule(true, true),
37-
SecurityGroup(true, false),
38-
PublicIpAddress(true, true),
39-
Project(true, false),
40-
Vpc(true, true),
41-
NetworkACL(true, true),
42-
StaticRoute(true, false),
43-
VMSnapshot(true, false),
44-
RemoteAccessVpn(true, true),
45-
Zone(false, true),
46-
ServiceOffering(false, true),
47-
Storage(false, true),
48-
PrivateGateway(false, true),
49-
NetworkACLList(false, true),
50-
VpnGateway(false, true),
51-
CustomerGateway(false, true);
27+
UserVm(true, true), Template(true, true), ISO(true, false), Volume(true, true), Snapshot(true, false), Network(true, true), Nic(false, true), LoadBalancer(true, true), PortForwardingRule(
28+
true, true), FirewallRule(true, true),
29+
30+
SecurityGroup(true, false), PublicIpAddress(true, true), Project(true, false), Vpc(true, true), NetworkACL(true, true), StaticRoute(true, false), VMSnapshot(true, false), RemoteAccessVpn(
31+
true, true), Zone(false, true), ServiceOffering(false, true), Storage(false, true), PrivateGateway(false, true), NetworkACLList(false, true), VpnGateway(false,
32+
true), CustomerGateway(false, true), VpnConnection(false, true);
5233

5334
ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) {
5435
this.resourceTagsSupport = resourceTagsSupport;

engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@
329329
<bean id="NetworkACLItemDetailsDaoImpl" class="org.apache.cloudstack.resourcedetail.dao.NetworkACLItemDetailsDaoImpl" />
330330
<bean id="Site2SiteVpnGatewayDetailsDaoImpl" class="org.apache.cloudstack.resourcedetail.dao.Site2SiteVpnGatewayDetailsDaoImpl" />
331331
<bean id="Site2SiteCustomerGatewayDetailsDaoImpl" class="org.apache.cloudstack.resourcedetail.dao.Site2SiteCustomerGatewayDetailsDaoImpl" />
332+
<bean id="Site2SiteVpnConnectionDetailsDaoImpl" class="org.apache.cloudstack.resourcedetail.dao.Site2SiteVpnConnectionDetailsDaoImpl" />
332333
<bean id="databaseIntegrityChecker" class="com.cloud.upgrade.DatabaseIntegrityChecker" />
333334

334335
</beans>
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.apache.cloudstack.resourcedetail;
18+
19+
import javax.persistence.Column;
20+
import javax.persistence.Entity;
21+
import javax.persistence.GeneratedValue;
22+
import javax.persistence.GenerationType;
23+
import javax.persistence.Id;
24+
import javax.persistence.Table;
25+
26+
import org.apache.cloudstack.api.ResourceDetail;
27+
28+
@Entity
29+
@Table(name = "s2s_vpn_connection_details")
30+
public class Site2SiteVpnConnectionDetailVO implements ResourceDetail {
31+
@Id
32+
@GeneratedValue(strategy = GenerationType.IDENTITY)
33+
@Column(name = "id")
34+
private long id;
35+
36+
@Column(name = "s2s_vpn_connection_id")
37+
private long resourceId;
38+
39+
@Column(name = "name")
40+
private String name;
41+
42+
@Column(name = "value", length = 1024)
43+
private String value;
44+
45+
@Column(name = "display")
46+
private boolean display;
47+
48+
public Site2SiteVpnConnectionDetailVO() {
49+
}
50+
51+
public Site2SiteVpnConnectionDetailVO(long id, String name, String value) {
52+
this.resourceId = id;
53+
this.name = name;
54+
this.value = value;
55+
}
56+
57+
@Override
58+
public long getId() {
59+
return id;
60+
}
61+
62+
@Override
63+
public String getName() {
64+
return name;
65+
}
66+
67+
@Override
68+
public String getValue() {
69+
return value;
70+
}
71+
72+
@Override
73+
public long getResourceId() {
74+
return resourceId;
75+
}
76+
77+
@Override
78+
public boolean isDisplay() {
79+
return display;
80+
}
81+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.apache.cloudstack.resourcedetail.dao;
18+
19+
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
20+
import org.apache.cloudstack.resourcedetail.Site2SiteVpnConnectionDetailVO;
21+
22+
import com.cloud.utils.db.GenericDao;
23+
24+
public interface Site2SiteVpnConnectionDetailsDao extends GenericDao<Site2SiteVpnConnectionDetailVO, Long>, ResourceDetailsDao<Site2SiteVpnConnectionDetailVO> {
25+
26+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing,
11+
// software distributed under the License is distributed on an
12+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13+
// KIND, either express or implied. See the License for the
14+
// specific language governing permissions and limitations
15+
// under the License.
16+
package org.apache.cloudstack.resourcedetail.dao;
17+
18+
import javax.ejb.Local;
19+
20+
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
21+
import org.apache.cloudstack.resourcedetail.Site2SiteVpnConnectionDetailVO;
22+
import org.springframework.stereotype.Component;
23+
24+
@Component
25+
@Local(value = {Site2SiteVpnConnectionDetailsDao.class})
26+
public class Site2SiteVpnConnectionDetailsDaoImpl extends ResourceDetailsDaoBase<Site2SiteVpnConnectionDetailVO> implements Site2SiteVpnConnectionDetailsDao {
27+
28+
@Override
29+
public void addDetail(long resourceId, String key, String value) {
30+
super.addDetail(new Site2SiteVpnConnectionDetailVO(resourceId, key, value));
31+
}
32+
}

server/src/com/cloud/api/ApiResponseHelper.java

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@
3131

3232
import javax.inject.Inject;
3333

34-
import org.apache.log4j.Logger;
35-
3634
import org.apache.cloudstack.acl.ControlledEntity;
3735
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
3836
import org.apache.cloudstack.affinity.AffinityGroup;
@@ -149,6 +147,7 @@
149147
import org.apache.cloudstack.usage.Usage;
150148
import org.apache.cloudstack.usage.UsageService;
151149
import org.apache.cloudstack.usage.UsageTypes;
150+
import org.apache.log4j.Logger;
152151

153152
import com.cloud.api.query.ViewResponseHelper;
154153
import com.cloud.api.query.vo.AccountJoinVO;
@@ -288,7 +287,6 @@
288287
import com.cloud.utils.Pair;
289288
import com.cloud.utils.StringUtils;
290289
import com.cloud.utils.db.EntityManager;
291-
import com.cloud.utils.exception.CloudRuntimeException;
292290
import com.cloud.utils.net.Ip;
293291
import com.cloud.utils.net.NetUtils;
294292
import com.cloud.vm.ConsoleProxyVO;
@@ -465,9 +463,9 @@ public SnapshotResponse createSnapshotResponse(Snapshot snapshot) {
465463
}
466464

467465
if (snapshotInfo == null) {
468-
s_logger.debug("Unable to find info for image store snapshot with uuid "+snapshot.getUuid());
466+
s_logger.debug("Unable to find info for image store snapshot with uuid " + snapshot.getUuid());
469467
snapshotResponse.setRevertable(false);
470-
}else{
468+
} else {
471469
snapshotResponse.setRevertable(snapshotInfo.isRevertable());
472470
}
473471

@@ -1704,8 +1702,8 @@ private List<CapacityVO> sumCapacities(List<? extends Capacity> hostCapacities)
17041702
short capacityType = capacity.getCapacityType();
17051703

17061704
// If local storage then ignore
1707-
if ((capacityType == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED || capacityType == Capacity.CAPACITY_TYPE_STORAGE) &&
1708-
poolIdsToIgnore.contains(capacity.getHostOrPoolId())) {
1705+
if ((capacityType == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED || capacityType == Capacity.CAPACITY_TYPE_STORAGE)
1706+
&& poolIdsToIgnore.contains(capacity.getHostOrPoolId())) {
17091707
continue;
17101708
}
17111709

@@ -2198,8 +2196,7 @@ public NetworkResponse createNetworkResponse(Network network) {
21982196
reservation = (NetUtils.long2Ip(startGuestIp) + "-" + NetUtils.long2Ip(startVmIp - 1));
21992197
}
22002198
if (startVmIp > startGuestIp + 1 && endVmIp < endGuestIp - 1) {
2201-
reservation =
2202-
(NetUtils.long2Ip(startGuestIp) + "-" + NetUtils.long2Ip(startVmIp - 1) + " , " + NetUtils.long2Ip(endVmIp + 1) + "-" + NetUtils.long2Ip(endGuestIp));
2199+
reservation = (NetUtils.long2Ip(startGuestIp) + "-" + NetUtils.long2Ip(startVmIp - 1) + " , " + NetUtils.long2Ip(endVmIp + 1) + "-" + NetUtils.long2Ip(endGuestIp));
22032200
}
22042201
}
22052202
response.setReservedIpRange(reservation);
@@ -2210,10 +2207,10 @@ public NetworkResponse createNetworkResponse(Network network) {
22102207
response.setBroadcastUri(broadcastUri);
22112208
String vlan = "N/A";
22122209
switch (BroadcastDomainType.getSchemeValue(network.getBroadcastUri())) {
2213-
case Vlan:
2214-
case Vxlan:
2215-
vlan = BroadcastDomainType.getValue(network.getBroadcastUri());
2216-
break;
2210+
case Vlan:
2211+
case Vxlan:
2212+
vlan = BroadcastDomainType.getValue(network.getBroadcastUri());
2213+
break;
22172214
}
22182215
// return vlan information only to Root admin
22192216
response.setVlan(vlan);
@@ -2626,8 +2623,8 @@ public ServiceResponse createNetworkServiceResponse(Service service) {
26262623
CapabilityResponse capabilityResponse = new CapabilityResponse();
26272624
capabilityResponse.setName(cap.getName());
26282625
capabilityResponse.setObjectName("capability");
2629-
if (cap.getName().equals(Capability.SupportedLBIsolation.getName()) || cap.getName().equals(Capability.SupportedSourceNatTypes.getName()) ||
2630-
cap.getName().equals(Capability.RedundantRouter.getName())) {
2626+
if (cap.getName().equals(Capability.SupportedLBIsolation.getName()) || cap.getName().equals(Capability.SupportedSourceNatTypes.getName())
2627+
|| cap.getName().equals(Capability.RedundantRouter.getName())) {
26312628
capabilityResponse.setCanChoose(true);
26322629
} else {
26332630
capabilityResponse.setCanChoose(false);
@@ -2641,8 +2638,8 @@ public ServiceResponse createNetworkServiceResponse(Service service) {
26412638
List<ProviderResponse> serviceProvidersResponses = new ArrayList<ProviderResponse>();
26422639
for (Network.Provider serviceProvider : serviceProviders) {
26432640
// return only Virtual Router/JuniperSRX/CiscoVnmc as a provider for the firewall
2644-
if (service == Service.Firewall &&
2645-
!(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX || serviceProvider == Provider.CiscoVnmc || serviceProvider == Provider.PaloAlto)) {
2641+
if (service == Service.Firewall
2642+
&& !(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX || serviceProvider == Provider.CiscoVnmc || serviceProvider == Provider.PaloAlto)) {
26462643
continue;
26472644
}
26482645

@@ -2734,8 +2731,7 @@ public OvsProviderResponse createOvsProviderResponse(OvsProvider result) {
27342731

27352732
OvsProviderResponse response = new OvsProviderResponse();
27362733
response.setId(result.getUuid());
2737-
PhysicalNetworkServiceProvider nsp = ApiDBUtils
2738-
.findPhysicalNetworkServiceProviderById(result.getNspId());
2734+
PhysicalNetworkServiceProvider nsp = ApiDBUtils.findPhysicalNetworkServiceProviderById(result.getNspId());
27392735
if (nsp != null) {
27402736
response.setNspId(nsp.getUuid());
27412737
}
@@ -3373,8 +3369,8 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord) {
33733369
NetworkVO network = _entityMgr.findById(NetworkVO.class, usageRecord.getNetworkId().toString());
33743370
usageRecResponse.setNetworkId(network.getUuid());
33753371

3376-
} else if (usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_READ || usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_WRITE ||
3377-
usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_READ || usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_WRITE) {
3372+
} else if (usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_READ || usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_WRITE
3373+
|| usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_READ || usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_WRITE) {
33783374
//Device Type
33793375
usageRecResponse.setType(usageRecord.getType());
33803376
//VM Instance Id

server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
import org.apache.cloudstack.resourcedetail.dao.NetworkACLItemDetailsDao;
3131
import org.apache.cloudstack.resourcedetail.dao.NetworkACLListDetailsDao;
3232
import org.apache.cloudstack.resourcedetail.dao.RemoteAccessVpnDetailsDao;
33+
import org.apache.cloudstack.resourcedetail.dao.Site2SiteCustomerGatewayDetailsDao;
34+
import org.apache.cloudstack.resourcedetail.dao.Site2SiteVpnConnectionDetailsDao;
35+
import org.apache.cloudstack.resourcedetail.dao.Site2SiteVpnGatewayDetailsDao;
3336
import org.apache.cloudstack.resourcedetail.dao.UserIpAddressDetailsDao;
3437
import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
3538
import org.apache.cloudstack.resourcedetail.dao.VpcGatewayDetailsDao;
@@ -92,9 +95,14 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource
9295
NetworkACLListDetailsDao _networkACLListDetailsDao;
9396
@Inject
9497
NetworkACLItemDetailsDao _networkACLDetailsDao;
98+
@Inject
99+
Site2SiteVpnGatewayDetailsDao _vpnGatewayDetailsDao;
100+
@Inject
101+
Site2SiteCustomerGatewayDetailsDao _customerGatewayDetailsDao;
102+
@Inject
103+
Site2SiteVpnConnectionDetailsDao _vpnConnectionDetailsDao;
95104

96-
private static Map<ResourceObjectType, ResourceDetailsDao<? extends ResourceDetail>> s_daoMap =
97-
new HashMap<ResourceObjectType, ResourceDetailsDao<? extends ResourceDetail>>();
105+
private static Map<ResourceObjectType, ResourceDetailsDao<? extends ResourceDetail>> s_daoMap = new HashMap<ResourceObjectType, ResourceDetailsDao<? extends ResourceDetail>>();
98106

99107
@Override
100108
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@@ -115,6 +123,9 @@ public boolean configure(String name, Map<String, Object> params) throws Configu
115123
s_daoMap.put(ResourceObjectType.PrivateGateway, _vpcGatewayDetailsDao);
116124
s_daoMap.put(ResourceObjectType.NetworkACLList, _networkACLListDetailsDao);
117125
s_daoMap.put(ResourceObjectType.NetworkACL, _networkACLDetailsDao);
126+
s_daoMap.put(ResourceObjectType.VpnGateway, _vpnGatewayDetailsDao);
127+
s_daoMap.put(ResourceObjectType.CustomerGateway, _customerGatewayDetailsDao);
128+
s_daoMap.put(ResourceObjectType.VpnConnection, _vpnConnectionDetailsDao);
118129

119130
return true;
120131
}

server/src/com/cloud/tags/TaggedResourceManagerImpl.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
import com.cloud.network.dao.LoadBalancerDao;
4343
import com.cloud.network.dao.NetworkDao;
4444
import com.cloud.network.dao.RemoteAccessVpnDao;
45+
import com.cloud.network.dao.Site2SiteCustomerGatewayDao;
46+
import com.cloud.network.dao.Site2SiteVpnConnectionDao;
47+
import com.cloud.network.dao.Site2SiteVpnGatewayDao;
4548
import com.cloud.network.rules.dao.PortForwardingRulesDao;
4649
import com.cloud.network.security.dao.SecurityGroupDao;
4750
import com.cloud.network.vpc.NetworkACLItemDao;
@@ -138,6 +141,12 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
138141
VpcGatewayDao _vpcGatewayDao;
139142
@Inject
140143
NetworkACLDao _networkACLListDao;
144+
@Inject
145+
Site2SiteVpnGatewayDao _vpnGatewayDao;
146+
@Inject
147+
Site2SiteCustomerGatewayDao _customerGatewayDao;
148+
@Inject
149+
Site2SiteVpnConnectionDao _vpnConnectionDao;
141150

142151
@Override
143152
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@@ -164,6 +173,9 @@ public boolean configure(String name, Map<String, Object> params) throws Configu
164173
s_daoMap.put(ResourceObjectType.Storage, _storagePoolDao);
165174
s_daoMap.put(ResourceObjectType.PrivateGateway, _vpcGatewayDao);
166175
s_daoMap.put(ResourceObjectType.NetworkACLList, _networkACLListDao);
176+
s_daoMap.put(ResourceObjectType.VpnGateway, _vpnGatewayDao);
177+
s_daoMap.put(ResourceObjectType.CustomerGateway, _customerGatewayDao);
178+
s_daoMap.put(ResourceObjectType.VpnConnection, _vpnConnectionDao);
167179

168180
return true;
169181
}
@@ -294,8 +306,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
294306
throw new InvalidParameterValueException("Value for the key " + key + " is either null or empty");
295307
}
296308

297-
ResourceTagVO resourceTag =
298-
new ResourceTagVO(key, value, accountDomainPair.first(), accountDomainPair.second(), id, resourceType, customer, resourceUuid);
309+
ResourceTagVO resourceTag = new ResourceTagVO(key, value, accountDomainPair.first(), accountDomainPair.second(), id, resourceType, customer, resourceUuid);
299310
resourceTag = _resourceTagDao.persist(resourceTag);
300311
resourceTags.add(resourceTag);
301312
}

setup/db/db/schema-421to430.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,3 +859,13 @@ CREATE TABLE `cloud`.`s2s_customer_gateway_details` (
859859
CONSTRAINT `fk_s2s_customer_gateway_details__s2s_customer_gateway_id` FOREIGN KEY `fk_s2s_customer_gateway_details__s2s_customer_gateway_id`(`s2s_customer_gateway_id`) REFERENCES `s2s_customer_gateway`(`id`) ON DELETE CASCADE
860860
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
861861

862+
863+
CREATE TABLE `cloud`.`s2s_vpn_connection_details` (
864+
`id` bigint unsigned NOT NULL auto_increment,
865+
`s2s_vpn_connection_id` bigint unsigned NOT NULL COMMENT 'VPC gateway id',
866+
`name` varchar(255) NOT NULL,
867+
`value` varchar(1024) NOT NULL,
868+
`display` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'True if the detail can be displayed to the end user',
869+
PRIMARY KEY (`id`),
870+
CONSTRAINT `fk_s2s_vpn_connection_details__s2s_vpn_connection_id` FOREIGN KEY `fk_s2s_vpn_connection_details__s2s_vpn_connection_id`(`s2s_vpn_connection_id`) REFERENCES `s2s_vpn_connection`(`id`) ON DELETE CASCADE
871+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

0 commit comments

Comments
 (0)